无法从应用程序安装 .apk

发布于 2024-11-10 16:19:13 字数 4140 浏览 2 评论 0原文

我有一个托管在 SourceForge 上的应用程序 (https://sourceforge.net/projects/pokedroid/)。我决定添加一个按钮来直接从 CVS 服务器下载应用程序的最新版本。 .apk 下载正常,但当我尝试安装它时,软件包安装程序给出“无法解析软件包”错误。我正在使用的代码:

    private class DownloadAndInstall extends AsyncTask<String, Integer, Boolean>
{
    protected Boolean doInBackground(String... derp)
    {
        String ur=derp[0];
        String fileName=derp[1];
        ByteArrayBuffer baf = new ByteArrayBuffer(50);

        try
        {
            URL url = new URL(ur);
            URLConnection ucon = null;
            ucon = url.openConnection();

            InputStream is = ucon.getInputStream();
            BufferedInputStream bis = new BufferedInputStream(is);

            int current = 0;
            int updateCount=0;
            while ((current = bis.read()) != -1)
            {
                if(updateCount==256)
                {
                    publishProgress(baf.length());
                    updateCount=0;
                }
                baf.append((byte) current);
                updateCount++;
            }

            FileOutputStream fos = PokeDroid.openFileOutput(fileName, Context.MODE_WORLD_READABLE);
            fos.write(baf.toByteArray());
            fos.close();

        } catch (Exception e) {
            Log.e("pokedroid", e.toString());
        }

        MessageDigest digest = null;
        try {
            digest = java.security.MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException e) {
            Log.e("pokedroid", e.toString());
        }
        digest.update(baf.toByteArray());
        byte[] h = digest.digest();

        if(baf.length()==0)
            return null;
        String[] fileList=fileList();
        boolean exists=false;
        for(String i:fileList)
            if(i.equals("updatehash.md5"))
                exists=true;

        String newHash=new String(h);
        Log.e("pokedroid", "new="+newHash);

        if(exists)
        {
            try
            {
                String oldHash=loadObject("updatehash.md5");
                Log.e("pokedroid", "old="+oldHash);
                if(oldHash.equals(newHash))
                    return false;
                else
                    saveObject(newHash, "updatehash.md5");
            }
            catch (Exception e)
            {
                Log.e("pokedroid",e.toString());
            }
        }
        else
        {
            try {
                saveObject(newHash, "updatehash.md5");
            } catch (IOException e) {
                Log.e("pokedroid",e.toString());
            }
        }
        return true;
    }

    protected void onProgressUpdate(Integer...integers)
    {
        p.setMessage("Downloading update...\n"+integers[0]/1000+"kb downloaded so far.");
    }

    protected void onPostExecute(Boolean b)
    {
        if(b==null)
        {
            noConnection.show();
            deleteFile("PokeDroid.apk");
            p.dismiss();
            return;
        }
        if(!b)
            noNewUpdate.show();
        else
        {
            Intent intent=new Intent();
            intent.setAction(android.content.Intent.ACTION_VIEW);
            intent.setDataAndType(Uri.parse("file:///data/data/com.games.pokedroid/files/PokeDroid.apk"), "application/vnd.android.package-archive");
            startActivity(intent);
            deleteFile("PokeDroid.apk");
        }
        p.dismiss();
    }

    public void saveObject(String obj, String filename) throws IOException
    {
        FileOutputStream fos = openFileOutput(filename,Context.MODE_PRIVATE);
        ObjectOutputStream out = new ObjectOutputStream(fos);
        out.writeObject(obj);
        out.close();
        fos.close();
    }

    public String loadObject(String filename) throws StreamCorruptedException, IOException, ClassNotFoundException
    {
        FileInputStream fis=openFileInput(filename);
        ObjectInputStream in=new ObjectInputStream(fis);
        String out=(String) in.readObject();
        in.close();
        fis.close();
        return out;
    }
}

当然,这是我的 Activity 中的子类。我做错了什么?

I have an app hosted on SourceForge (https://sourceforge.net/projects/pokedroid/). I decided to add a button to download the newest version of the app straight from the CVS server. The .apk downloads fine, but when I try to install it, the package installer gives a "cannot parse package" error. The code I'm using:

    private class DownloadAndInstall extends AsyncTask<String, Integer, Boolean>
{
    protected Boolean doInBackground(String... derp)
    {
        String ur=derp[0];
        String fileName=derp[1];
        ByteArrayBuffer baf = new ByteArrayBuffer(50);

        try
        {
            URL url = new URL(ur);
            URLConnection ucon = null;
            ucon = url.openConnection();

            InputStream is = ucon.getInputStream();
            BufferedInputStream bis = new BufferedInputStream(is);

            int current = 0;
            int updateCount=0;
            while ((current = bis.read()) != -1)
            {
                if(updateCount==256)
                {
                    publishProgress(baf.length());
                    updateCount=0;
                }
                baf.append((byte) current);
                updateCount++;
            }

            FileOutputStream fos = PokeDroid.openFileOutput(fileName, Context.MODE_WORLD_READABLE);
            fos.write(baf.toByteArray());
            fos.close();

        } catch (Exception e) {
            Log.e("pokedroid", e.toString());
        }

        MessageDigest digest = null;
        try {
            digest = java.security.MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException e) {
            Log.e("pokedroid", e.toString());
        }
        digest.update(baf.toByteArray());
        byte[] h = digest.digest();

        if(baf.length()==0)
            return null;
        String[] fileList=fileList();
        boolean exists=false;
        for(String i:fileList)
            if(i.equals("updatehash.md5"))
                exists=true;

        String newHash=new String(h);
        Log.e("pokedroid", "new="+newHash);

        if(exists)
        {
            try
            {
                String oldHash=loadObject("updatehash.md5");
                Log.e("pokedroid", "old="+oldHash);
                if(oldHash.equals(newHash))
                    return false;
                else
                    saveObject(newHash, "updatehash.md5");
            }
            catch (Exception e)
            {
                Log.e("pokedroid",e.toString());
            }
        }
        else
        {
            try {
                saveObject(newHash, "updatehash.md5");
            } catch (IOException e) {
                Log.e("pokedroid",e.toString());
            }
        }
        return true;
    }

    protected void onProgressUpdate(Integer...integers)
    {
        p.setMessage("Downloading update...\n"+integers[0]/1000+"kb downloaded so far.");
    }

    protected void onPostExecute(Boolean b)
    {
        if(b==null)
        {
            noConnection.show();
            deleteFile("PokeDroid.apk");
            p.dismiss();
            return;
        }
        if(!b)
            noNewUpdate.show();
        else
        {
            Intent intent=new Intent();
            intent.setAction(android.content.Intent.ACTION_VIEW);
            intent.setDataAndType(Uri.parse("file:///data/data/com.games.pokedroid/files/PokeDroid.apk"), "application/vnd.android.package-archive");
            startActivity(intent);
            deleteFile("PokeDroid.apk");
        }
        p.dismiss();
    }

    public void saveObject(String obj, String filename) throws IOException
    {
        FileOutputStream fos = openFileOutput(filename,Context.MODE_PRIVATE);
        ObjectOutputStream out = new ObjectOutputStream(fos);
        out.writeObject(obj);
        out.close();
        fos.close();
    }

    public String loadObject(String filename) throws StreamCorruptedException, IOException, ClassNotFoundException
    {
        FileInputStream fis=openFileInput(filename);
        ObjectInputStream in=new ObjectInputStream(fis);
        String out=(String) in.readObject();
        in.close();
        fis.close();
        return out;
    }
}

This is a subclass in my Activity, of course. What am I doing wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

雨巷深深 2024-11-17 16:19:13

我可以在您的代码中看到一个问题:

 startActivity(intent);
 deleteFile("PokeDroid.apk");

此代码发送意图,然后删除文件。请注意,startActivity 是异步函数。即它发送请求,但不等待该请求完成。因此,当应用程序安装程序活动实际收到意图时(让我们这样称呼它),您的 .apk 文件已经被您删除了。

如何修复

您需要将这两行代码替换为:

startActivityForResult(intent);

然后在 onActivityResult 函数中:

deleteFile("PokeDroid.apk");

I can see one issue in your code:

 startActivity(intent);
 deleteFile("PokeDroid.apk");

This code sends intent and then deletes the file. Note that startActivity is asynchronous function. I.e. it sends the request, but does not wait for completion of that request. So when the intent is actually received by Application Installer Activity (let's call it that way ) your .apk file has already been deleted by you.

How to fix:

You need to replace those two lines of code with:

startActivityForResult(intent);

And then in onActivityResult function:

deleteFile("PokeDroid.apk");
街角迷惘 2024-11-17 16:19:13

您是否检查过您的手机是否已配置为接受第 3 方应用程序?

apk 是否已签名?

have you checked that your mobile is configured to accept 3rd party apps?

is the apk signed?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文