【问题标题】:Android: Cannot open downloaded file from notification. Error: "Can't open file"Android:无法从通知中打开下载的文件。错误:“无法打开文件”
【发布时间】:2017-01-25 10:11:32
【问题描述】:

我的应用程序从 Internet 下载文件并将其保存到“下载”文件夹中,并提供通知,该文件已下载。当我单击通知时,我创建了选择器意图来选择一个应用程序来打开文件。但是,我选择的任何应用程序都不会打开带有错误消息的文件:“无法打开文件”,但是当我转到文件管理器时,它可以正常打开。我想这与权限有关吗? 顺便说一句,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;
}

【问题讨论】:

  • 你的安卓版本?
  • 如我所说:android 7.1。
  • 哦,我错过了。您是否授予了 READ_EXTERNAL_STORAGE 运行时权限?
  • 我已经在 Manifest 文件中定义了它,但我没有在运行时。我现在会调查一下。
  • No.. 你应该为最新版本做运行时权限.. 试试看.. 这里是可以帮助你的链接:sitepoint.com/requesting-runtime-permissions-in-android-m-and-n

标签: android android-volley android-notifications android-pendingintent


【解决方案1】:

将此代码放入您的 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;
    }

【讨论】:

    【解决方案2】:

    如果您使用的是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;
            }
        }
    

    【讨论】:

    • 我尝试过请求读取权限,但似乎该应用程序具有这些权限。我通过调试检查。再次说明,外部应用程序在收到我的应用程序通知时无法打开下载的文件,但实际上可以从文件管理器中打开它。
    猜你喜欢
    • 1970-01-01
    • 2015-01-03
    • 1970-01-01
    • 2019-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-08
    • 1970-01-01
    相关资源
    最近更新 更多