iening iening - 1 month ago 7
Android Question

android6.0 can't get gallery path , I have got uses-permission

I want to get photo from my photo gallery to crop it, but the path is null. Andorid5.0 can use this way, but Android 6.0 and Android 7.0 can't use this way. I have got this app permission.

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);
}


And permission code:

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;
}
}


And loginfo is

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

Answer

Andorid5.0 can use this way

You did not test it very well. Your approach will fail on all Android devices, at least some of the time. It will fail more frequently on Android 6.0+.

Your code makes two invalid assumptions:

  • You assume that the Uri that comes back from ACTION_GET_CONTENT has something to do with the MediaStore. This is incorrect. The Uri that comes back from ACTION_GET_CONTENT can be anything that the user-selected activity wants to return. All that is more-or-less guaranteed is that you can use ContentResolver and openInputStream() to read the content.

  • You assume that the MediaStore will always give you a DATA column that is usable. That is not a requirement, even if the MediaStore happens to know about the Uri (see the previous bullet).

If the scheme of the Uri that you get back from ACTION_GET_CONTENT is file, then getPath() will be a filesystem path. You may be able to use that path (otherwise, it is a bug in the third-party app that gave you that Uri).

More commonly, the scheme of the Uri will be content. In that case, you can use ContentResolver and openInputStream() to read in the content identified by that Uri, but there is no required filesystem path behind that Uri. That Uri can point to anything the other developer wants: BLOB columns in databases, files in locations that you cannot access, data that needs to be downloaded because it is not yet on the device, etc.