2016-12-23 19 views
0

.apkファイルをダウンロードしてインストールします。私がFileProviderを使用していないときは、すべてうまくいっていますが、FileProviderを使用してファイルからuriを作成すると、IllegalArgumentExceptionが発生します。ファイルURIではありません:content://pl.rasztabiga.klasa1a.provider/external_storage_root/klasa1a。 APK on lineAndroid:ファイルではありませんURI:.apkファイルをダウンロード中

final long downloadId = manager.enqueue(request); 

私はstackoverflowからすべてを試しましたが、何も助けてくれませんでした。ここに私のコードは次のとおりです。

File file = new File(Environment.getExternalStorageDirectory(), "klasa1a.apk"); 
final Uri uri = FileProvider.getUriForFile(MainActivity.this, getApplicationContext().getPackageName() + ".provider", file); 

     //Delete update file if exists 
     //File file = new File(destination); 
     if (file.exists()) 
      file.delete(); 

     //get url of app on server 
     String url = "http://rasztabiga.ct8.pl/klasa1a.apk"; 

     //set downloadmanager 
     DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url)); 
     request.setDescription("Downloading new version"); 
     request.setTitle(MainActivity.this.getString(R.string.app_name)); 

     //set destination 
     request.setDestinationUri(uri); 

     // get download service and enqueue file 
     final DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE); 
     final long downloadId = manager.enqueue(request); 

     //set BroadcastReceiver to install app when .apk is downloaded 
     BroadcastReceiver onComplete = new BroadcastReceiver() { 
      public void onReceive(Context ctxt, Intent intent) { 
       Intent install = new Intent(Intent.ACTION_VIEW); 
       install.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
       install.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 
       install.setDataAndType(uri, 
         manager.getMimeTypeForDownloadedFile(downloadId)); 
       startActivity(install); 

       unregisterReceiver(this); 
       finish(); 
      } 
     }; 
     //register receiver for when .apk download is compete 
     registerReceiver(onComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)); 

答えて

2

ACTION_VIEWACTION_INSTALL_PACKAGE唯一のAndroid 7.0のようcontentスキームをサポートしています。それ以前には、fileを使用する以外に選択肢はありません。だから、変更:

final Uri uri = FileProvider.getUriForFile(MainActivity.this, getApplicationContext().getPackageName() + ".provider", file); 

へ:

final Uri uri = (Build.VERSION.SDK_INT>=Build.VERSION_CODES.N) ? 
    FileProvider.getUriForFile(MainActivity.this, BuildConfig.APPLICATION_ID + ".provider", file) : 
    Uri.fromFile(file); 
+1

残念ながら、これは7.1では機能しません。それは同じものを投げます:ファイルではありません。URI:content://pl.rasztabiga.klasa1a.provider/external_storage_root/klasa1a.apk –

+0

@BartłomiejRasztabiga:7.1.1を実行しているNexus 9で動作しています。どのデバイスをテストしていますか? – CommonsWare

+0

Xiaomi Redmi Note 3 Pro、Android 7.1.1 –

0

問題がDownloadManagerにありました。 uriを「content://」として解析することはできません.SDK24以降は「file://」としてのみ使用できます。使用できません。一般的なIOStreamsとHttpURLConnectionを使用するとすべて正常に動作します。彼のプロジェクトを私に見せてくれた@ CommonSWareに感謝します。 これは次のようになります。

 File file = new File(Environment.getExternalStorageDirectory(), "klasa1a.apk"); 
     final Uri uri = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) ? 
       FileProvider.getUriForFile(MainActivity.this, BuildConfig.APPLICATION_ID + ".provider", file) : 
       Uri.fromFile(file); 

     //Delete update file if exists 
     //File file = new File(destination); 
     if (file.exists()) 
      //file.delete() - test this, I think sometimes it doesnt work 
      file.delete(); 

     //get url of app on server 
     String url = "http://rasztabiga.ct8.pl/klasa1a.apk"; 

     InputStream input = null; 
     OutputStream output = null; 
     HttpURLConnection connection = null; 
     try { 
      URL sUrl = new URL(url); 
      connection = (HttpURLConnection) sUrl.openConnection(); 
      connection.connect(); 

      // download the file 
      input = connection.getInputStream(); 
      output = new FileOutputStream(file); 

      byte data[] = new byte[4096]; 
      int count; 
      while ((count = input.read(data)) != -1) { 
       // allow canceling with back button 
       if (isCancelled()) { 
        input.close(); 
        return null; 
       } 

       output.write(data, 0, count); 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } finally { 
      try { 
       if (output != null) 
        output.close(); 
       if (input != null) 
        input.close(); 
      } catch (IOException ignored) { 
      } 

      if (connection != null) 
       connection.disconnect(); 
     } 

     Intent install = new Intent(Intent.ACTION_INSTALL_PACKAGE) 
       .setData(uri) 
       .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 
     startActivity(install); 

     return null; 
    } 
関連する問題