【问题标题】:What permissions do I need to download files?下载文件需要什么权限?
【发布时间】:2018-09-10 09:18:43
【问题描述】:

我正在尝试使用 DownloadManager 类下载文件。

public void downloadFile(View view) {

    String urlString = "your_url_here";
    try {
        // Get file name from the url
        String fileName = urlString.substring(urlString.lastIndexOf("/") + 1);
        // Create Download Request object
        DownloadManager.Request request = new DownloadManager.Request(Uri.parse((urlString)));
        // Display download progress and status message in notification bar
        request.setNotificationVisibility(Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
        // Set description to display in notification
        request.setDescription("Download " + fileName + " from " + urlString);
        // Set title
        request.setTitle("DownloadManager");
        // Set destination location for the downloaded file
        request.setDestinationUri(Uri.parse("file://" + Environment.getExternalStorageDirectory() + "/" + fileName));
        // Download the file if the Download manager is ready
        did = dManager.enqueue(request);

    } catch (Exception e) {
    }
}

// BroadcastReceiver to receive intent broadcast by DownloadManager
private BroadcastReceiver downloadReceiver = new BroadcastReceiver() {

    @Override
    public void onReceive(Context arg0, Intent arg1) {
        // TODO Auto-generated method stub
        Query q = new Query();
        q.setFilterById(did);
        Cursor cursor = dManager.query(q);
        if (cursor.moveToFirst()) {
            String message = "";
            int status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
            if (status == DownloadManager.STATUS_SUCCESSFUL) {
                message = "Download successful";
            } else if (status == DownloadManager.STATUS_FAILED) {
                message = "Download failed";
            }
            tvMessage.setText(message);
        }


    }
};

我正在使用dexter获取权限

 Dexter.withActivity(this)
                .withPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
                .withListener(new PermissionListener() {
                    @Override
                    public void onPermissionGranted(PermissionGrantedResponse response) {

我的清单中也有两个

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

但我在尝试下载文件时仍然收到此错误(仅在 Oreo 上)。它适用于安卓 7

No permission to write to /storage/emulated/0/download: Neither user 10205 nor current process has android.permission.WRITE_EXTERNAL_STORAGE.

【问题讨论】:

    标签: android android-permissions


    【解决方案1】:

    您只需要互联网许可。

    <uses-permission android:name="android.permission.INTERNET" />
    

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    

    如果你想存储和阅读这个下载的文件。

    【讨论】:

      【解决方案2】:

      需要互联网许可:

      <uses-permission android:name="android.permission.INTERNET" />
      

      如果你想在没有任何存储权限的情况下保存文件,你可以使用getExternalFilesDir。 如文档中所述:

      getExternalFilesDir

      添加于API level 8

      File getExternalFilesDir (String type)

      返回主目录的绝对路径 应用程序可以放置的共享/外部存储设备 它拥有的持久性文件。这些文件是内部的 应用程序,并且通常不作为媒体对用户可见。

      这就像getFilesDir() 一样,这些文件将在 应用程序已卸载,但有一些重要的 区别:共享存储可能并不总是可用,因为 可移动媒体可以由用户弹出。可以检查媒体状态 使用getExternalStorageState(File)。没有强制执行安全措施 与这些文件。例如,任何持有 WRITE_EXTERNAL_STORAGE 可以写入这些文件。

      如果模拟共享存储设备(由isExternalStorageEmulated(File) 确定), 它的内容由私有用户数据分区支持,这意味着 在这里存储数据而不是私有数据几乎没有什么好处 getFilesDir()等返回的目录

      从 KITKAT 开始,无需权限即可读取或写入返回的路径;调用应用程序始终可以访问它。这仅适用于为调用应用程序包名称生成的路径。

      访问路径 属于其他包,WRITE_EXTERNAL_STORAGE 和/或 READ_EXTERNAL_STORAGE 是必需的。在具有多个用户的设备上(如 由UserManager描述),每个用户都有自己的隔离共享 贮存。应用程序只能访问共享存储 他们正在运行的用户。

      返回的路径可能会随着时间而改变,如果 插入了不同的共享存储介质,所以只有相对路径 应该持久化。

      https://developer.android.com/reference/android/content/Context#getExternalFilesDir(java.lang.String)


      此链接可能有用:

      Save files on device storage

      【讨论】:

        【解决方案3】:

        您收到此错误是因为您的应用在 Android 6.0(API 级别 23)上运行。从 API 级别 >= 23 开始,您需要在运行时检查权限。您的代码适用于 23 级以下。所以首先检查您的用户是否已授予使用存储的权限:

        if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
            Log.e("Permission error","You have permission");
            return true;
        }
        

        如果没有则提示请求:

        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE);
        

        完整代码如下所示:

        public  boolean haveStoragePermission() {
            if (Build.VERSION.SDK_INT >= 23) {
                if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
                        == PackageManager.PERMISSION_GRANTED) {
                    Log.e("Permission error","You have permission");
                    return true;
                } else {
        
                    Log.e("Permission error","You have asked for permission");
                    ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
                    return false;
                }
            }
            else { //you dont need to worry about these stuff below api level 23
                Log.e("Permission error","You already have the permission");
                return true;
            }
        }
        

        并通过回调接收结果:

            @Override
            public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
                super.onRequestPermissionsResult(requestCode, permissions, grantResults);
                if(grantResults[0]== PackageManager.PERMISSION_GRANTED){
                    //you have the permission now.
                    DownloadManager.Request request = new DownloadManager.Request(Uri.parse(myurl));
                    request.setTitle("Vertretungsplan");
                    request.setDescription("wird heruntergeladen");
                    request.allowScanningByMediaScanner();
                    request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
                    String filename = URLUtil.guessFileName(myurl, null, MimeTypeMap.getFileExtensionFromUrl(myurl));
                    request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, filename);
                    DownloadManager manager = (DownloadManager) c.getSystemService(Context.DOWNLOAD_SERVICE);
                    manager.enqueue(request);
                }
            }
        


        【讨论】:

          猜你喜欢
          • 2022-12-14
          • 2020-11-03
          • 2011-02-10
          • 2012-09-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-09-01
          相关资源
          最近更新 更多