安卓6.0 - 在不要求权限的情况下下载文件到外部存储

4

我在我的设备上拥有超级用户权限。我曾经非常成功地使用这个功能来编写和更新我的应用程序,但自从安卓6.0以来,由于新类型的权限请求,这个功能已经停止工作了。

我的问题是:既然我在我的rooted设备上拥有超级用户访问权限,我该如何编辑我的功能,以便在不需要向用户请求权限的情况下下载SD卡上的外部文件呢?

以下是我用来更新应用程序的功能:

public class UpdateAppZ extends AsyncTask<String,Void,Void>{
    private Context context;
    public void setContext(Context contextf){
        context = contextf;
    }

    @Override
    protected Void doInBackground(String... arg0) {
        try {
            URL url = new URL(arg0[0]);
            HttpURLConnection c = (HttpURLConnection) url.openConnection();
            c.setRequestMethod("GET");
            c.setDoOutput(true);
            c.connect();

            String PATH = "/mnt/sdcard/Download/";
            File file = new File(PATH);
            file.mkdirs();
            File outputFile = new File(file, "update.apk");
            if(outputFile.exists()){
                outputFile.delete();
            }
            FileOutputStream fos = new FileOutputStream(outputFile);

            InputStream is = c.getInputStream();

            byte[] buffer = new byte[1024];
            int len1 = 0;
            while ((len1 = is.read(buffer)) != -1) {
                fos.write(buffer, 0, len1);
            }
            fos.close();
            is.close();

            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setDataAndType(Uri.fromFile(new File("/mnt/sdcard/Download/update.apk")), "application/vnd.android.package-archive");
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // without this flag android returned a intent error!
            context.startActivity(intent);


        } catch (Exception e) {
            Log.e("UpdateAPP", "Update error! " + e.getMessage());
        }
        return null;
    }
}

并调用:

UpdateAppZ atualizaApp = new UpdateAppZ();    
                             atualizaApp.setContext(getApplicationContext()); 
                              atualizaApp.execute("http://85.118.98.251/misho/app-debug.apk");

你的构建工具、目标和编译的 SDK 版本是什么? - Radhey
@cgarrido,你能提供一段代码片段吗?下载完成后,我需要从设备上运行已下载的文件。 - Mister M
@MisterM 只需将 "/mnt/sdcard/Download/ 替换为 Context#getFilesDir() - crgarridos
我需要在下载完成后从设备上运行已下载的文件。您没有说明是您的应用程序应该“运行”它还是由意图选择的不同应用程序。 - greenapps
下载SD卡上的外部文件。您很可能根本没有下载到微型SD卡,而是下载到了外部存储器。 - greenapps
显示剩余4条评论
3个回答

2

下载到 getExternalFilesDir()。其他应用程序都可以访问,无需权限。


1
根据文档:从KITKAT开始,无需权限即可读取或写入返回的路径;它始终对调用应用程序可访问。这仅适用于为调用应用程序的包名称生成的路径。要访问属于其他包的路径,需要WRITE_EXTERNAL_STORAGE和/或READ_EXTERNAL_STORAGE。 - Radhey

1

1

https://dev59.com/Oarka4cB1Zd3GeqPa0JB#51112708


你可以使用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)


这个链接可能会有帮助:

将文件保存到设备存储中


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接