API级别上的空URI> = 23相机意图

时间:2017-12-26 13:22:57

标签: android nullpointerexception android-6.0-marshmallow android-camera-intent android-api-levels

这可能是重复的,但我似乎无法确定准确的解决方案。 相机工作正常,并在api 23以下的设备上返回图像uri。 然而,app在设备apove api 23上捕获图像后立即崩溃并出现日志错误

java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=2, result=-1, data=Intent { act=inline-data (has extras) }} to activity {ana.foodi/ana.foodi.MainActivity}: java.lang.NullPointerException: uri
                                                         at android.app.ActivityThread.deliverResults(ActivityThread.java:3940)
                                                         at android.app.ActivityThread.handleSendResult(ActivityThread.java:3983)
                                                         at android.app.ActivityThread.-wrap16(ActivityThread.java)
                                                         at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1548)
                                                         at android.os.Handler.dispatchMessage(Handler.java:111)
                                                         at android.os.Looper.loop(Looper.java:207)
                                                         at android.app.ActivityThread.main(ActivityThread.java:5765)
                                                         at java.lang.reflect.Method.invoke(Native Method)
                                                         at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
                                                         at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:679)
                                                      Caused by: java.lang.NullPointerException: uri
                                                         at com.android.internal.util.Preconditions.checkNotNull(Preconditions.java:60)
                                                         at android.content.ContentResolver.query(ContentResolver.java:481)
                                                         at android.content.ContentResolver.query(ContentResolver.java:441)
                                                         at ana.foodi.MainActivity.onActivityResult(MainActivity.java:672)

使用断点检查后,实现的Uri(selectedImage)在下面为空:

 @Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    final String filePath;
    if(resultCode == Activity.RESULT_OK && REQUEST_POST_PHOTO==999){


        if(requestCode == 2 ) {
            requestRuntimePermission();
            Uri selectedImage = data.getData();
            String[] filePaths = {MediaStore.Images.Media.DATA};
            Cursor c = this.getContentResolver().query(selectedImage, filePaths, null, null, null);
            c.moveToFirst();
            int columnIndex = c.getColumnIndex(filePaths[0]);
            filePath = c.getString(columnIndex);
            c.close();

我已尝试使用此

请求运行时权限
public void requestRuntimePermission() {
    if (Build.VERSION.SDK_INT >= 23) {
        if (ContextCompat.checkSelfPermission(context,android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this,
                    new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
        }
    }
}

但错误仍然存​​在。

startActivityForResult调用

REQUEST_POST_PHOTO=999;
                Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                startActivityForResult(cameraIntent, REQUEST_CODE_POST);

5 个答案:

答案 0 :(得分:1)

您正在使用ACTION_IMAGE_CAPTUREACTION_IMAGE_CAPTURE不应通过Uri返回onActivityResult()。相反,要么:

  • 您在EXTRA_OUTPUT ACTION_IMAGE_CAPTURE上提供Intent,在这种情况下,图片应该保存到该位置(请参阅this sample app)或< / p>

  • 您未在EXTRA_OUTPUT ACTION_IMAGE_CAPTURE上提供Intent,在这种情况下,您会通过Bitmap附加信息获得缩略图"data" Intent已发送至onActivityResult()

the documentation中介绍了这一点。

某些有缺陷的相机应用返回Uri。不要指望这种行为,因为写得好的相机应用程序不会。

答案 1 :(得分:0)

试试这个

使用WRITE_EXTERNAL_STORAGEWRITE_EXTERNAL_STORAGE来读取和写入文件

<uses-feature android:name="android.hardware.camera2" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

这里要求写入权限&amp;读取权限添加多个权限

public void requestRuntimePermission() {
    if (Build.VERSION.SDK_INT >= 23) {
        if (ContextCompat.checkSelfPermission(context,android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this,
                    new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
        }
    }
}

选中此Android 6.0 multiple permissions

//如果已授予,则检查是否授予权限,然后调用此块

        Uri selectedImage = data.getData();
        String[] filePaths = {MediaStore.Images.Media.DATA};
        Cursor c = this.getContentResolver().query(selectedImage, filePaths, null, null, null);
        c.moveToFirst();
        int columnIndex = c.getColumnIndex(filePaths[0]);
        filePath = c.getString(columnIndex);
        c.close();

答案 2 :(得分:0)

至少对于旧版本,如果允许多个选择(Intent#EXTRA_ALLOW_MULTIPLE),URI将作为剪贴板数据返回:

data.getClipData()

请参阅Intent#getClipData()ClipData

检查数据是否在那里返回:

ClipData clipData = data.getClipData();
Uri selectedImage = null;
if (clipData != null) {
    selectedImage = clipData.getItemAt(0).getUri();
} else {
    selectedImage = data.getData();
}

答案 3 :(得分:0)

 targetSdkVersion 21
 change your targetsdk version in build.gradle to marshmallow it will be solved. 

答案 4 :(得分:0)

private static final int REQUEST_CODE_IMAGE = 1000;
private String importFileName = "";

private void cameraIntent() {
    importFileName = getString(R.string.app_name) + new Random().nextInt();
    startActivityForResult(getCameraIntent(context, importFileName), REQUEST_CODE_IMAGE);
}

public Intent getCameraIntent(Context context, String fileName) {
    Intent chooserIntent = null;
    List<Intent> intentList = new ArrayList<>();
    Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    takePhotoIntent.putExtra("return-data", true);
    takePhotoIntent.putExtra(MediaStore.EXTRA_SCREEN_ORIENTATION, context.getResources().getConfiguration().orientation);
    takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(context.getExternalCacheDir(), fileName)));
    intentList = addIntentsToList(context, intentList, Collections.singletonList(takePhotoIntent));

    if (intentList.size() > 0) {
        String title = context.getResources().getString(R.string.choose);
        chooserIntent = Intent.createChooser(intentList.remove(intentList.size() - 1), title);
        chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentList.toArray(new Parcelable[]{}));
    }
    return chooserIntent;
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    switch (requestCode) {
        case REQUEST_CODE_IMAGE:
            if (resultCode == RESULT_OK) {
                onCaptureImageResult(data);
            }
            break;
    }
}

private void onCaptureImageResult(Intent data) {
    Uri imageUri;
    if (data == null) {
        imageUri = Uri.fromFile(new File(getExternalCacheDir(), importFileName));
    } else {
        imageUri = data.getData();
        if (imageUri == null)
            imageUri = Uri.fromFile(new File(getExternalCacheDir(), importFileName));
    }
}

如果您从用户那里获得权限(相机,读/写外部存储权限),则此代码段将正常运行。你可以调用cameraIntent()。