下载文件需要什么权限?

问题描述 投票:2回答:3

我正在尝试使用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上)。它适用于android 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
3个回答
2
投票

您只需要互联网许可。

<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" />

如果要存储和读取此下载的文件。


1
投票

您收到此错误的原因是您的应用在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);
        }
    }


1
投票

互联网许可是必需的:

<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

© www.soinside.com 2019 - 2024. All rights reserved.