【问题标题】:Android 6.0 - Download file to external storage without asking for permissionAndroid 6.0 - 无需请求许可即可将文件下载到外部存储
【发布时间】:2018-06-30 15:26:00
【问题描述】:

我的设备上有超级用户访问权限。我非常成功地使用此功能以编程方式下载和更新我的应用程序,但从 android 6.0 开始,此功能停止工作(因为新类型的权限请求)。

我的问题是:由于我在我的根设备上拥有超级用户访问权限,如何编辑我的功能以便我可以在不征求用户许可的情况下下载 sdcard 上的外部文件?

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

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版本是什么?
  • buildToolsVersion '23.0.3' minSdkVersion 19 targetSdkVersion 23 这个函数在 6.0 之前运行良好,但我需要对其进行编辑以便它也可以在 6.0 上运行
  • 为什么不将它下载到 File 的应用程序目录?您不需要公开 apk。
  • @cgarrido 你能提供代码 sn-p 吗?下载完成后,我需要从设备运行下载的文件
  • 正如建议:不要使用“/mnt/sdcard/Download/”,所有设备都没有相同的挂载点路径。首选Environment.getExternalStorageDirectory()

标签: android android-6.0-marshmallow android-permissions


【解决方案1】:

下载到getExternalFilesDir()。其他应用有权访问时无需权限。

【讨论】:

  • 根据文档:从 KITKAT 开始,读取或写入返回的路径不需要权限;调用应用程序始终可以访问它。这仅适用于为调用应用程序的包名称生成的路径。要访问属于其他包的路径,需要 WRITE_EXTERNAL_STORAGE 和/或 READ_EXTERNAL_STORAGE。
【解决方案2】:

不,你不能从 Android 6.0 开始这样做,你需要在运行时请求危险的权限。

因为如果设备运行的是 Android 6.0(API 级别 23)或更高版本, 并且应用的 targetSdkVersion 为 23 或更高,操作系统将强制执行 应用程序在运行时向用户请求权限。

你是否有 root 访问权限。

来源:
https://developer.android.com/guide/topics/security/permissions.html https://developer.android.com/training/permissions/index.html

【讨论】:

    【解决方案3】:

    https://stackoverflow.com/a/51112708/4650581


    如果你想在没有任何权限的情况下保存文件,你可以使用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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-12
      • 1970-01-01
      • 1970-01-01
      • 2017-08-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多