在我的应用程序中我试图从厨房中选择图像,以便将该图像传递给服务器。
Code 5在Android 5及更低版本上正常运行,但对于Nexus 5上的Android 6,我无法获取图像信息。 我得到的日志跟踪
注意:Android 5及以下版本的代码正常运行
11-06 12:27:43.736: W/System.err(31678): java.lang.SecurityException: Permission Denial: reading com.google.android.apps.photos.contentprovider.MediaContentProvider uri content://com.google.android.apps.photos.contentprovider/0/1/content%3A//media/external/images/media/19138/ACTUAL/94710853 from pid=31678, uid=10111 requires the provider be exported, or grantUriPermission()
11-06 12:27:43.757: W/System.err(31678):
at android.os.Parcel.readException(Parcel.java:1599)
11-06 12:27:43.757: W/System.err(31678):
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:183)
11-06 12:27:43.757: W/System.err(31678):
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:135)
11-06 12:27:43.757: W/System.err(31678):
at android.content.ContentProviderProxy.query(ContentProviderNative.java:421)
11-06 12:27:43.757: W/System.err(31678):
at android.content.ContentResolver.query(ContentResolver.java:491)
11-06 12:27:43.757: W/System.err(31678):
at android.content.ContentResolver.query(ContentResolver.java:434)
11-06 12:27:43.758: W/System.err(31678):
at org.apache.cordova.file.ContentFilesystem.openCursorForURL(ContentFilesystem.java:258)
11-06 12:27:43.758: W/System.err(31678):
at org.apache.cordova.file.ContentFilesystem.getFileMetadataForLocalURL(ContentFilesystem.java:169)
11-06 12:27:43.758: W/System.err(31678):
at org.apache.cordova.file.FileUtils.getFileMetadata(FileUtils.java:822)
11-06 12:27:43.758: W/System.err(31678):
at org.apache.cordova.file.FileUtils.access$500(FileUtils.java:52)
11-06 12:27:43.758: W/System.err(31678):
at org.apache.cordova.file.FileUtils$15.run(FileUtils.java:394)
11-06 12:27:43.758: W/System.err(31678):
at org.apache.cordova.file.FileUtils$25.run(FileUtils.java:551)
11-06 12:27:43.758: W/System.err(31678):
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
11-06 12:27:43.758: W/System.err(31678):
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
11-06 12:27:43.758: W/System.err(31678):
at java.lang.Thread.run(Thread.java:818)
答案 0 :(得分:21)
这样做...... 按钮单击检查SDK版本
if (Build.VERSION.SDK_INT >= 23){
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(MainActivity.this,
Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
Manifest.permission.READ_EXTERNAL_STORAGE)) {
// Show an expanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
// MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE is an
// app-defined int constant. The callback method gets the
// result of the request.
}
}else{
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
}
}else {
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
photoPickerIntent.setType("image/*");
startActivityForResult(photoPickerIntent, SELECT_PHOTO);
}
之后在Override方法onRequestPermissionsResult中编写此代码:
case MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// contacts-related task you need to do.
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
photoPickerIntent.setType("image/*");
startActivityForResult(photoPickerIntent, SELECT_PHOTO);
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
}
return;
}
之后
@Override
protected void onActivityResult(int reqCode, int resultCode, Intent data) {
super.onActivityResult(reqCode, resultCode, data);
switch (reqCode) {
case SELECT_PHOTO:
if (resultCode == RESULT_OK) {
try {
final Uri imageUri = data.getData();
final InputStream imageStream = getContentResolver().openInputStream(imageUri);
final Bitmap selectedImage = BitmapFactory.decodeStream(imageStream);
contactimage.setImageBitmap(selectedImage);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
答案 1 :(得分:5)
我相信您需要在运行时向用户请求权限(这是从api 22到23的最明显的变化之一)。
您可以尝试从Android Developers permission page
中提取的此代码段if (Build.VERSION.SDK_INT >= 23){
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
Manifest.permission.READ_EXTERNAL_STORAGE)) {
// Show an expanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(thisActivity,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
// MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE is an
// app-defined int constant. The callback method gets the
// result of the request.
}
}
}
如果有帮助,请告诉我。
答案 2 :(得分:2)
要从Marshmallow中的图库中获取图像,您需要在运行时授予 READ_EXTERNAL_STORAGE 权限。 Android版本M已经改变了授予应用程序权限的方式。
在Marshmallow之前,所有必需的权限都会立即授予,即在安装时。但是在Marshmallow中,只有在需要该权限的情况下才会要求用户获得许可,并且用户必须允许或拒绝该权限。
以下两个链接将为您提供更多帮助。链接1来自Android的官方文档,而链接2是一个博客,用一个工作示例解释了这个问题。
Link1:http://developer.android.com/training/permissions/requesting.html
答案 3 :(得分:2)
我有同样的问题。使用
从图库中选取图像后,图像显示在Imageview中Intent galleryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Video.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(galleryIntent, videoIdentifier);
并从URI
解码位图图像但保存URI以备将来使用并重新打开应用程序并重新使用已保存的URI无效。无法从URI解码位图。
我通过从URI路径
中提取原始内容uri解决了这个问题public String RemoveUnwantedString(String pathUri){
//pathUri = "content://com.google.android.apps.photos.contentprovider/-1/2/content://media/external/video/media/5213/ORIGINAL/NONE/2106970034"
String[] d1 = pathUri.split("content://");
for (String item1:d1) {
if (item1.contains("media/")) {
String[] d2 = item1.split("/ORIGINAL/");
for (String item2:d2) {
if (item2.contains("media/")) {
pathUri = "content://" + item2;
break;
}
}
break;
}
}
//pathUri = "content://media/external/video/media/5213"
return pathUri;
}
答案 4 :(得分:0)
这是我用其他例子创建的简单方法
调用CHECKGALLERYPERMISSION()方法,将代码粘贴到方法
中 private void CHECKGALLERYPERMISSION()
{
int MY_READ_PERMISSION_REQUEST_CODE =1 ;
int PICK_IMAGE_REQUEST = 2;
if (ContextCompat.checkSelfPermission(YourActivity.this, android.Manifest.permission.READ_EXTERNAL_STORAGE)== PackageManager.PERMISSION_GRANTED)
{
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE_REQUEST);
}
else
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
{
requestPermissions(
new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE},
MY_READ_PERMISSION_REQUEST_CODE);
}
else
{
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[]
permissions, int[] grantResults) {
if (requestCode == MY_READ_PERMISSION_REQUEST_CODE
&& grantResults[0] == PackageManager.PERMISSION_GRANTED)
{
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE_REQUEST);
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null)
{
Uri uri = data.getData();
try
{
Bitmap bitmap = MediaStore.Images.Media.getBitmap(YourActivity.this.getContentResolver(), uri);
imageview.setImageBitmap(bitmap);
}
catch (IOException e)
{
e.printStackTrace();
}
}
}