简体   繁体   English

尝试以编程方式更新我的apk会导致解析错误

[英]Trying to update my apk programmatically results in parse error

I need to update my application without Google Play. 我需要在没有Google Play的情况下更新我的应用程序。 So I uploaded my apk to my server to be downloaded when needed. 所以我将apk上传到我的服务器上,以便在需要时下载。

It's downloaded fine by the following code, but when the installation intent is started it's throwing: "Parse Error: There is a problem parsing the package" 通过以下代码可以很好地下载它,但是当安装意图开始时,它会抛出:“解析错误:解析软件包时出现问题”

If I try to run the downloaded apk manually, it still gives the same error. 如果我尝试手动运行下载的apk,仍然会出现相同的错误。

BUT, if I transfer the apk by USB and then run it, it installs smoothly. 但是,如果我通过USB传输apk并运行它,则安装会很顺利。 So this problem is not about the apk itself. 因此,此问题与apk本身无关。

Here is my Task class: 这是我的Task类:

class Update implements Runnable {
    @Override
    public void run() {
        FTPClient ftpClient = new FTPClient();
        try {
            ftpClient.connect(InetAddress.getByName("mysite.com"));
            ftpClient.login("mysite.com", "123456"));
            ftpClient.enterLocalPassiveMode();
            String remoteFile1 = "/httpdocs/program/app-release.apk";
            String downPath = getExternalStoragePublicDirectory(DIRECTORY_DOWNLOADS).getAbsolutePath();
            File myapk = new File(downPath + "/app-release.apk");
            OutputStream outputStream1 = new BufferedOutputStream(new FileOutputStream(myapk));
            boolean success = ftpClient.retrieveFile(remoteFile1, outputStream1);
            outputStream1.close();
            myapk.setReadable(true, false);
            if (!success) {
                ftpClient.logout();
                ftpClient.disconnect();
                return;
            } else {
                Intent promptInstall = new Intent(Intent.ACTION_VIEW)
                        .setDataAndType(Uri.fromFile(myapk), "application/vnd.android.package-archive")
                        .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(promptInstall);
            }
        }
        catch (Exception ex) {
            //catch exception
        }
    }
}

Alright, it was my own mistake. 好吧,这是我自己的错误。 Sorry for anyone scanned up and frustrated about my perfectly fine working code. 对不起,任何人扫描我的完美工作代码感到沮丧。

The reason was me, trying to update the app I ran directly from Android Studio over USB. 原因是我,试图更新通过USB直接从Android Studio运行的应用程序。 Despite it's been running on "Release" mode, it throws the parse error on the newly downloaded apk file (I'm still not sure why). 尽管它一直在“发布”模式下运行,但它会在新下载的apk文件上引发解析错误(我仍然不确定为什么)。

So, I just generated a signed apk with proper (lower) versioning; 因此,我刚刚生成了带有正确(较低)版本控制的签名apk; copy it into the phone and then install. 将其复制到手机中,然后安装。 Only then, the app can properly download and run the newer versioned apk file. 只有这样,应用程序才能正确下载并运行更新版本的apk文件。 Updating itself as expected. 按预期更新自己。

Let this be an example case for anyone did the same thing as me. 让这作为一个示例案例,说明有人做过与我相同的事情。 Use generated apk when testing for a manual update function. 测试手动更新功能时,请使用生成的apk。

Lastly, I want to share my code. 最后,我想分享我的代码。 I changed it from FTP to direct download via HttpURLConnection. 我将其从FTP更改为通过HttpURLConnection直接下载。 Both versions work fine (the code in the question and this). 两种版本都可以正常工作(问题和此代码)。 So feel free to choose the one suits your job. 因此,随时选择适合您工作的一种。

class Update implements Runnable {
    @Override
    public void run() {
        try {
            URL url = new URL("mysite.com/app-release.apk");
            HttpURLConnection c = (HttpURLConnection) url.openConnection();
            c.setRequestMethod("GET");
            c.setDoOutput(true);
            c.connect();
            String PATH = getExternalStoragePublicDirectory(DIRECTORY_DOWNLOADS).getAbsolutePath();
            File file = new File(PATH);
            File outputFile = new File(file, "app-release.apk");
            FileOutputStream fos = new FileOutputStream(outputFile);
            InputStream is = c.getInputStream();
            byte[] buffer = new byte[1024];
            int len1 = 0;
            while ((len1 = is.read(buffer)) != -1) {
                fos.write(buffer, 0, len1);
            }
            fos.close();
            is.close();
            Intent promptInstall = new Intent(Intent.ACTION_VIEW)
                    .setDataAndType(Uri.fromFile(outputFile), "application/vnd.android.package-archive")
                    .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(promptInstall);
        } catch (Exception ex) {
            //catch exception
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM