2016-05-16 15 views
9

W jednym z przypadków użycia aplikacja na początku kontaktuje się z serwerem i pobiera aktualizację tej samej aplikacji.Instalacja APK programowo na Marshmallow

Do pobierania używam klasy DownloadManager systemu Android. Następnie za pomocą poniższego kodu próbuje utworzyć intencję instalatora aplikacji pod numerem onReceive(), tj. Po pomyślnym pobraniu pliku APK.

@Override 
public void onReceive(Context context, Intent intent) { 

    //check if the broadcast message is for our Enqueued download 
    long referenceId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1); 
    if (downloadReference == referenceId) { 
     try { 
      Log.v("", "Downloading of the new app version complete"); 

      String filepath = Environment.getExternalStorageDirectory() + "/" + 
        Environment.DIRECTORY_DOWNLOADS + "/" + mLatestVersionFileName; 

      //start the installation of the latest version 
      Uri uri = downloadManager.getUriForDownloadedFile(downloadReference); 

      //downloadManager.getUriForDownloadedFile(downloadReference) 
      Uri fileLoc = Uri.fromFile(new File(filepath)); 

      Intent promptInstall = new Intent(Intent.ACTION_VIEW); 
      promptInstall.setDataAndType(uri, "application/vnd.android.package-archive"); 
      promptInstall.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
      startActivity(promptInstall); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

    } 
} 

Kod działa poprawnie na urządzeniach Pre-prawoślazu i użytkownik dostaje ekranie, aby zainstalować plik APK.

To nie działa na urządzeniu Marshmallow.

otrzymuję następujący wyjątek na Marshmallow:

android.content.ActivityNotFoundException: Nie stwierdzono aktywny uchwyt Intent {act = android.intent.action.VIEW dat = zawartość: // download/my_downloads/287 typ = application/vnd.android.package-archiwum FLG = 0x10000000}

próbowałem następujące rzeczy:

  1. stosując dokładnie PackageInstaller Mar shmallow (com.google.android.packageinstaller/com.android.packageinstaller.PackageInstallerActivity) nazwa komponentu jako część intencji.
  2. Przekazywanie pliku fileLoc zamiast uri.
promptInstall.setDataAndType(uri, "application/vnd.android.package-archive"); 

Powoduje to 'błąd Parse'.

Idealne zamiary są rozwiązywane przez system operacyjny Android. Myślę, że to nie jest duży problem i być może brakuje mi czegoś podczas tworzenia Intent.

Odpowiedz

3

Spróbuj tego

public void onReceive(Context context, Intent intent) { 
       String action = intent.getAction(); 
       if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) { 
        long downloadId = intent.getLongExtra(
          DownloadManager.EXTRA_DOWNLOAD_ID, 0); 
        Query query = new Query(); 
        query.setFilterById(enqueue); 
        Cursor c = dm.query(query); 
        if (c.moveToFirst()) { 
         int columnIndex = c 
           .getColumnIndex(DownloadManager.COLUMN_STATUS); 
         if (DownloadManager.STATUS_SUCCESSFUL == c 
           .getInt(columnIndex)) { 

          ImageView view = (ImageView) findViewById(R.id.imageView1); 
          String uriString = c 
            .getString(c 
              .getColumnIndex(DownloadManager.COLUMN_LOCAL_URI)); 

          //start the installation of the latest version 
          Uri uri = Uri.parse(uriString); 
          Intent promptInstall = new Intent(Intent.ACTION_VIEW); 
          promptInstall.setDataAndType(uri, "application/vnd.android.package-archive"); 
          promptInstall.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
          mContext.startActivity(promptInstall); 
         } 
        } 
       } 
      } 
3

można spróbować to:

@Override 
public void onReceive(Context context, Intent intent) { 

String action = intent.getAction(); 

     if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) { 

      DownloadManager.Query query = new DownloadManager.Query(); 
      query.setFilterById(yourDownloadID); 
     DownloadManager dm = (DownloadManager)getSystemService(DOWNLOAD_SERVICE); 
      Cursor downloadResult = dm.query(query); 

      if (downloadResult.moveToFirst()) { 
       int statusColumnIndex = downloadResult.getColumnIndex(DownloadManager.COLUMN_STATUS); 
       int status = downloadResult.getInt(statusColumnIndex); 

       if (status == DownloadManager.STATUS_SUCCESSFUL) { 
        //download completed successfully 
        int localFileNameId = downloadResult.getColumnIndex(DownloadManager.COLUMN_LOCAL_FILENAME); 

        String downloadPathFile = downloadResult.getString(localFileNameId); 

     Intent intent = new Intent(Intent.ACTION_VIEW); 
        intent.setDataAndType(Uri.fromFile(new File(downloadPathFile)), "application/vnd.android.package-archive"); 
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
        startActivity(intent); 
}