以编程方式更新应用程序时出现解析错误
Parsing error while updating app programmatically
我的目标是将应用程序更新托管到远程服务器并通过 API 检查更新。应用程序将检查定义的 url 以检查更新,如果响应版本代码大于当前代码,它将从服务器下载更新的 apk 并通过代码安装。我托管了一个 PHP 文件,用于检查服务器的版本和 apk 文件。应用程序正在毫无问题地下载apk。但是下载后,在安装文件时,它显示 "Parse Error : There is a problem parsing the package."
我搜索了 Whosebug 和 google 来解决这个问题,但找不到任何合适的解决方案来解决这个问题并安装更新。已提供所有必需的许可。文件提供程序工作正常。下载的文件也是手动安装的并且 运行 没有任何问题。但唯一的问题是在以编程方式安装它时出现。
这是gradle.bulid低版本的文件配置:
minSdkVersion 21
targetSdkVersion 28
versionCode 1
versionName "1.0"
和gradle.bulid更新版本的文件配置:
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"/>
在清单中声明的文件提供程序:
<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显示路径
E/Path: /storage/emulated/0/Download/app-debug.apk
(文件在下载文件夹中,手动安装没有问题)
在下载管理器广播的下载完成意图后,应用程序通过此接收器捕获并尝试安装更新的 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 和 Whosebug 中的教程和问答,这段代码是正确的,但在以编程方式安装时仍然抛出解析错误。
期待得到社区的帮助来解决这个问题。我随时准备分享项目的任何相关文件或片段。
提前致谢。
编辑 1:
Testing device is Samsung Galaxy J8 Infinity with Android 8.0.0 (API 26)
我有同样的问题。在 Android 8.0.0 (API 26) 中有一个检查 canRequestPackageInstalls () 的选项。
这可能是您问题的解决方案。查找更多 here
我的目标是将应用程序更新托管到远程服务器并通过 API 检查更新。应用程序将检查定义的 url 以检查更新,如果响应版本代码大于当前代码,它将从服务器下载更新的 apk 并通过代码安装。我托管了一个 PHP 文件,用于检查服务器的版本和 apk 文件。应用程序正在毫无问题地下载apk。但是下载后,在安装文件时,它显示 "Parse Error : There is a problem parsing the package."
我搜索了 Whosebug 和 google 来解决这个问题,但找不到任何合适的解决方案来解决这个问题并安装更新。已提供所有必需的许可。文件提供程序工作正常。下载的文件也是手动安装的并且 运行 没有任何问题。但唯一的问题是在以编程方式安装它时出现。
这是gradle.bulid低版本的文件配置:
minSdkVersion 21
targetSdkVersion 28
versionCode 1
versionName "1.0"
和gradle.bulid更新版本的文件配置:
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"/>
在清单中声明的文件提供程序:
<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显示路径
E/Path: /storage/emulated/0/Download/app-debug.apk
(文件在下载文件夹中,手动安装没有问题)
在下载管理器广播的下载完成意图后,应用程序通过此接收器捕获并尝试安装更新的 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 和 Whosebug 中的教程和问答,这段代码是正确的,但在以编程方式安装时仍然抛出解析错误。
期待得到社区的帮助来解决这个问题。我随时准备分享项目的任何相关文件或片段。
提前致谢。
编辑 1:
Testing device is Samsung Galaxy J8 Infinity with Android 8.0.0 (API 26)
我有同样的问题。在 Android 8.0.0 (API 26) 中有一个检查 canRequestPackageInstalls () 的选项。
这可能是您问题的解决方案。查找更多 here