2015-07-28 2 views
0

Я создаю приложение для своего клиента, одним из его требований является загрузка и установка внешнего устройства apk (размером около 62 мб) на устройстве. Устройства будут внедрены, так что это не проблема. Но, загружая apk с использованием AsyncTask, progress bar сбрасывается до 0% после достижения 34% (точный 34% каждый раз, даже на разных устройствах) и бросает java.io.IOException: unexpected end of stream.загрузка файла с помощью asynctask останавливается посередине

Вот код, я использую:

public class InstallAPK extends AsyncTask<Void,Integer,Void> { 

ProgressDialog progressDialog; 
int status = 0; 

private Context context; 
public InstallAPK(Context context, ProgressDialog progress){ 
    this.context = context; 
    this.progressDialog = progress; 
} 

public void onPreExecute() { 
    if(progressDialog!=null) 
     progressDialog.show(); 
} 

@Override 
protected Void doInBackground(Void... arg0) { 
    try { 
     URL url = new URL(context.getString(R.string.kodi_apk_link)); 
     HttpURLConnection c = (HttpURLConnection) url.openConnection(); 
     c.setRequestMethod("GET"); 
     c.setDoOutput(true); 
     c.connect(); 

     // getting file length 
     int lenghtOfFile = c.getContentLength(); 
     Log.e("File length", ""+lenghtOfFile); 

     File outputFile = new File(context.getFilesDir(), context.getString(R.string.kodi_apk_name)); 
     if(outputFile.exists()){ 
      if(outputFile.length() != lenghtOfFile) 
       outputFile.delete(); 
      else { 
       publishProgress(-1); 
       final String libs = "LD_LIBRARY_PATH=/vendor/lib:/system/lib "; 
       final String commands = libs + "pm install -r " + context.getFilesDir().getAbsolutePath() + "/" 
         + context.getString(R.string.kodi_apk_name); 
       installApk(commands); 
       return null;      
      } 
     } 
     FileOutputStream fos = new FileOutputStream(outputFile); 

     InputStream is = c.getInputStream(); 
     //i tried both, with and without buffered reader 
     BufferedInputStream bufferedInputStream = new BufferedInputStream(is); 

     byte[] buffer = new byte[1024]; 
     int len1 = 0, total=0; 

     if (lenghtOfFile != -1) 
     { 
      buffer = new byte[lenghtOfFile]; 
      do { 
       len1 += bufferedInputStream.read(buffer, len1, lenghtOfFile-len1); 
       publishProgress((int)((len1*100)/lenghtOfFile)); 
      } while (len1 < lenghtOfFile); 
     } 

     //I was using this code before, but it's not working too 
     /*while ((len1 = is.read(buffer)) != -1) { 
      total += len1; 
      publishProgress((int)((total*100)/lenghtOfFile)); 
      fos.write(buffer, 0, len1); 
     }*/ 
     fos.flush(); 
     fos.close(); 
     bufferedInputStream.close(); 
     is.close(); 

     //Log.e("Directory path", myDir.getAbsolutePath()); 

     publishProgress(-1); 

     final String libs = "LD_LIBRARY_PATH=/vendor/lib:/system/lib "; 

     final String commands = libs + "pm install -r " + context.getFilesDir().getAbsolutePath() + "/" 
       + context.getString(R.string.kodi_apk_name); 

     installApk(commands); 


    } catch (FileNotFoundException fnfe) { 
     status = 1; 
     Log.e("File", "FileNotFoundException! " + fnfe); 
    } 

    catch(Exception e) 
    { 
     Log.e("UpdateAPP", "Exception " + e); 
    } 
    return null; 
} 

protected void onProgressUpdate(Integer... progress) { 
    if(progress[0]!=-1) { 
     // setting progress percentage 
     progressDialog.setProgress(progress[0]); 
    } else { 
     progressDialog.setIndeterminate(true); 
     progressDialog.setMessage("Installing Kodi..."); 
    } 
} 

public void onPostExecute(Void unused) { 
    if(progressDialog!=null) { 
     progressDialog.dismiss(); 
    } 
    if(status == 1) 
     Toast.makeText(context,"App Not Available",Toast.LENGTH_LONG).show(); 
    else 
     Toast.makeText(context,"Successfully installed the app",Toast.LENGTH_LONG).show(); 

    Intent LaunchIntent = context.getPackageManager().getLaunchIntentForPackage(context.getString(R.string.kodi_apk_package)); 
    if(LaunchIntent!=null) 
     context.startActivity(LaunchIntent); 
    else 
     Toast.makeText(context, "Error in installig Kodi, Try again.", Toast.LENGTH_LONG).show(); 
} 

private void installApk(String commands) { 
    try { 
     Process p = Runtime.getRuntime().exec("su"); 
     InputStream es = p.getErrorStream(); 
     DataOutputStream os = new DataOutputStream(p.getOutputStream()); 

     os.writeBytes(commands + "\n"); 

     os.writeBytes("exit\n"); 
     os.flush(); 

     int read; 
     byte[] buffer = new byte[4096]; 
     String output = new String(); 
     while ((read = es.read(buffer)) > 0) { 
      output += new String(buffer, 0, read); 
     } 

     Log.v("AutoUpdaterActivity", output.toString()); 

     p.waitFor(); 

    } catch (IOException e) { 
     Log.v("AutoUpdaterActivity", e.toString()); 
    } catch (InterruptedException e) { 
     Log.v("AutoUpdaterActivity", e.toString()); 
    } 
} 

} 

ответ

1

Я пробовал все, чтобы этот код работал. Но это не так. Тогда я нашел альтернативу этому. Я попробовал IntentService, чтобы скачать apk, и на удивление это сработало. Я думаю, что AsyncTask может иметь какой-то предел для скачивания. Для загрузки с использованием IntentService я использовал this code. Ответ очень информативный. Он также имеет некоторые другие альтернативы для загрузки.

+0

Вы, сэр, заслуживаете гораздо больше, чем просто мой запас для спасения моей задницы через 2 дня ударов головой – khandelwaldeval

0

Вы должны добавить тайм-аут соединения для HttpURLConnection.

 HttpURLConnection c = (HttpURLConnection) url.openConnection(); 
     c.setRequestMethod("GET"); 
     c.setDoOutput(true); 
     //set timeout to 5 seconds , set your time here 
     c.setConnectTimeout(5000); 
     c.connect(); 
Его работа для меня. Я надеюсь, что эта работа для вас.

+0

не работает. : | –