【问题标题】:Download APK from url and execute从 url 下载 APK 并执行
【发布时间】:2015-03-05 12:15:20
【问题描述】:

我正在使用DownloadManager 从 url 下载 apk。下载完成,我在我的 BroadcastReceiver 中获得了DownloadManager.ACTION_DOWNLOAD_COMPLETE 的 onReceive。

一些编码:我从一个 url 下载 apk 文件到下载目录。

DownloadManager.Request r = new DownloadManager.Request(mUri);
r.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "myapp.apk");
r.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
DownloadManager dm = (DownloadManager) activity.getSystemService(Context.DOWNLOAD_SERVICE);
SharedPreferences mSharedPref = activity.getSharedPreferences("package", Context.MODE_PRIVATE);
mSharedPref.edit().putLong("downloadID", dm.enqueue(r)).commit();

接收

File apkFile = new File(Environment.DIRECTORY_DOWNLOADS + "myapp.apk");
Intent promptInstall = new Intent(Intent.ACTION_VIEW).setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive");
startActivity(promptInstall);

问题:

  • 文件在那里,我想执行它,但我的包安装程序没有显示
  • 即使我在手机下载文件夹中看到该文件,如果我想安装它,我也没有可供选择的软件包安装程序
  • 我不确定文件和路径是否正确..
  • 我尝试打开文件时收到来自 android 的解析错误

有人有想法吗?

【问题讨论】:

  • 除非设备已设置为允许侧载,否则您希望如何运行此 apk?这种事情正是恶意代码想要的工作方式——从未知来源下载任意可执行文件并运行它们。
  • 我不希望它自动运行。我想要用户可以选择使用包安装程序打开下载文件的提示。所以需要用户交互,它也不是恶意的..
  • 这不是恶意的,因为它会启动安装程序,不会提示用户是否安装 APK。你能输出准确的apkFile的路径吗?
  • 我登录onReceive的路径是:apkFile.getPath() = "Download/myapp.apk" apkFile.getAbsolutePath() = "/Download/myapp.apk"

标签: android apk android-download-manager


【解决方案1】:

确保您拥有在您的AndroidManifest.xml 中声明的android.permission.INSTALL_PACKAGES 权限。

然后获取你的 APK 路径:

File apkFile = new File(Environment.getExternalStorageDirectory() + "/download/" + "app.apk");

现在运行 Intent:

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

【讨论】:

  • android.permission.INSTALL_PACKAGES 用于系统应用程序,我不想使用它,因为我希望它不适用于非 root 设备
  • 很好,但请检查您的路径。我相信这是您代码中的一个错误。
【解决方案2】:

我最近不得不做这样的事情,希望它有所帮助:

编辑:几个注释, apkurl 是下载位置的字符串。 使字节缓冲区足够大以进行响应

    try {

        String PATH = Environment.getExternalStorageDirectory() + "/download/";
        File file = new File(PATH);
        file.mkdirs();
        // Create a file on the external storage under download
        File outputFile = new File(file, "app.apk");
        FileOutputStream fos = new FileOutputStream(outputFile);

        HttpGet m_httpGet = null;
        HttpResponse m_httpResponse = null;

        // Create a http client with the parameters
        HttpClient m_httpClient = setupHttpClient();
        String result = null;

        try {

            // Create a get object
            m_httpGet = new HttpGet(apkurl);

            // Execute the html request
            m_httpResponse = m_httpClient.execute(m_httpGet);
            HttpEntity entity = m_httpResponse.getEntity();

            // See if we get a response
            if (entity != null) {

                InputStream instream = entity.getContent();
                byte[] buffer = new byte[1024];

                // Write out the file
                int len1 = 0;
                while ((len1 = instream.read(buffer)) != -1) {
                    fos.write(buffer, 0, len1);
                }
                fos.close();
                instream.close();// till here, it works fine - .apk is download to my sdcard in download file

            }

        } catch (ConnectTimeoutException cte) {
            // Toast.makeText(MainApplication.m_context, "Connection Timeout", Toast.LENGTH_SHORT).show();
            return false;
        } catch (Exception e) {
            return false;
        } finally {
            m_httpClient.getConnectionManager().closeExpiredConnections();
        }

        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setDataAndType(
                Uri.fromFile(new File(Environment.getExternalStorageDirectory() + "/download/" + "app.apk")),
                "application/vnd.android.package-archive");
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        MainApplication.getApp().getApplicationContext().startActivity(intent);

        // System.exit(0);

    } catch (IOException e) {
        Debug.ERROR(CLASSNAME, METHODNAME, "Failed to update new apk");
        return false;
    } catch (Exception e1) {
        Debug.ERROR(CLASSNAME, METHODNAME, "Failed to update new apk");
        return false;
    }

    return true;

【讨论】:

  • 老实说,我试图简单地使用 DownloadManager 来避免 Http 和 Stream 的事情。如果没有任何帮助,我会试一试
  • 尝试一下以开始安装 apk。剩下的就是从 get 下载一个 apk 仅供参考。确保您有权从存储中读取/写入
  • 是的!现在,我采用了您示例的 Intent 部分。它似乎与路径中断..非常感谢。
  • 如果您还在那里:我再次测试它并遇到了一些问题。我可以在提示中选择包安装程序,但只能从意图提示中选择...如果我转到下载目录并打开/触摸文件,则包安装程序不在选择列表中...
  • 我不太清楚你的意思是什么对不起。你是说如果你使用意图,那么你会得到安装apk的提示。但是,如果您使用 ESFileExplorer 之类的东西,然后单击 apk 它什么都不做?如果是这样的话,你用的是什么手机?
【解决方案3】:

您使用该设备进行的所有下载...

为了澄清我所说的“下载”的意思,这里是一个屏幕截图。这是 Nexus 4 上 Android 5 的标准下载文件夹。当我单击其中的 apk 时,我没有收到安装 .apk 的提示。取而代之的是 HTML-Viewer 或其他无用的东西可供选择...

一个可能的错误可能是DownloadManager..也许他“标记”下载的文件错误,因此它不会被解释为apk文件,我不知道......但我打电话给

promptInstall.setDataAndType(Uri.fromFile(new File(Environment.getExternalStorageDirectory() + "/download/myapp.apk")), "application/vnd.android.package-archive");

【讨论】:

  • 我的应用程序 apk 下载不会出现在我的 nexus 设备的此文件夹中,我一直必须使用“ESFileExplorer”或等效用户才能访问它们
  • 那是因为我说DownloadManager.Request r = new DownloadManager.Request(mUri); r.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "myApp.apk"); 找到了指向网络服务器的东西...stackoverflow.com/questions/27822218/… 让我们看看
  • 仅供参考:对于大多数设备,现在我添加了DownloadManager.Request r = new DownloadManager.Request(mUri); r.setMimeType("application/vnd.android.package-archive");
猜你喜欢
  • 2016-09-07
  • 2022-05-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-28
  • 2015-05-16
  • 1970-01-01
  • 2022-01-16
相关资源
最近更新 更多