2014-10-11 4 views
0

UPDATE2: Проблема связана с onResume и . Это не имеет никакого отношения к BitmapFactory.decodeFile(). Проблема в том, что когда я иду, чтобы сделать снимок, вызывается , но ничего не сохраняется в SharedPreferences, так как еще ничего не нужно сохранять. Но как только я вернусь от съемки, вызывается onResume и пытается установить путь изображения к пользовательскому объекту, взяв соответствующее значение от SharedPreferences. Поскольку там нет соответствующего значения, оно применяет значение по умолчанию от нуля до imagePath.Отображение ImageView с использованием BitmapFactory и пути к файлу, возвращает NullPointerException

ОБНОВЛЕНИЕ: Схема моей программы ActivityA хостов FragmentA, где размещается DialogFragment, которые вы видите ниже. Пользователь нажимает кнопку в FragmentA, чтобы сделать снимок, и как только они сделали снимок, в onActivityResult Я установил путь изображения как переменную String в пользовательский объект, и я проверяю его существование, вызывая Log.d(mObject.getImagePath(), ...).

Затем они могут повторно нажать одну и ту же кнопку изображения для просмотра изображения. Здесь происходит NullPointerException. Хотя я проверяю, что путь изображения существует в onActivityResult, он возвращает null позже, когда я пытаюсь получить к нему доступ. Вот почему BitmapFactory.decodeFile() возвращает null, так как imagePath имеет значение null в FragmentA, конечно, это будет null, когда я попытаюсь получить к нему доступ в качестве дополнительного в DialogFragment.

Может ли кто-нибудь понять, почему путь изображения возвращается null, даже если я проверяю его в onActivityResult и назначить его моему объекту? Я понятия не имею, почему это происходит. У меня есть аналогичная кнопка, где пользователь может вводить текст, а затем снова нажмите кнопку, чтобы просмотреть/отредактировать этот текст в диалоговом окне. Я выполняю ту же процедуру назначения переменной моему объекту в onActivityResult, и у меня нет проблем.

ПРИМЕЧАНИЕ. Если вы хотите посмотреть, как снимается и сохраняется изображение, обратитесь к this или ответьте на связанный вопрос справа.

imagePath:

/data/data/myPackageName/files/myInternalPicturesDir/IMG_20141011_152840.jpg.

FragmentA:

//onCreateView 
    mImageButton = (Button) v.findViewById(R.id.imageButton); 
    mImageButton.setOnClickListener(new View.OnClickListener() 
    { 
     public void onClick(View v) 
     { 
      if (isImageButtonFirstClick) 
      { 
       Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
       imageUri = CameraUtils.getOutputMediaFileUri(CameraUtils.MEDIA_TYPE_IMAGE); 
       intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri); 
       startActivityForResult(intent, REQUEST_IMAGE); 
      } 
      else 
      { 
       try 
       { 
        Log.d("mImageButton onClick", mMyObject.getImagePath()); 
        //returns null... 
       } 
       catch (Exception e) 
       { 
        e.printStackTrace(); 
       } 

       FragmentManager fm = getActivity().getSupportFragmentManager(); 
       InputImageFragment dialog = InputImageFragment.newInstance(mMyObject.getImagePath()); 
       dialog.show(fm, DIALOG_IMAGE); 
      } 
     } 
    }); 

... 

@Override 
public void onActivityResult(int requestCode, int resultCode, Intent data) 
{ 
    if (resultCode != Activity.RESULT_OK) 
    { 
     return; 
    } 
    ... 
    else if (requestCode == REQUEST_IMAGE) 
    { 
     String pathToInternallyStoredImage = CameraUtils.saveToInternalStorage(getActivity(), imageUri); 
     mMyObject.setImagePath(pathToInternallyStoredImage); 

     //verify imagePath exists, both return correct path 
     Log.d("onActivityResult pathToInternallyStoredImage", pathToInternallyStoredImage); 
     Log.d("onActivityResult mMyObject.getImagePath", mMyObject.getImagePath()); 

     isImageButtonFirstClick = false; 
     preferences.edit().putBoolean("isImageButtonFirstClick", isImageButtonFirstClick).commit(); 
    } 

DialogFragment:

public static InputImageFragment newInstance(String imagePath) 
{ 
    Bundle args = new Bundle(); 
    args.putSerializable(EXTRA_IMAGEPATH, imagePath); 

    InputImageFragment fragment = new InputImageFragment(); 
    fragment.setArguments(args); 

    return fragment; 
} 

@Override 
public Dialog onCreateDialog(Bundle savedInstanceState) 
{ 
    String imagePath = (String) getArguments.getSerializable(EXTRA_IMAGEPATH); 

    try 
    { 
     Log.d("onCreateDialog imagePath", imagePath); 
     //returns null... 
    } 
    catch (Exception e) 
    { 
     e.printStackTrace(); 
    } 

    View v = getActivity().getLayoutInflater().inflate(R.layout.dialog_input_image, null); 

    final ImageView imageView = (ImageView) v.findViewById(R.id.dialogInputImageView); 
    Bitmap image = BitmapFactory.decodeFile(imagePath); 
    imageView.setImageBitmap(image); 

    return new AlertDialog.Builder(getActivity()) 
      .setView(v) 
      .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() 
      { 
       @Override 
       public void onClick(DialogInterface dialog, int whichButton) 
       { 
        dialog.cancel(); 
       } 
      }) 
      .create(); 
} 

}

Это возвращает NullPointerException, и от моего чтения на BitmapFactory, это либо потому, что имя файла является недействительным или не может быть декодируется в растровое изображение.

10-13 17:10:39.498 5330-5330/myPackageName E/BitmapFactory﹕ Unable to decode stream: java.lang.NullPointerException

диалоговое окно отображается, но это просто пустая коробка с OK кнопки.

Я читал об аналогичных проблемах, в которых проблема заключалась в том, что сам был пустым. Я не думаю, что здесь проблема, но ниже - XML ​​dialog_input_image. Я пробовал работать с XML, и у меня был ImageView как ребенок FrameLayout, похожий на другие примеры, которые я видел, но я получаю ту же ошибку.

<?xml version="1.0" encoding="utf-8"?> 

<ImageView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/dialogInputImageView" 
    android:orientation="vertical" 
    android:scaleType="centerInside" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content"> 
</ImageView> 

Я новичок в Android, поэтому я не уверен, где я ошибаюсь. Любая помощь оценили, спасибо!

+0

, где u 'раздувание' макета в' onCreateView' – kId

+0

@kaushik Так как это 'DialogFragment', я не называю' onCreateView'. Я раздуваю макет в 'onCreateDialog', затем вызываю' setView (v) 'когда я возвращаю новый' AlertDialog.Builder' – pez

+0

Является ли битмап, возвращаемый BitmapFactory.decodeFile, нулевым? Прикрепление logcat для этого исключения определенно поможет. –

ответ

1

Проблема не имеет ничего общего с BitmapFactory.decodeFile().

Проблема заключалась в том, что когда пользователь делает снимок, вызывается . Он проверяет, существует ли существующий путь изображения, и если это так, сохраняет его в SharedPreferences. В первый раз, когда пользователь открывает приложение, путь изображения не будет существовать, так что ничего не сохраняется. После того, как снимок сделан, вызывается onResume и пытается восстановить путь изображения от SharedPreferences, но в итоге присвоено значение по умолчанию null, так как путь изображения не существовал. Я использовал boolean, чтобы отслеживать, когда следует восстановить информацию в onResume, но гораздо лучшим решением было просто проверить, было ли это значение null, прежде чем пытаться его восстановить.

if (preferences.getString("imagePath", null) != null) 
    { 
     myObject.setImagePath(preferences.getString("imagePath", null)); 
    } 

Исходный код работал бы, предполагая, что путь изображения уже существует. Но это не сработало бы в первый раз.

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

0

Вы бы лучше использовать Context метод getFilesDir() для чтения из внутренней памяти, как:

String image path = getFilesDir() .getAbsolutePath(); + "/myInternalPicturesDir/IMG_20141011_152840.jpg"; 
final ImageView imageView = (ImageView) v.findViewById(R.id.dialogInputImageView); 
Bitmap image = BitmapFactory.decodeFile(imagePath); 
imageView.setImageBitmap(image); 
+0

Спасибо за ответ. Вызов 'getActivity(). GetFilesDir(). GetAbsolutePath();' из моего 'DialogFragment' просто возвращает'/data/data/myPackageName/files'. Разве результирующая строка 'imagePath'' String' не будет прежней? – pez

+0

Не могли бы вы пройти полную трассировку стека в своем посте? – ToYonos

+0

Конечно. Это все, что он показывает: '10-11 16: 35: 56.098 31000-31000/myPackageName E/BitmapFactory: Невозможно декодировать поток: java.lang.NullPointerException' – pez

0

перед изменением Uri в растровом первым получить свой путь из кода ниже, а затем установить его

.......... 
Bitmap image = BitmapFactory.decodeFile(getRealPathFromURI(URI)); 
} 

public String getRealPathFromURI(Uri contentURI) throws Exception { 
    String result; 
    Cursor cursor = context.getContentResolver().query(contentURI, null, 
      null, null, null); 
    if (cursor == null) { 
     result = contentURI.getPath(); 
    } else { 
     cursor.moveToFirst(); 
     int idx = cursor 
       .getColumnIndex(MediaStore.Images.ImageColumns.DATA); 
     result = cursor.getString(idx); 
     cursor.close(); 
    } 
    return result; 
}