Android: невозможно открыть загруженный файл из уведомления. Ошибка: "Не удается открыть файл"

Мое приложение загружает файл из Интернета и сохраняет его в папке "Загрузки", а также предоставляет уведомление о том, что файл был загружен. Когда я нажимаю на уведомление, я создал chooserIntent, чтобы выбрать приложение, чтобы открыть файл. Тем не менее, любое приложение, которое я выберу, не откроет файл с сообщением об ошибке: "Не удается открыть файл", но когда я иду в файловый менеджер, он открывается нормально. Я думаю, это связано с разрешениями? Кстати, Uri получается так (Android 7.1):

Uri fileUri = FileProvider.getUriForFile(getActivityContext(), getAppContext().getPackageName() + ".provider", file);

Вот мой код для уведомления:

private Notification downloadCompleteNotification(String title, String message, Uri uri) {
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    intent.setDataAndType(uri, "*/*");
    Intent chooser = Intent.createChooser(intent, getResources().getString(R.string.open_file_with));
    NotificationCompat.Builder builder = initBasicBuilder(title, message, intent);
    builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_u));
    builder.setOngoing(false);

    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, chooser, 0);
    builder.setContentIntent(pendingIntent);
    return builder.build();
}

private NotificationCompat.Builder initBasicBuilder(String title, String text, Intent intent) {
    NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
    builder.setSmallIcon(R.drawable.u)
            .setContentTitle(title)
            .setContentText(text);
    if (intent != null) {
        TaskStackBuilder taskStackBuilder = TaskStackBuilder.create(this);
        taskStackBuilder.addNextIntentWithParentStack(intent);
    }
    return builder;
}

2 ответа

Поместите этот код в ваш метод метода onCreate. Вы можете добавить несколько разрешений здесь через запятую

int PERMISSION_ALL = 1;
        String[] PERMISSIONS = {android.Manifest.permission.READ_EXTERNAL_STORAGE};

        if(!hasPermissions(this, PERMISSIONS)){
            ActivityCompat.requestPermissions(this, PERMISSIONS, PERMISSION_ALL);
        }

И добавьте эту функцию:

public static boolean hasPermissions(Context context, String... permissions) {
        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && context != null && permissions != null) {
            for (String permission : permissions) {
                if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
                    return false;
                }
            }
        }
        return true;
    }

Если вы используете API level 23 или выше. Вам нужно дать Run Time разрешение. Как и внутри файла манифеста.

private static final int REQUEST_EXTERNAL_STORAGE = 1;
private static String[] PERMISSIONS_STORAGE = {
     Manifest.permission.READ_EXTERNAL_STORAGE,
     Manifest.permission.WRITE_EXTERNAL_STORAGE
};


private boolean checkPermissions() {
        int result;
        List<String> listPermissionsNeeded = new ArrayList<>();
        for (String p : PERMISSIONS_STORAGE) {
            result = ContextCompat.checkSelfPermission(mContext, p);
            if (result != PackageManager.PERMISSION_GRANTED) {
                listPermissionsNeeded.add(p);
            }
        }
        if (!listPermissionsNeeded.isEmpty()) {
            ActivityCompat.requestPermissions(this, listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]), REQUEST_EXTERNAL_STORAGE);
            return false;
        }
        return true;
    }

@Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode) {
            case REQUEST_EXTERNAL_STORAGE:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // Permission granted.
                } else {
                    //code for deny
                }
                break;
        }
    }
Другие вопросы по тегам