2016-05-13 1 views
2

Я использую ACTION_IMAGE_CAPTURE с предопределенной целью Uri в значительной степени, как указано в документации. Однако, когда я пытаюсь декодировать изображение сразу после получения моей активности, decodeStream() терпит неудачу. Если я попробую еще раз через несколько секунд, все будет хорошо. Я предполагаю, что файл записывается асинхронно в фоновом режиме. Как я могу узнать, когда он доступен для использования?Изображение, снятое с ACTION_IMAGE_CAPTURE - первый вызов decodeStream не работает, другие OK

Вот основные части моего кода:

Определение имя целевого файла:

String filename = String.format("pic%d.jpg", new Date().getTime()); 
File file = new File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), filename); 

try { 
    file.createNewFile(); 
} catch (IOException e) { 
    file = new File(context.getFilesDir(), filename); 
} 
targetUri = Uri.fromFile(photoFile); 

фотосъемке:

Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, targetUri); 
fragment.startActivityForResult(takePictureIntent, RESULT_TAKE_PICTURE); 

В onActivityResult():

if (resultCode == Activity.RESULT_OK) { 
    if (data != null) { 
     // Note that data.getData() is null here. 
     InputStream is = getContentResolver().openInputStream(targetUri); 
     if (is != null) { 
      Bitmap bm = BitmapFactory.decodeStream(is); 

decodeStream возврат null. Если я сделаю тот же звонок снова через несколько секунд, это будет успешным. Есть ли что-нибудь, что говорит мне, когда файл доступен?

UPDATE: По предложению greenapps', я делаю decodeStream звонок с inJustDecodeBounds первым, чтобы получить размеры, чтобы увидеть, если это проблема памяти. Оказывается, этот первый только декодированный проход заканчивается неудачно, но теперь фактический вызов decodeStream, который сразу следует, преуспевает! Если я тогда сделаю оба снова, они оба удастся!

Итак, первый вызов decodeStream всегда терпит неудачу, и все остальные после этого хороши, даже если они происходят сразу после этого (= внутри того же метода). Так что это, вероятно, не проблема с асинхронной записью. Но что-то еще. Но что?

+0

targetUri и URI? – greenapps

+0

Как вы настроили targetUri? Из пути к файловой системе? Затем используйте decodeFile на исходном пути. – greenapps

+0

'Я предполагаю, что файл записывается асинхронно в фоновом режиме '. Я думаю, что decodeStream возвращает null из-за нехватки памяти. Спустя некоторое время gc восстановился достаточно. Попробуйте использовать только границы декодирования. – greenapps

ответ

0
public static void updateFile(File file ,Context context) { 
     MediaScannerConnection.scanFile(context, 
       new String[]{file.getAbsolutePath()}, null, 
       new MediaScannerConnection.OnScanCompletedListener() { 
        public void onScanCompleted(String path, Uri uri) { 
        } 
       } 
     ); 
    } 

Я думаю, вы можете использовать его для обновления перед открытиемInputStream.

0

Из фрагмента кода вы поделились я thiiink проблема заключается в том, что вы устанавливаете файл изображения в файл переменной файлу

File file = new File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), filename); 

Но вы настраиваете изображение Ури из файла photoFile, который, вероятно, является нулевым

targetUri = Uri.fromFile(photoFile); 

Таким образом, в основном вам необходимо заменить targetUri = Uri.fromFile(photoFile); на targetUri = Uri.fromFile(file);

Или еще лучше data.getData() возвратят изображение Uri directlty как этого

InputStream is = null; 
     try { 
      is = getContentResolver().openInputStream(data.getData()); 
     } catch (FileNotFoundException e) { 
      e.printStackTrace(); 
     } 
     if (is != null) { 
      Bitmap bm = BitmapFactory.decodeStream(is); 

      ((ImageView) findViewById(R.id.imageView1)).setImageBitmap(bm); 
     } 

Вы все еще нужны декодировать битовую карту, чтобы избежать исключений ОЫХ вы можете использовать Glide для загрузки изображений с использованием изображения URI.

полный класс Проверено на Xpria C

package com.example.test; 

    import java.io.File; 
    import java.io.FileNotFoundException; 
    import java.io.IOException; 
    import java.io.InputStream; 
    import java.util.Date; 

    import android.app.Activity; 
    import android.content.Intent; 
    import android.graphics.Bitmap; 
    import android.graphics.BitmapFactory; 
    import android.net.Uri; 
    import android.os.Bundle; 
    import android.os.Environment; 
    import android.provider.MediaStore; 
    import android.view.View; 
    import android.view.View.OnClickListener; 
    import android.widget.ImageView; 

    public class TestActivity extends Activity { 

     @Override 
     protected void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 
      setContentView(R.layout.activity_test); 

      findViewById(R.id.take_picture).setOnClickListener(
        new OnClickListener() { 

         @Override 
         public void onClick(View v) { 
          dispatchTakePictureIntent(); 
         } 
        }); 
     } 

     static final int REQUEST_TAKE_PHOTO = 1; 

     private void dispatchTakePictureIntent() { 
      Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
      // Ensure that there's a camera activity to handle the intent 
      if (takePictureIntent.resolveActivity(getPackageManager()) != null) { 
       // Create the File where the photo should go 
       File photoFile = null; 
       try { 
        photoFile = createImageFile(); 
       } catch (IOException ex) { 
        // Error occurred while creating the File 
       } 
       // Continue only if the File was successfully created 
       if (photoFile != null) { 
        takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, 
          Uri.fromFile(photoFile)); 
        startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO); 
       } 
      } 
     } 

     protected static final int RESULT_TAKE_PICTURE = 100; 

     private File createImageFile() throws IOException { 
      // Create an image file name 
      String filename = String.format("pic%d.jpg", new Date().getTime()); 
      File file = new File(
        getExternalFilesDir(Environment.DIRECTORY_PICTURES), filename); 

      try { 
       file.createNewFile(); 
      } catch (IOException e) { 
       file = new File(getFilesDir(), filename); 
      } 

      return file; 
     } 

     @Override 
     protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
      if (requestCode == REQUEST_TAKE_PHOTO && resultCode == RESULT_OK) { 

       InputStream is = null; 
       try { 
        is = getContentResolver().openInputStream(data.getData()); 
       } catch (FileNotFoundException e) { 
        e.printStackTrace(); 
       } 
       if (is != null) { 
        Bitmap bm = BitmapFactory.decodeStream(is); 

        ((ImageView) findViewById(R.id.imageView1)).setImageBitmap(bm); 
       } 
      } 


} 
} 
2
if (requestCode == Utility.GALLERY_PICTURE) { 

     Uri selectedImageUri = null; 
     try { 
      selectedImageUri = data.getData(); 
      if (mImgProfilePic != null) { 
       // mImgProfilePic.setImageURI(selectedImageUri); 
       mImgProfilePic.setImageBitmap(decodeUri(getActivity(), 
         selectedImageUri, 60)); 
       // decodeUri 

      } 
     } catch (Exception e) { 

     } 
     // ////////////// 
     try { 
      // Bundle extras = data.getExtras(); 
      // // get the cropped bitmap 
      // Bitmap thePic = extras.getParcelable("data"); 
      // mImgProfilePic.setImageBitmap(thePic); 

      final Uri tempUri = selectedImageUri; 
      Log.d("check", "uri " + tempUri); 
      // http://dev1.brainpulse.org/quickmanhelp/webservice/api.php?act=companylogo 
      upLoadServerUri = "http://dev1.brainpulse.org/quickmanhelp/webservice/api.php?act=employee_profile_pic&image="; 
      upLoadServerUri = Utility.EMPLOYEE_PROFILE_PIC_URL 
        + "&employee_id=" + empId; 
      dialog = ProgressDialog.show(getActivity(), "", 
        "Uploading file...", true); 

      new Thread(new Runnable() { 
       public void run() { 
        getActivity().runOnUiThread(new Runnable() { 
         public void run() { 
          // messageText.setText("uploading started....."); 
         } 
        }); 
        uploadFilePath = getRealPathFromURI(tempUri); 
        uploadFile(uploadFilePath + ""); 
        // uploadFile(tempUri+""); 
       } 
      }).start(); 

     } catch (Exception e) { 

     } 

     // /////// 

    } 
Смежные вопросы