我创建了一个应用程序,尝试从远程服务器将APK更新下载到内部存储,然后在设备上安装更新。我在一个API24设备上测试了它,一切都如愿以偿。
现在,我正在API 19设备上测试它(测试代码中与更新应用程序的旧方式有关的部分),并且我一直得到“解析清单时的分析错误”。令我困惑的是,我可以手动在设备上安装APK,并且没有解析错误,所以我认为问题不存在于实际的清单文件中。我检查了内部存储中下载的APK文件的长度,它似乎完全被下载了。下载APK的代码对于所有API版本都是相同的。
代码:
pathToApk = getFilesDir() + "/update.apk";
try (InputStream is = response.body().byteStream();
BufferedInputStream input = new BufferedInputStream(is);
OutputStream os = new FileOutputStream(pathToApk)) {
byte[] data = new byte[1024];
int count;
while ((count = input.read(data)) != -1) {
os.write(data, 0, count);
}
}
File toInstall = new File(pathToApk);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
Uri apkUri = Uri.fromFile(toInstall);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}错误:
W/PackageParser: Unable to read AndroidManifest.xml of /data/data/my.package.name/files/update.apk
java.io.FileNotFoundException: AndroidManifest.xml
at android.content.res.AssetManager.openXmlAssetNative(Native Method)
at android.content.res.AssetManager.openXmlBlockAsset(AssetManager.java:501)
at android.content.res.AssetManager.openXmlResourceParser(AssetManager.java:469)
at android.content.pm.PackageParser.parsePackage(PackageParser.java:544)
at com.android.packageinstaller.PackageUtil.getPackageInfo(PackageUtil.java:73)
at com.android.packageinstaller.PackageInstallerActivity.onCreate(PackageInstallerActivity.java:467)
at android.app.Activity.performCreate(Activity.java:5350)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1088)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2320)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2417)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1342)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:5322)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:829)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:645)
at dalvik.system.NativeStart.main(Native Method)
11-10 10:16:24.213 4140-4140/? W/PackageInstaller: Parse error when parsing manifest. Discontinuing installationAndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="my.package.name">
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".main.activities.UpdateActivity"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
</application>
</manifest>编辑
请看我的答案以求解决。
发布于 2017-11-10 10:36:54
问题是系统无法从我在API<=23上应用程序的私有内部存储读取APK。解决办法很简单。
更改了这一行:
OutputStream os = new FileOutputStream(pathToApk)对此:
boolean old = Build.VERSION.SDK_INT < Build.VERSION_CODES.N;
OutputStream os = old ?
openFileOutput("update.apk", Context.MODE_WORLD_READABLE)
: new FileOutputStream(pathToApk)发布于 2017-11-10 09:55:29
在这里添加请求。
1.checkSelfPermission for Manifest.permission.READ_EXTERNAL_STORAGE
readFile();requestPermissions。2.在代码中处理onRequestPermissionsResult
/**
* permission code
*/
private static final int MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 1;
/**
* requestPermissions and do something
*
*/
public void requestRead() {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
} else {
readFile();
}
}
/**
* do you want to do
*/
public void readFile() {
// do something
}
/**
* onRequestPermissionsResult
*
* @param requestCode
* @param permissions
* @param grantResults
*/
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
readFile();
} else {
// Permission Denied
Toast.makeText(ToolbarActivity.this, "Permission Denied", Toast.LENGTH_SHORT).show();
}
return;
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}向清单添加权限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />发布于 2018-07-03 06:03:04
描述很好的这里
我就是这么管理的
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.N){
outputFile = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "ABC.apk")
} else {
outputFile = File(filesDir, "ABC.apk")
}https://stackoverflow.com/questions/47219686
复制相似问题