New KitKat URIs dont respond to Intent.ACTION_VIEW

2019-03-25 06:22发布

Since KitKat has changed the URIs from pickers to likes of

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

then none of my ACTION_VIEW intents work anymore. When for example user picks an image, I use

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

        f.startActivity(intent);
    }

and Android Gallery and Google+ Photos come up, but when selected, the Gallery just shows blank screens, Photos says "medium not found"

The same thing with sounds, I am used to use

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

    f.startActivity(intent);
}

Which used to show Google Play Music in previous versions, with the little white playing dialog UI. With the new URIs, I get exception that no app is able to handle this intent.

// With photos, the funny thing is that, when you choose Gallery instead of the Pictures in the new KK picker UI, it returns the old URIs which work.

Any ideas? Are the system apps just not ready for the new uris? Should I somehow hack the new uris to old ones to make intents work? Or am I missing something?

Thanks!

2条回答
劳资没心,怎么记你
2楼-- · 2019-03-25 06:28

The solution is to pass the flag FLAG_GRANT_READ_URI_PERMISSION to the intent (on KitKat and above):

intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

Also make sure that this content Uri was retrieved from an ACTION_OPEN_DOCUMENT intent as described here: https://stackoverflow.com/a/19874645/334209

查看更多
闹够了就滚
3楼-- · 2019-03-25 06:41

You can use the following intent to pick an image from the gallery

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

and the get the selected image in onActivityResult like,

@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);
    }
查看更多
登录 后发表回答