2011-05-30 93 views
0

我有一个应用托管在SourceForge上(https://sourceforge.net/projects/pokedroid/)。我决定添加一个按钮直接从CVS服务器下载最新版本的应用程序。 .apk下载的很好,但是当我尝试安装它时,软件包安装程序会给出一个“无法解析软件包”的错误。我正在使用的代码:无法从应用安装.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中的一个子类,当然。我究竟做错了什么?

+0

你应该确保你正在创建并尝试ACTION_VIEW相同的文件。硬编码到您的应用程序私有存储的绝对路径让我感到无理的假设。如果你打算让世界可读,为什么不把它放在SD卡上? (好的,好的,是的,这使得它不仅可读,而且更容易找到 - 但这可能会帮助你理清问题) – 2011-05-30 20:23:26

+0

嗨非全部创意, 我想做同样的事情,但在startActivityForResult(intent)之后, ;它给我错误,“有解析包的问题”。你能帮我解决吗? – 2013-02-21 11:22:11

+0

软件包可能存在问题(例如,签名错误,传输时损坏等)。如果不是这样,我真的不知道;自从我在大约一年前发布这个问题以来,我还没有对Android做过更多的工作。你可能想问一个新的问题。对不起,如果我不是很有帮助:/ – 2013-02-28 21:24:59

回答

3

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

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

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

如何解决

您需要更换这些代码两行:

startActivityForResult(intent); 

然后在onActivityResult功能:

deleteFile("PokeDroid.apk"); 
+0

哦,哇,我不能相信我错过了。我会给你一个镜头。 – 2011-05-30 21:34:44

+0

是的,像一个魅力工作!谢谢! – 2011-05-30 21:39:42

1

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

是apk的签名?

+1

这可能是问题。未签名的版本将永远不会覆盖已签名的版本。当然还有第三方的东西。 ;) – Eric 2011-05-30 19:57:07