2011-05-30 74 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