新的KitKat URI不响应Intent.ACTION_VIEW

由于KitKat已将URI从拾取器更改为喜欢的

content://com.android.providers.media.documents/document/image:3951 

那时我的ACTION_VIEW意图都不再有用了。 例如,当用户选择图像时,我使用

 public static void openImage(Fragment f, Uri uri) { Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(uri, "image/*"); f.startActivity(intent); } 

并且Android图库和Google+照片会出现,但选中后,图库只显示空白屏幕,照片显示“未find中等”

声音是一样的,我习惯使用

 public static void playSound(Fragment f, Uri uri) { Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(uri, "audio/*"); f.startActivity(intent); } 

用于在以前的版本中显示Google Play音乐,使用小白色播放对话框UI。 使用新的URI,我得到一个例外,没有应用程序能够处理此意图。

//对于照片,有趣的是,当你在新的KK选择器UI中选择Gallery而不是Pictures时,它会返回有效的旧URI。

有任何想法吗? 系统应用程序还没有为新的uris做好准备吗? 我应该以某种方式将新的uris破解为旧的uris以使意图有效吗? 或者我错过了什么?

谢谢!

解决方案是将标志FLAG_GRANT_READ_URI_PERMISSION传递给intent(在KitKat及以上):

 intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 

还要确保从ACTION_OPEN_DOCUMENT意图中检索此内容Uri,如下所述: https : //stackoverflow.com/a/19874645/334209

您可以使用以下意图从库中选择图像

 Intent i = new Intent (Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(i, 2); 

并在onActivityResult中获取所选图像,

 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if(data==null)return; try { Bitmap bit = scaleImage(this, data.getData()); img.setImageBitmap(bit); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static Bitmap scaleImage(Context context, Uri photoUri) throws IOException { InputStream is = context.getContentResolver().openInputStream(photoUri); BitmapFactory.Options dbo = new BitmapFactory.Options(); dbo.inJustDecodeBounds = true; BitmapFactory.decodeStream(is, null, dbo); is.close(); int rotatedWidth, rotatedHeight; int orientation = getOrientation(context, photoUri); if (orientation == 90 || orientation == 270) { rotatedWidth = dbo.outHeight; rotatedHeight = dbo.outWidth; } else { rotatedWidth = dbo.outWidth; rotatedHeight = dbo.outHeight; } Bitmap srcBitmap; is = context.getContentResolver().openInputStream(photoUri); if (rotatedWidth > 100 || rotatedHeight > 100) { float widthRatio = ((float) rotatedWidth) / ((float) 100); float heightRatio = ((float) rotatedHeight) / ((float) 100); float maxRatio = Math.max(widthRatio, heightRatio); // Create the bitmap from file BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = (int) maxRatio; srcBitmap = BitmapFactory.decodeStream(is, null, options); } else { srcBitmap = BitmapFactory.decodeStream(is); } is.close(); /* * if the orientation is not 0 (or -1, which means we don't know), we * have to do a rotation. */ if (orientation > 0) { Matrix matrix = new Matrix(); matrix.postRotate(orientation); srcBitmap = Bitmap.createBitmap(srcBitmap, 0, 0, srcBitmap.getWidth(), srcBitmap.getHeight(), matrix, true); } String type = context.getContentResolver().getType(photoUri); ByteArrayOutputStream baos = new ByteArrayOutputStream(); if (type.equals("image/png")) { srcBitmap.compress(Bitmap.CompressFormat.PNG, 100, baos); } else if (type.equals("image/jpg") || type.equals("image/jpeg")) { srcBitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos); } byte[] bMapArray = baos.toByteArray(); baos.close(); return BitmapFactory.decodeByteArray(bMapArray, 0, bMapArray.length); } public static int getOrientation(Context context, Uri photoUri) { /* it's on the external media. */ Cursor cursor = context.getContentResolver().query(photoUri, new String[] { MediaStore.Images.ImageColumns.ORIENTATION }, null, null, null); if (cursor.getCount() != 1) { return -1; } cursor.moveToFirst(); return cursor.getInt(0); }