【问题标题】:camera crashes on startactcityforresult and onactivity result in turn fails相机在 startactivityforresult 和 onactivityresult 上崩溃依次失败
【发布时间】:2016-08-14 13:47:20
【问题描述】:

我正在尝试使用以下方法将图像上传到 Firebase 存储

 @AfterPermissionGranted(RC_STORAGE_PERMS)
private void launchCamera() {
    Log.d(TAG, "launchCamera");

    // Check that we have permission to read images from external storage.
    String perm = Manifest.permission.WRITE_EXTERNAL_STORAGE;
    if (!EasyPermissions.hasPermissions(this, perm)) {
        EasyPermissions.requestPermissions(this, getString(R.string.rationale_storage),
                RC_STORAGE_PERMS, perm);
        return;
    }


    // Choose file storage location, must be listed in res/xml/file_paths.xml
    File dir = new File(Environment.getExternalStorageDirectory() + "/photos");
    File file = new File(dir, UUID.randomUUID().toString() + ".jpg");
    try {
        // Create directory if it does not exist.
        if (!dir.exists()) {
            dir.mkdir();
        }
        boolean created = file.createNewFile();
        Log.d(TAG, "file.createNewFile:" + file.getAbsolutePath() + ":" + created);
    } catch (IOException e) {
        Log.e(TAG, "file.createNewFile" + file.getAbsolutePath() + ":FAILED", e);
    }

    // Create content:// URI for file, required since Android N
    // See: https://developer.android.com/reference/android/support/v4/content/FileProvider.html
    mFileUri = FileProvider.getUriForFile(this,
            "com.mordred.youlift.fileprovider", file);



    //this is my own set of fixes to grant permission to uri, not sure its neceary though, seems like overkill
    Context context = this;
    Intent intent = new Intent();
    intent.setAction(Intent.ACTION_SEND);
    List<ResolveInfo> resInfoList = context.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
    for (ResolveInfo resolveInfo : resInfoList) {
        String packageName = resolveInfo.activityInfo.packageName;
        context.grantUriPermission(packageName, mFileUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
    }
    // Create and launch the intent
    context.grantUriPermission(getPackageName(), mFileUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    takePictureIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, mFileUri);

    //condition suggested by android developers
    if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
        startActivityForResult(takePictureIntent, RC_TAKE_PICTURE);
    }
}

当我拍照时相机崩溃,并且应用程序根据我的 onactivityresult() 函数中的 if 结构显示“拍照失败”。这是它的代码

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        Log.d(TAG, "onActivityResult:" + requestCode + ":" + resultCode + ":" + data);
        if (requestCode == RC_TAKE_PICTURE) {
            if (resultCode == RESULT_OK) {
                if (mFileUri != null) {
                    uploadFromUri(mFileUri);
                } else {
                    Log.w(TAG, "File URI is null");
                }
            } else {
                Toast.makeText(this, "Taking picture failed.", Toast.LENGTH_SHORT).show();
            }
        }
    }

我的堆栈跟踪是

08-14 14:22:39.722 26970-26970/com.mordred.youlift D/PictureActivity: launchCamera
08-14 14:22:39.727 26970-26970/com.mordred.youlift I/dalvikvm: Could not find method android.app.Fragment.requestPermissions, referenced from method pub.devrel.easypermissions.EasyPermissions.executePermissionsRequest
08-14 14:22:39.727 26970-26970/com.mordred.youlift W/dalvikvm: VFY: unable to resolve virtual method 391: Landroid/app/Fragment;.requestPermissions ([Ljava/lang/String;I)V
08-14 14:22:39.727 26970-26970/com.mordred.youlift D/dalvikvm: VFY: replacing opcode 0x6e at 0x001d
08-14 14:22:39.727 26970-26970/com.mordred.youlift I/dalvikvm: Could not find method android.app.Fragment.shouldShowRequestPermissionRationale, referenced from method pub.devrel.easypermissions.EasyPermissions.shouldShowRequestPermissionRationale
08-14 14:22:39.727 26970-26970/com.mordred.youlift W/dalvikvm: VFY: unable to resolve virtual method 396: Landroid/app/Fragment;.shouldShowRequestPermissionRationale (Ljava/lang/String;)Z
08-14 14:22:39.727 26970-26970/com.mordred.youlift D/dalvikvm: VFY: replacing opcode 0x6e at 0x001c
08-14 14:22:39.727 26970-26970/com.mordred.youlift W/EasyPermissions: hasPermissions: API version < M, returning true by default
08-14 14:22:39.742 26970-26970/com.mordred.youlift D/PictureActivity: file.createNewFile:/storage/sdcard0/photos/a520231b-ff0c-435d-a3db-a3e9816d6726.jpg:true
08-14 14:22:42.682 26970-26970/com.mordred.youlift W/IInputConnectionWrapper: showStatusIcon on inactive InputConnection
08-14 14:23:26.567 26970-26983/com.mordred.youlift E/DatabaseUtils: Writing exception to parcel
                                                                              java.lang.SecurityException: Permission Denial: reading android.support.v4.content.FileProvider uri                      content://com.mordred.youlift.fileprovider/external/a520231b-ff0c-435d-a3db-a3e9816d6726.jpg from pid=27383, uid=1000 requires the provider be exported, or grantUriPermission()
                                                                    at android.content.ContentProvider$Transport.enforceReadPermission(ContentProvider.java:332)
                                                                    at android.content.ContentProvider$Transport.openAssetFile(ContentProvider.java:250)
                                                                    at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:236)
                                                                    at android.os.Binder.execTransact(Binder.java:367)
                                                                    at dalvik.system.NativeStart.run(Native Method)
08-14 14:23:27.597 26970-26970/com.mordred.youlift D/PictureActivity: onActivityResult:101:0:null

【问题讨论】:

    标签: android file storage


    【解决方案1】:

    首先,您的循环活动是针对ACTION_SEND,这对您没有任何好处,因为您使用的是ACTION_IMAGE_CAPTURE。

    其次,将Intent.FLAG_GRANT_WRITE_URI_PERMISSION添加到takePictureIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);。

    另请注意,您只需执行以下操作之一:addFlags() 或 grantUriPermission(),具体取决于操作系统版本:

      if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.LOLLIPOP) {
        i.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
      }
      else {
        List<ResolveInfo> resInfoList=
          getPackageManager()
            .queryIntentActivities(i, PackageManager.MATCH_DEFAULT_ONLY);
    
        for (ResolveInfo resolveInfo : resInfoList) {
          String packageName = resolveInfo.activityInfo.packageName;
          grantUriPermission(packageName, outputUri,
            Intent.FLAG_GRANT_WRITE_URI_PERMISSION |
              Intent.FLAG_GRANT_READ_URI_PERMISSION);
        }
      }
    

    (其中i 是ACTION_IMAGE_CAPTURE Intent)

    Here is the full activity 该代码的来源。

    【讨论】:

    • 非常感谢,这正是我的问题,现在可以了。但是,我对如何从手机中抓取图像而不是拍照感到困惑,你能指导我看任何文章吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-04
    • 1970-01-01
    相关资源
    最近更新 更多