Проблемы с сохранением фотографии в файл - PullRequest
8 голосов
/ 23 апреля 2010

Человек, я все еще не могу сохранить фотографию, когда я отправляю намерение с просьбой сделать фотографию. Вот что я делаю:

  1. Создать URI, представляющий путь

    android.content.Context c = getApplicationContext(); 
    
    String fname = c.getFilesDir().getAbsolutePath()+"/parked.jpg";
    
    java.io.File file = new java.io.File( fname ); 
    
    Uri fileUri = Uri.fromFile(file);
    
  2. Создайте намерение (не забудьте имя pkg!) И запустите действие

    private static int TAKE_PICTURE = 22;
    
    Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE );
    
    intent.putExtra("com.droidstogo.boom1." + MediaStore.EXTRA_OUTPUT, fileUri);
    startActivityForResult( intent, TAKE_PICTURE );
    
  3. Начинается действие камеры, и я могу сделать снимок и одобрить его. Мой onActivityResult() затем вызывается. Но мой файл не записывается. URI: file: ///data/data/com.droidstogo.boom1/files/parked.jpg

  4. Я могу создать миниатюру OK (не вставляя лишнюю в намерение), и могу записать этот файл ОК, а затем прочитать ее обратно.

Кто-нибудь может увидеть, какую простую ошибку я совершаю? Ничего очевидного не видно в logcat - камера четко делает снимок. Спасибо,

Peter


Следует отметить, что у меня установлены соответствующие разрешения в файле AndroidManifest.xml:

    <uses-permission android:name="android.permission.READ_OWNER_DATA" />
    <uses-permission android:name="android.permission.WRITE_OWNER_DATA" />

    <uses-permission android:name="android.permission.CAMERA" />

    <uses-feature android:name="android.hardware.camera" />
    <uses-library android:name="com.google.android.maps" />



</application>

Есть идеи? Любые идеи о том, что можно попробовать, чтобы получить больше информации о проблеме?

Ответы [ 4 ]

7 голосов
/ 30 апреля 2010
  1. Как сказал Стив Х, вы не можете просто использовать файл: ///data/data/com.droidstogo.boom1/files/parked.jpg для этого.Это личный каталог вашего приложения, и камера не может писать туда.Например, вы можете использовать какой-нибудь файл SD-карты - он доступен для всех.

  2. Как сказал stealthcopter, дополнительное намерение - это просто MediaStore.EXTRA_OUTPUT без имени вашего пакета.

  3. Не проблема только к вашему сведению.Я предполагаю, что ни одно из указанных вами разрешений на самом деле не требуется для этой операции.

Вот мой пример кода:

final int REQUEST_FROM_CAMERA=1;

private File getTempFile()
{
    //it will return /sdcard/image.tmp
    return new File(Environment.getExternalStorageDirectory(),  "image.tmp");
}

private void getPhotoClick()
{
  Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
  intent.putExtra(MediaStore.EXTRA_OUTPUT,Uri.fromFile(getTempFile()));
  startActivityForResult(intent, REQUEST_FROM_CAMERA);
}


protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  if (requestCode == REQUEST_FROM_CAMERA && resultCode == RESULT_OK) {
    InputStream is=null;

    File file=getTempFile();
    try {
        is=new FileInputStream(file);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }

    //On HTC Hero the requested file will not be created. Because HTC Hero has custom camera
    //app implementation and it works another way. It doesn't write to a file but instead
    //it writes to media gallery and returns uri in intent. More info can be found here:
    ///932002/android-actionimagecapture-namerenie
    //http://code.google.com/p/android/issues/detail?id=1480
    //So here's the workaround:
    if(is==null){
        try {
            Uri u = data.getData();
            is=getContentResolver().openInputStream(u);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    //Now "is" stream contains the required photo, you can process it
    DoSomeProcessing(is);

    //don't forget to remove the temp file when it's not required. 
  }

}
1 голос
/ 28 апреля 2010

Ваша проблема может быть связана с каталогом, в котором вы пытаетесь сохранить файл. Для сохранения файлов на SD-карту вам не нужны никакие специальные разрешения, но способ получения ссылки на папку отличается от того, как вы мы сделали это Это также зависит от того, хотите ли вы сохранить изображение таким образом, чтобы его можно было извлечь из MediaStore (то есть, например, приложение галереи или альбомов или любое другое приложение, которое использует их для поиска изображений) или нет. Предполагая, что вы хотите, чтобы он был указан в MediaStore, вот код для этого:

ContentValues newImage = new ContentValues(2);
newImage.put(Media.DISPLAY_NAME, "whatever name you want shown");
newImage.put(Media.MIME_TYPE, "image/png");

Uri uri = contentResolver.insert(Media.EXTERNAL_CONTENT_URI, newImage);

try {
    Bitmap bitmap = //get your bitmap from the Camera, however that's done  
    OutputStream out = contentResolver.openOutputStream(uri);
    boolean success = bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
    out.close();
    if (success){
        Log.d("Image Writer", "Image written successfully.");                   
    } else {
        Log.d("Image Writer", "Image write failed, but without an explanation.");
    }

} catch (Exception e){
    Log.d("Image Writer", "Problem with the image. Stacktrace: ", e);
}

На моем эмуляторе под управлением v1.5 он успешно сохраняет растровое изображение на SD-карту в папке DCIM / Camera с именем файла, являющимся текущим временем. (Время сохраняется в миллисекундах с 1 января 1970 года, по некоторым причинам также называемого «эпохой».)

1 голос
/ 28 апреля 2010

Это потому, что вы добавили дополнительную точку:

 intent.putExtra("com.droidstogo.boom1."

Вместо:

 intent.putExtra("com.droidstogo.boom1"
0 голосов
/ 27 мая 2012

Как сказал Стив, вы должны сохранить свою фотографию на SD-карту. Каталог, в котором вы пытаетесь сохранить, является приватным, и если у вас нет рутированного устройства, вы не сможете писать туда. Попробуйте заменить эту строку:

String fname = c.getFilesDir().getAbsolutePath()+"/parked.jpg";

с этой строкой

String fname = Environment.getExternalStorageDirectory().getAbsolutePath() + "somePathYouKnownExists" + +"/parked.jpg";

Этого должно быть достаточно.

...