使用相机拍照后无法恢复活动

4
我想创建一个活动,在该活动中,我可以使用相机或图库上传图像到imageView中。
在我的平板电脑上这个功能正常,但在我的Galaxy S4手机上,在使用相机拍照后无法恢复活动。以下是logcat记录:
E/AndroidRuntime: FATAL EXCEPTION: main
              Process: com.example.gianluca.achieveme, PID: 27301
              java.lang.RuntimeException: Unable to resume activity {com.example.gianluca.achieveme/com.example.gianluca.achieveme.AchievementCompleted}: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1, result=-1, data=null} to activity {com.example.gianluca.achieveme/com.example.gianluca.achieveme.AchievementCompleted}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.net.Uri.getPath()' on a null object reference
                  at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3403)
                  at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3434)
                  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2772)
                  at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4471)
                  at android.app.ActivityThread.access$1000(ActivityThread.java:177)
                  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1455)
                  at android.os.Handler.dispatchMessage(Handler.java:102)
                  at android.os.Looper.loop(Looper.java:145)
                  at android.app.ActivityThread.main(ActivityThread.java:5951)
                  at java.lang.reflect.Method.invoke(Native Method)
                  at java.lang.reflect.Method.invoke(Method.java:372)
                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1400)
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1195)
               Caused by: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1, result=-1, data=null} to activity {com.example.gianluca.achieveme/com.example.gianluca.achieveme.AchievementCompleted}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.net.Uri.getPath()' on a null object reference
                  at android.app.ActivityThread.deliverResults(ActivityThread.java:4067)
                  at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3389)
                  at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3434) 
                  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2772) 
                  at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4471) 
                  at android.app.ActivityThread.access$1000(ActivityThread.java:177) 
                  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1455) 
                  at android.os.Handler.dispatchMessage(Handler.java:102) 
                  at android.os.Looper.loop(Looper.java:145) 
                  at android.app.ActivityThread.main(ActivityThread.java:5951) 
                  at java.lang.reflect.Method.invoke(Native Method) 
                  at java.lang.reflect.Method.invoke(Method.java:372) 
                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1400) 
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1195) 
               Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.net.Uri.getPath()' on a null object reference
                  at com.example.gianluca.achieveme.AchievementCompleted.onActivityResult(AchievementCompleted.java:126)
                  at android.app.Activity.dispatchActivityResult(Activity.java:6549)
                  at android.app.ActivityThread.deliverResults(ActivityThread.java:4063)
                  at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3389) 
                  at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3434) 
                  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2772) 
                  at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4471) 
                  at android.app.ActivityThread.access$1000(ActivityThread.java:177) 
                  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1455) 
                  at android.os.Handler.dispatchMessage(Handler.java:102) 
                  at android.os.Looper.loop(Looper.java:145) 
                  at android.app.ActivityThread.main(ActivityThread.java:5951) 
                  at java.lang.reflect.Method.invoke(Native Method) 
                  at java.lang.reflect.Method.invoke(Method.java:372) 
                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1400) 
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1195

我看到说使用相机会浪费大量内存,所以我必须使用onSavedInstanceState和onRestoreInstanceState来保存状态,但是我不知道如何操作。你能给我解释一下吗?这里是我的activity的Java代码:

public class AchievementCompleted extends AppCompatActivity implements DatePickerDialog.OnDateSetListener{

public static TextView tvTitle;
public static TextView tvDescription;
public static Button bDate;
public static Button bPosition;
public static Switch switchbutton;

private Uri imageCaptureUri;
private ImageView mImageView;
private static final int PICK_FROM_CAMERA=1;
private static final int PICK_FROM_FILE=2;

private Button bPhoto;


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

    tvTitle = (TextView)findViewById(R.id.titolo);
    tvDescription = (TextView)findViewById(R.id.descrizione);
    bDate = (Button)findViewById(R.id.data);
    switchbutton = (Switch)findViewById(R.id.swtich);

    Intent intent = getIntent();
    tvTitle.setText(intent.getStringExtra("Titolo"));
    tvDescription.setText(intent.getStringExtra("Descrizione"));

    switchbutton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

        }
    });

    final String[] items = new String [] {"Scatta foto", "Scegli dalla galleria"};
    ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.select_dialog_item,items);
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle("Seleziona l'immagine");
    builder.setAdapter(adapter, new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            if(which==0){
                Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                File file = new File(Environment.getExternalStorageDirectory(),"tmp_avatar"+ String.valueOf(System.currentTimeMillis())+".jpg");
                imageCaptureUri = Uri.fromFile(file);
                try{
                    intent.putExtra(MediaStore.EXTRA_OUTPUT,imageCaptureUri);
                    intent.putExtra("return data",true);

                    startActivityForResult(intent,PICK_FROM_CAMERA);
                }catch (Exception ex){
                    ex.printStackTrace();
                }
                dialog.cancel();
            }else{
                Intent intent = new Intent();
                intent.setType("image/*");
                intent.setAction(Intent.ACTION_GET_CONTENT);
                startActivityForResult(Intent.createChooser(intent,"Completa l'azione usando"),PICK_FROM_FILE);
            }
        }
    });
    final AlertDialog dialog=builder.create();
    mImageView=(ImageView)findViewById(R.id.immagine);
    bPhoto = (Button)findViewById(R.id.btnFoto);
    bPhoto.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            dialog.show();
        }
    });
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if(resultCode!=RESULT_OK)
        return;
    Bitmap bitmap = null;
    String path="";
    if(requestCode==PICK_FROM_FILE){
        imageCaptureUri=data.getData();
        path=getRealPathFromURI(imageCaptureUri);
        if(path==null)
            path=imageCaptureUri.getPath();
        if(path!=null){
            BitmapFactory.Options mBitMapOption = new BitmapFactory.Options();
            mBitMapOption.inSampleSize=2;
            bitmap= BitmapFactory.decodeFile(path,mBitMapOption);
        }

    }else{
        path=imageCaptureUri.getPath();
        BitmapFactory.Options mBitMapOption = new BitmapFactory.Options();
        mBitMapOption.inSampleSize=2;
        bitmap= BitmapFactory.decodeFile(path,mBitMapOption);
    }
    mImageView.setImageBitmap(bitmap);
}

public String getRealPathFromURI(Uri contentURI){
    String[] proj={MediaStore.Images.Media.DATA};
    Cursor cursor = managedQuery(contentURI,proj,null,null,null);
    if(cursor==null) return null;
    int column_index=cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
    cursor.moveToFirst();
    return cursor.getString(column_index);
}
}

Thank you in advance


第126行是什么? - ρяσѕρєя K
请将以下代码添加到清单文件中:<activity android:name=".activities.AchievementCompleted " android:configChanges="orientation|screenSize" /> - Ankita Shah
非常感谢!现在还有一件事..你知道为什么我设置在imageView中的每张图片都显示为横向模式吗?只有截图是以纵向模式显示的。 - Gianluca Ceccoli
https://dev59.com/KH_aa4cB1Zd3GeqP9_XR - Arpan Sharma
@GianlucaCeccoli 我也遇到了三星Tab 7的同样问题。你找到解决方案了吗? - happy_coding
显示剩余4条评论
2个回答

0

我也遇到了一些三星平板的同样问题,请在清单文件中添加android:configChanges="orientation|screenSize"


0

imageCaptureUri从未初始化。请交换这两行代码:

if(requestCode==PICK_FROM_FILE) { imageCaptureUri=data.getData(); 变为:

imageCaptureUri=data.getData();
if(requestCode==PICK_FROM_FILE) {    

所以初始化发生了。


1
仍然无法工作,我尝试像上面的Ankita Shah建议的那样在清单中添加android:configChanges="orientation|screenSize",它确实起作用,只需添加那一行即可。 - Gianluca Ceccoli

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接