android6.0无法获得图库路径,我有使用权限

时间:2016-10-28 12:35:22

标签: android

我想从我的照片库中获取照片以裁剪它,但路径为空。 Andorid5.0可以使用这种方式,但Android 6.0和Android 7.0无法使用这种方式。我有这个应用程序许可。

public void initPop(View view) {
    albums = (TextView)view.findViewById(R.id.albums);
    cancel = (LinearLayout) view.findViewById(R.id.cancel);
    albums.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            popupWindow.dismiss();
            Intent openAlbumIntent = new Intent(Intent.ACTION_GET_CONTENT);
            openAlbumIntent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
            startActivityForResult(openAlbumIntent, PHOTOZOOM);
        }
    });
    cancel.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            popupWindow.dismiss();
        }
    });
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode != RESULT_OK) {
        return;
    }
    Uri uri = null;
    switch (requestCode) {
        case PHOTOZOOM:
            if (data == null) {
                return;
            }
            uri = data.getData();
            String[] proj = {
                    MediaStore.Images.Media.DATA
            };
            Cursor cursor = getContentResolver().query(uri, proj, null, null, null);
            if (cursor != null) {
                int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                cursor.moveToFirst();
                Log.i("Ienning", "onActivityResult: the cursor is " + column_index);
                path = cursor.getString(column_index);
            }
            Intent intent3 = new Intent(PersonCenter.this, ClipActivity.class);
            intent3.putExtra("path", path);
            Log.i("Ienning", "The Path is " + path);
            startActivityForResult(intent3, IMAGE_COMPLETE);
            break;
        case IMAGE_COMPLETE:
            final String temppath = data.getStringExtra("path");
            editor.putString("temppath", temppath);
            editor.commit();
            head.setImageBitmap(getLoacalBitmap(temppath));
            break;
        default:
            break;
    }
    super.onActivityResult(requestCode, resultCode, data);
}

许可代码:

public void getpermission() {
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
        if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE))
        {
            new AlertDialog.Builder(this)
                    .setMessage("get permission")
                    .setPositiveButton("ok", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            ActivityCompat.requestPermissions(PersonCenter.this, new String[] {Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS}, MY_PERMISSIONS_REQUEST_WRITE_STORAGE);
                        }
                    }).show();
        } else {
            ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS}, MY_PERMISSIONS_REQUEST_WRITE_STORAGE);
        }
    }
    else {
        Log.i("Ienning", " this is ok manifest permission");
    }
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == MY_PERMISSIONS_REQUEST_WRITE_STORAGE) {
        if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            Log.i("Ienning", "onRequestPermissionResult: the result permission is ok!");
        } else {
            if (!ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                Toast.makeText(this, "permission denied!", Toast.LENGTH_SHORT).show();
            }
        }
        return;
    }
}

并且loginfo是

10-28 19:39:44.424 25265-25265/com.example.ienning.ncuhome I/Ienning: onActivityResult: the cursor is 0
10-28 19:39:44.425 25265-25265/com.example.ienning.ncuhome I/Ienning: The Path is null

1 个答案:

答案 0 :(得分:1)

  

Andorid5.0可以使用这种方式

你没有很好地测试它。您的方法将在所有Android设备上失败,至少在某些时候。它会在Android 6.0 +上更频繁地失败。

您的代码有两个无效的假设:

  • 您认为Uri返回的ACTION_GET_CONTENTMediaStore有关。这是不正确的。从Uri返回的ACTION_GET_CONTENT可以是用户选择的活动想要返回的任何内容。所有或多或少的保证是您可以使用ContentResolveropenInputStream()来阅读内容。

  • 您认为MediaStore始终会为您提供可用的DATA列。即使MediaStore碰巧知道Uri(参见上一个项目符号),也不要求这样做。

如果您从Uri返回的ACTION_GET_CONTENT方案为file,则getPath()将成为文件系统路径。您可以使用该路径(否则,第三方应用中的错误会为您提供Uri)。

更常见的是,Uri的方案为content。在这种情况下,您可以使用ContentResolveropenInputStream()来读取Uri标识的内容,但Uri <后面没有必需的文件系统路径/ em>的。 Uri可以指向其他开发人员想要的任何内容:数据库中的BLOB列,无法访问的位置中的文件,因为它尚未下载需要下载的数据在设备上等。