2016-12-23 1 views
0

Я хочу загрузить файл .apk и установить его. Когда я не использую FileProvider, все идет хорошо, но когда я создаю uri из файла с помощью FileProvider, у меня есть 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_VIEW и ACTION_INSTALL_PACKAGE поддерживают только content схему, как в Android 7.0. До этого у вас нет выбора, кроме как использовать 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: Он работает для меня на Nexus 9, работающем на 7.1.1. На каком устройстве вы тестируете? – CommonsWare

+0

Xiaomi Redmi Note 3 Pro, Android 7.1.1 –

0

Проблема была в DownloadManager. Он не может анализировать uri как «content: //», только как «file: //», так как с sdk24 мы не можем его использовать. Используя общие 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; 
    } 
Смежные вопросы