问题描述
我的目标是将应用更新托管到远程服务器 &通过 API 检查更新.应用程序将检查定义的 url 以检查更新,如果响应版本代码大于当前代码,它将从服务器下载更新的 apk &通过代码安装.我托管了一个用于检查版本的 PHP 文件 &apk 文件到服务器.应用程序正在下载 apk 没有任何问题.但是下载后,在安装文件时,显示解析错误:解析包时出现问题."
My goal is to host an app update to remote server & check for update via API. App will check the defined url for checking the update, if response version code is greater than current code, it'll download the updated apk from server & install it by code. I hosted a PHP file for checking the version & the apk file to a server. App is downloading the apk without any problem. But after download, while installing the file, it is showing "Parse Error : There is a problem parsing the package."
我搜索了 stackoverflow &google 来解决这个问题,但找不到任何合适的解决方案来解决这个问题 &安装更新.已提供所有必需的许可.文件提供程序工作正常.下载的文件也手动安装&已经运行没有任何问题.但以编程方式安装时会出现唯一的问题.
I searched stackoverflow & google to get rid of the problem, but can't find any proper solution to fix this issue & install the update. All required permission have been provided. File Provider is working properly. Downloaded file is also installed manually & has been run without any issue. But the only issue arises when installing it programmatically.
这是低版本的gradle.bulid文件配置:
This is gradle.bulid file config for lower version:
minSdkVersion 21
targetSdkVersion 28
versionCode 1
versionName "1.0"
和更新版本的 gradle.bulid 文件配置:
and gradle.bulid file config for updated version:
minSdkVersion 21
targetSdkVersion 28
versionCode 2
versionName "1.1"
以下内容在清单中:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
清单中声明的文件提供程序:
Declared file provider inside manifest:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true"
tools:replace="android:authorities">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
</provider>
提供程序文件包含:
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path path="Android/data/${applicationId}/" name="files_root" />
<root-path name="root" path="/" />
</paths>`
现在是编码部分
下载我写的文件
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(updateURL));
request.setMimeType("application/vnd.android.package-archive");
request.setTitle("Downloading " + updateURL.substring(updateURL.lastIndexOf("/") + 1));
request.allowScanningByMediaScanner();
//request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
String dir = Environment.DIRECTORY_DOWNLOADS;
String file = updateURL.substring(updateURL.lastIndexOf("/") + 1);
request.setDestinationInExternalPublicDir(dir, file);
downloadPathFile += "/" + file;
Log.e("Path", downloadPathFile);
DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
manager.enqueue(request);
registerReceiver(onComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
logcat 显示路径
The logcat shows the path
E/Path: /storage/emulated/0/Download/app-debug.apk
(文件在下载文件夹中,手动安装没有问题)
(File is there in the Download folder & there is no issue on installing manually)
下载管理器广播的下载完成意图后,应用程序通过此接收器捕获该意图 &尝试安装更新的 apk.
After download completing intent broadcasted by download manager, app catches that via this receiver & tries to install the updated apk.
BroadcastReceiver onComplete = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent1) {
Toast.makeText(context, "Download Completed...", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(Intent.ACTION_VIEW);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
Uri contentUri = FileProvider.getUriForFile(MainActivity.this, context.getApplicationContext().getPackageName() + ".provider", new File(downloadPathFile));
intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
} else {
intent.setDataAndType(Uri.fromFile(new File(downloadPathFile)), "application/vnd.android.package-archive");
}
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
unregisterReceiver(onComplete);
}
};
根据教程&在 Google & 中找到的问答stackoverflow,此代码是正确的,但在以编程方式安装时仍然抛出解析错误.
According to the tutorials & Q&A found in Google & stackoverflow, this code is correct but still it is throwing the parse error while installing programmatically.
期待得到社区的帮助来解决这个问题.我随时准备分享项目的任何相关文件或片段.
Looking forward to get help from the community to overcome the issue. I'm always ready to share any related file or snippets of the project.
提前致谢.
编辑 1:测试设备是Samsung Galaxy J8 Infinity with Android 8.0.0 (API 26)
推荐答案
我遇到了同样的问题.有一个选项可以检查 canRequestPackageInstalls () 在 Android 8.0.0 (API 26) 中.
I had same problem. There is an option to check canRequestPackageInstalls () in Android 8.0.0 (API 26).
这可能是您问题的解决方案.在此处
This might be the solution of your problem. Find more here
这篇关于以编程方式更新应用程序时解析错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!