首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >解析清单时的解析错误

解析清单时的解析错误
EN

Stack Overflow用户
提问于 2017-11-10 09:38:07
回答 3查看 4.3K关注 0票数 4

我创建了一个应用程序,尝试从远程服务器将APK更新下载到内部存储,然后在设备上安装更新。我在一个API24设备上测试了它,一切都如愿以偿。

现在,我正在API 19设备上测试它(测试代码中与更新应用程序的旧方式有关的部分),并且我一直得到“解析清单时的分析错误”。令我困惑的是,我可以手动在设备上安装APK,并且没有解析错误,所以我认为问题不存在于实际的清单文件中。我检查了内部存储中下载的APK文件的长度,它似乎完全被下载了。下载APK的代码对于所有API版本都是相同的。

代码:

代码语言:javascript
复制
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);
}

错误:

代码语言:javascript
复制
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 installation

AndroidManifest.xml:

代码语言:javascript
复制
<?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>

编辑

请看我的答案以求解决。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-11-10 10:36:54

问题是系统无法从我在API<=23上应用程序的私有内部存储读取APK。解决办法很简单。

更改了这一行:

代码语言:javascript
复制
OutputStream os = new FileOutputStream(pathToApk)

对此:

代码语言:javascript
复制
boolean old = Build.VERSION.SDK_INT < Build.VERSION_CODES.N;
OutputStream os = old ? 
    openFileOutput("update.apk", Context.MODE_WORLD_READABLE)
    : new FileOutputStream(pathToApk)
票数 1
EN

Stack Overflow用户

发布于 2017-11-10 09:55:29

在这里添加请求。

1.checkSelfPermission for Manifest.permission.READ_EXTERNAL_STORAGE

  • 如果允许,您可以执行readFile();
  • 如果没有,您应该使用requestPermissions

2.在代码中处理onRequestPermissionsResult

代码语言:javascript
复制
/**
 * 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);
}

向清单添加权限

代码语言:javascript
复制
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
票数 0
EN

Stack Overflow用户

发布于 2018-07-03 06:03:04

描述很好的这里

我就是这么管理的

代码语言:javascript
复制
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.N){
            outputFile = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "ABC.apk")
        } else {
            outputFile = File(filesDir, "ABC.apk")
        }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47219686

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档