【问题标题】:Parse error when trying toprogrammatically install APK from android app尝试从 android 应用程序以编程方式安装 APK 时出现解析错误
【发布时间】:2017-01-16 12:37:34
【问题描述】:

尽量简洁:

-APK 文件没有损坏。

-我可以浏览到手机文件系统中的 APK 并从那里手动安装它而不会出现问题。

-我正在使用以下代码来启动安装过程。文件位置确认正确:

 public void installfromlocal()
    {
        String downloadfilelocation = getsharedresourcestring("updatepackagelocation");
        Log.e("installing from",downloadfilelocation);
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setDataAndType(Uri.fromFile(new File(downloadfilelocation)), "application/vnd.android.package-archive");
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent);
    }

到目前为止,我可以从互联网上的几个小时收集到的是,显然我无法让我的应用程序以编程方式从外部存储安装 APK。我显然也不能将文件复制到内部存储并从那里安装。

那么现在呢?此外,我没有收到来自 Logcat 的消息。我只收到一个弹出窗口,提醒我解析 apk 时出错。

【问题讨论】:

  • downloadfilelocation 指向究竟在哪里?
  • downloadfilelocation你在日志中得到的路径好吗?
  • 是的,位置很好。它指向 file:///storage/sdcard0/Download/org.mycompany.myapp.apk
  • 这里也一样。问题出现在 android 6 和 7。较低版本没问题(相同的 apk)
  • 它在 4.4 和任何 Cyanogenmod 12 上为我完成。

标签: android apk android-install-apk


【解决方案1】:

我找到了一个解决方案(不太清楚为什么会出现这个问题,但我解决了)。

在我看来,使用 DownloadManager 下载时,您无法通过 URI 访问下载的文件,并且访问被拒绝(以及各种文件未找到异常错误),这就是 PackageInstaller 无法读取所有清单的原因(这就是解析错误)。

这就是我所做的,我希望也能解决你的问题,我知道至少可以这么说并不优雅。

由于不推荐使用 DownloadManager.COLUMN_LOCAL_FILENAME,我尝试使用 COLUMN_LOCAL_URI 来访问文件并访问其内容(q 是光标)

String strUri = q.getString(q.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
Uri apkUri = Uri.parse(strUri);

使用这个 uri,我可以访问该文件并将其复制到 getExternalCacheDir() 中的临时文件

ParcelFileDescriptor pfd =   context.getContentResolver().openFileDescriptor(apkUri, "r");

InputStream inFile = new FileInputStream(pfd.getFileDescriptor());
OutputStream outFile = new FileOutputStream(tmpFile);

        //copy
        byte[] buffer = new byte[1024];
        int length;

        while ((length = inFile.read(buffer)) > 0) {
            outFile.write(buffer, 0, length);
        }

        outFile.flush();
        inFile.close();
        outFile.close();

获取创建的文件并获取其 uri(可访问)并使用该 uri 启动活动。

希望对你有帮助

【讨论】:

    【解决方案2】:

    您应该使用文件的规范路径。来自文档-

    规范路径名既是绝对的又是唯一的。规范形式的精确定义取决于系统。如果需要,此方法首先将此路径名转换为绝对形式,就像调用 getAbsolutePath() 方法一样,然后以系统相关的方式将其映射到其唯一形式。这通常涉及删除冗余名称,例如“。”和路径名中的“..”,解析符号链接(在 UNIX 平台上),并将驱动器号转换为标准大小写(在 Microsoft Windows 平台上)。

    【讨论】:

    • 我为什么需要这样做?
    • 问题是一些 OEM 的一些错误的 android 版本,packageInstaller 给出错误 - EACCES(权限被拒绝),而您仍然可以从该路径访问文件。所以你需要获取文件,getCanonicalPath()。包安装程序会安装它。
    • 好的。谢谢你的解释。
    • 另请注意,您的包必须具有对该位置的读/写权限。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-24
    • 2016-09-12
    • 2012-05-12
    • 1970-01-01
    • 2021-11-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多