Android Gallery on Android 4.4 (KitKat) returns different URI for Intent.ACTION_GET_CONTENT

后端 未结 19 2268
温柔的废话
温柔的废话 2020-11-22 02:44

Before KitKat (or before the new Gallery) the Intent.ACTION_GET_CONTENT returned a URI like this

content://media/external/images/media/39

19条回答
  •  孤独总比滥情好
    2020-11-22 03:09

    I've tried several of the answers here, and I think I have a solution that will work every time and manages permissions as well.

    It is based on the clever solution from LEO. This post should contain all the code you need to make this work, and it should work on any phone and Android version ;)

    In order to have the ability to pick a file from an SD card, you'll need this in your manifest:

    
    

    Constants:

    private static final int PICK_IMAGE = 456; // Whatever number you like
    public static final int MY_PERMISSIONS_REQUEST_READ_EXTERNAL = 28528; // Whatever number you like
    public static final String FILE_TEMP_NAME = "temp_image"; // Whatever file name you like
    

    Check permission and launchImagePick if possible

    if (ContextCompat.checkSelfPermission(getThis(),
            Manifest.permission.READ_EXTERNAL_STORAGE)
            != PackageManager.PERMISSION_GRANTED) {
    
        ActivityCompat.requestPermissions(getThis(),
                new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
                MY_PERMISSIONS_REQUEST_READ_EXTERNAL);
    }
    else {
        launchImagePick();
    }
    

    Permission response

    @Override
    public void onRequestPermissionsResult(int requestCode,
                                           @NonNull
                                             String permissions[],
                                           @NonNull
                                             int[] grantResults) {
    
        if (manageReadExternalPermissionResponse(this, requestCode, grantResults)) {
            launchImagePick();
        }
    }
    

    Manage permission response

    public static boolean manageReadExternalPermissionResponse(final Activity activity, int requestCode, int[] grantResults) {
    
        if (requestCode == MY_PERMISSIONS_REQUEST_READ_EXTERNAL) {
    
            // 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.
                return true;
    
            } else if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_DENIED) {
    
                boolean showRationale = ActivityCompat.shouldShowRequestPermissionRationale(activity,
                        Manifest.permission.READ_EXTERNAL_STORAGE);
    
                if (!showRationale) {
                    // The user also CHECKED "never ask again".
                    // You can either enable some fall back,
                    // disable features of your app
                    // or open another dialog explaining
                    // again the permission and directing to
                    // the app setting.
    
                } else {
                    // The user did NOT check "never ask again".
                    // This is a good place to explain the user
                    // why you need the permission and ask if he/she wants
                    // to accept it (the rationale).
                }
            } else {
                // Permission denied, boo! Disable the
                // functionality that depends on this permission.
            }
        }
        return false;
    }
    

    Launch image pick

    private void launchImagePick() {
    
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        intent.setType("image/*");
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        startActivityForResult(intent, PICK_IMAGE);
    
        // see onActivityResult
    }
    

    Manage Image pick response

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == PICK_IMAGE) {
    
            if (resultCode == Activity.RESULT_OK) {
                if (data != null && data.getData() != null) {
    
                    try {
                         InputStream inputStream = getContentResolver().openInputStream(data.getData())
                         if (inputStream != null) {
    
                            // No special persmission needed to store the file like that
                            FileOutputStream fos = openFileOutput(FILE_TEMP_NAME, Context.MODE_PRIVATE);
    
                            final int BUFFER_SIZE = 1 << 10 << 3; // 8 KiB buffer
                            byte[] buffer = new byte[BUFFER_SIZE];
                            int bytesRead = -1;
                            while ((bytesRead = inputStream.read(buffer)) > -1) {
                                fos.write(buffer, 0, bytesRead);
                            }
                            inputStream.close();
                            fos.close();
    
                            File tempImageFile = new File(getFilesDir()+"/"+FILE_TEMP_NAME);
    
                            // Do whatever you want with the File
    
                            // Delete when not needed anymore
                            deleteFile(FILE_TEMP_NAME);
                        }
                    }
                    catch (Exception e) {
                        e.printStackTrace();
                    }
                } else {
                    // Error display
                }
            } else {
                // The user did not select any image
            }
        }
    }
    

    That's all folks; this works for me on all the telephones I have.

提交回复
热议问题