2015-06-02 2 views
1

В приложении, которое я разрабатываю, пользователь может определить изображение в своем профиле. При первом запуске приложения отображается интро-активность, в которой пользователь может выбирать между выбором фотографии из галереи или записью новой с помощью камеры.Фрагмент onActivityResult возвращает null

Это прекрасно работает. После того, как пользователь устанавливает pic профиля, я сохраняю его в папке приложения, и позже я смогу использовать этот файл в приложении.

Мое приложение основано на ящике навигации (поддержка), поэтому оно состоит из фрагментов. Один из этих фрагментов - это профиль пользователя, в котором показан профиль pic. здесь у пользователя есть шанс снова изменить этот рисунок. Здесь я получаю неприятности.

Чтобы выбрать новый рисунок, я использую тот же код, который я использовал для получения рисунка в интро-активности, просто приспосабливая некоторые вещи к фрагменту (поместив getActivity()). Но, похоже, это не возвращает изображение фрагменту, и он бросает NPE.

Это как ПИК является selectect из галереи в SettingsFragment:

Intent galleryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); 
galleryIntent.setType("image/*"); 
startActivityForResult(galleryIntent, PICK_IMAGE_REQUEST_FRAG); 

А вот onActivityResult в SettingsFragment тоже:

@Override 
public void onActivityResult(int requestCode, int resultCode, Intent data) { 
    super.onActivityResult(requestCode, resultCode, data); 
    switch (requestCode) { 
     case PICK_IMAGE_REQUEST_FRAG: 
      if (resultCode == getActivity().RESULT_OK && data != null) { 
       /*We get the image URI*/ 
       Uri selectedImageUri = data.getData(); 
       Bitmap srcBmp = null; 
       try { 
        srcBmp = MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(), selectedImageUri); 
       } catch (FileNotFoundException e) { 
        Log.e("GET_IMAGE", e.getMessage(), e); 
       } catch (IOException e) { 
        Log.e("GET_IMAGE", e.getMessage(), e); 
       } 

       /*Transform the original image to landscape to use it as profile background*/ 
       Bitmap landBmp = null; 
       if (srcBmp.getWidth() <= srcBmp.getHeight()) { 
        landBmp = Bitmap.createBitmap(
          srcBmp, 
          0, 
          srcBmp.getHeight()/2 - srcBmp.getWidth()/2, //srcBmp.getHeight()/4 ? 
          srcBmp.getWidth(), 
          srcBmp.getWidth() /2 
        ); 
       } 

       /*Scale the bitmap*/ 
       int originalWidth = srcBmp.getWidth(); 
       int originalHeight = srcBmp.getHeight(); 
       int newWidth = 400; 
       int newHeight = (originalHeight*newWidth)/originalWidth; 
       Bitmap fullbitmap = Bitmap.createScaledBitmap(landBmp, newWidth, newHeight, true); 
       /*Save the bitmap in app-folder*/ 
       ContextWrapper cw1 = new ContextWrapper(getActivity().getApplicationContext()); 
       File directory1 = cw1.getDir("profile", Context.MODE_PRIVATE); 
       if (!directory1.exists()) { 
        directory1.mkdir(); 
       } 
       File filepath1 = new File(directory1, "profile_pic.png"); 
       FileOutputStream fos1 = null; 
       try { 
        fos1 = new FileOutputStream(filepath1); 
        fullbitmap.compress(Bitmap.CompressFormat.PNG, 100, fos1); 
        fos1.close(); 
       } catch (Exception e) { 
        Log.e("SAVE_FULL_IMAGE", e.getMessage(), e); 
       } 

       /*Show background profile pic*/ 
       Drawable drawable = new BitmapDrawable(getResources(), fullbitmap); 
       header_container.setBackgroundDrawable(drawable); 
      } 
      break; 

Но, как сказал, приложение падает это то, что LogCat говорит:

java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=131073, result=-1, 
    data=Intent { dat=content://media/external/images/media/204 flg=0x1 }} 
    to activity {com.myproject.executer/com.myproject.executer.MainActivity}: 
java.lang.NullPointerException at android.app.ActivityThread.deliverResults(ActivityThread.java:3389) 

Caused by: java.lang.NullPointerException at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:590) 
    at com.myproject.executer.SettingsFragment.onActivityResult(SettingsFragment.java:275) 

Где линия 275 Bitmap fullbitmap = Bitmap.createScaledBitmap(landBmp, newWidth, newHeight, true);

Итак, я плохо понимаю, что происходит, потому что в нем говорится что-то, что не может привести к результату MainActivity, и оно должно доставить результат в SettingsFragment.

+0

Проверьте, является ли переменная srcBmp нулевой или нет. – Pankaj

ответ

1

Если метод onActivityResult() не завершается и возврат, то система считает это как поставка потерпев неудачу, поэтому ошибки начинаются с этим сообщением.

В вашем коде, кажется, что landBmp имеет значение null, поскольку условие srcBmp.getWidth() <= srcBmp.getHeight() является ложным, и вы не инициализируете landBmp в этом случае. Это бросает NullPointerException, и прекращение выполнения до onActivityResult() возвращается.

+1

Спасибо, очень Майк! Я не понимал, что я не справился с этим! Такая ошибка – masmic

0

вы можете чтение: http://inthecheesefactory.com/blog/how-to-fix-nested-fragment-onactivityresult-issue/en?fb_action_ids=780839882030502&fb_action_types=og.comments

Создать ActivityResultEvent.java

import android.content.Intent; 

/** 
* Created by nuuneoi on 3/12/2015. 
*/ 
public class ActivityResultEvent { 

    private int requestCode; 
    private int resultCode; 
    private Intent data; 

    public ActivityResultEvent(int requestCode, int resultCode, Intent data) { 
     this.requestCode = requestCode; 
     this.resultCode = resultCode; 
     this.data = data; 
    } 

    public int getRequestCode() { 
     return requestCode; 
    } 

    public void setRequestCode(int requestCode) { 
     this.requestCode = requestCode; 
    } 

    public int getResultCode() { 
     return resultCode; 
    } 

    public void setResultCode(int resultCode) { 
     this.resultCode = resultCode; 
    } 

    public Intent getData() { 
     return data; 
    } 

    public void setData(Intent data) { 
     this.data = data; 
    } 
} 

Создать ActivityResultBus.java

import android.os.Handler; 
import android.os.Looper; 

import com.squareup.otto.Bus; 

/** 
* Created by nuuneoi on 3/12/2015. 
*/ 
public class ActivityResultBus extends Bus { 

    private static ActivityResultBus instance; 

    public static ActivityResultBus getInstance() { 
     if (instance == null) 
      instance = new ActivityResultBus(); 
     return instance; 
    } 

    private Handler mHandler = new Handler(Looper.getMainLooper()); 

    public void postQueue(final Object obj) { 
     mHandler.post(new Runnable() { 
      @Override 
      public void run() { 
       ActivityResultBus.getInstance().post(obj); 
      } 
     }); 
    } 

} 

// >>>>>>>>>>> >>>override onActivityResult on Activity

public class MainActivity extends ActionBarActivity { 

    ... 

    @Override 
    protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
     super.onActivityResult(requestCode, resultCode, data); 
     ActivityResultBus.getInstance().postQueue(
        new ActivityResultEvent(requestCode, resultCode, data)); 
    } 

    ... 

} 

В фрагменте:

@Override 
    public void onActivityResult(int requestCode, int resultCode, Intent data) { 
     super.onActivityResult(requestCode, resultCode, data); 
     // Don't forget to check requestCode before continuing your job 
     if (requestCode == 12345) { 
      // Do your job 
      tvResult.setText("Result Code = " + resultCode); 
     } 
    } 
@Override 
    public void onStart() { 
     super.onStart(); 
     ActivityResultBus.getInstance().register(mActivityResultSubscriber); 
    } 

    @Override 
    public void onStop() { 
     super.onStop(); 
     ActivityResultBus.getInstance().unregister(mActivityResultSubscriber); 
    } 

    private Object mActivityResultSubscriber = new Object() { 
     @Subscribe 
     public void onActivityResultReceived(ActivityResultEvent event) { 
      int requestCode = event.getRequestCode(); 
      int resultCode = event.getResultCode(); 
      Intent data = event.getData(); 
      onActivityResult(requestCode, resultCode, data); 
     } 
    }; 
Смежные вопросы