2016-10-12 12 views
9

FileProviderの変更によりAndroid N用のアプリケーションを修正する必要があります。私は基本的に私たちの最後の私たちのためにこのトピックについてすべてを読んだが、ソリューションは私のためにうまくいきませんでした。FileProviderを使用してAndroid Nにダウンロードしたファイルを開く

ここでは、我々のアプリからのダウンロードを開始しDownloadフォルダに格納し、DownloadManagerとしてsoonsとして意図ACTION_VIEWを呼び出し、彼はダウンロードが終了だ告げる私達の前のコードです:

BroadcastReceiver onComplete = new BroadcastReceiver() { 
    public void onReceive(Context ctxt, Intent intent) { 
     Log.d(TAG, "Download commplete"); 

     // Check for our download 
     long referenceId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1); 
     if (mDownloadReference == referenceId) { 
      DownloadManager.Query query = new DownloadManager.Query(); 
      query.setFilterById(mDownloadReference); 
      Cursor c = mDownloadManager.query(query); 
      if (c.moveToFirst()) { 
       int columnIndex = c.getColumnIndex(DownloadManager.COLUMN_STATUS); 
       if (DownloadManager.STATUS_SUCCESSFUL == c.getInt(columnIndex)) { 
        String localUri = c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI)); 
        String fileExtension = MimeTypeMap.getFileExtensionFromUrl(localUri); 
        String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(fileExtension); 

        if (mimeType != null) { 
         Intent openFileIntent = new Intent(Intent.ACTION_VIEW); 
         openFileIntent.setDataAndTypeAndNormalize(Uri.parse(localUri), mimeType); 
         openFileIntent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); 

         try { 
          mAcme.startActivity(openFileIntent); 
         } 
         catch (ActivityNotFoundException e) { 
          // Ignore if no activity was found. 
         } 
        } 
       } 
      } 
     } 
    } 
}; 

これは、Android M上で動作しますが、しかし、人気のあるFileUriExposedExceptionのためにNで壊れます。私は今、FileProviderを使ってこれを修正しようとしましたが、動作させることができません。私はコンテンツのURIを取得しようとすると、それは壊しています:

file:///storage/emulated/0/Download/test.pdf

Environment.getExternalStorageDirectory()戻り/storage/emulated/0、これがためのコードです:localUriは、ファイルのDownloadManagerから返さ

Failed to find configured root that contains /file:/storage/emulated/0/Download/test.pdf

することです変換:

File file = new File(localUri); 
Log.d(TAG, localUri + " - " + Environment.getExternalStorageDirectory()); 
Uri contentUri = FileProvider.getUriForFile(ctxt, "my.file.provider", file); 

file_paths.xml

<provider 
     android:name="android.support.v4.content.FileProvider" 
     android:authorities="my.file.provider" 
     android:exported="false" 
     android:grantUriPermissions="true"> 
     <meta-data 
      android:name="android.support.FILE_PROVIDER_PATHS" 
      android:resource="@xml/file_paths"/> 
    </provider> 

AndroidManifest.xmlから:

<?xml version="1.0" encoding="utf-8"?> 
<paths xmlns:android="http://schemas.android.com/apk/res/android"> 
    <external-path name="external_path" path="." /> 
</paths> 

そして私は、私はそのxmlファイルで見つけることができるすべての値を試してみました。 :(ここ

+0

あなたがAndroidのサポートライブラリの最新バージョンであることを確認してください。あなたが袖口から外れているなら、これは現在の 'FileProvider'のバグのように感じます。 – CommonsWare

+3

'file:/// storage/emulated/0/Download/test.pdf'です。あなたはそれをそのまま使うことはできません。それから「file://」を削除します。有効なファイルパス '/ storage/emulated/0/Download/test.pdf'を使用する必要があります。 – greenapps

+0

@CommonsWare私はv24.2で動作しています。1 – althaus

答えて

6

ありがとうございました。地元のURIはDownlodManagerから取得されました接頭辞はfile://です。これは新しいFileProviderのために削除しなければなりません:

if (localUri.substring(0, 7).matches("file://")) { 
    localUri = localUri.substring(7); 
} 
File file = new File(localUri); 
+2

次回は、コメントで回答が見つかると、そのコメントを投稿するようにポスターを招待してください。 – greenapps

+0

自由に回答を投稿してください。私はまだその目的のために私のものを受け入れていません。 – althaus

+0

あなたは完全な回答を投稿できますか? – emaillenin

3

のAndroidManifest.xml

の変化
<provider 
    android:name="android.support.v4.content.FileProvider" 
    android:authorities="${applicationId}.provider" 
    android:exported="false" 
    android:grantUriPermissions="true"> 
    <meta-data 
     android:name="android.support.FILE_PROVIDER_PATHS" 
     android:resource="@xml/file_paths"/> 
</provider> 

ファイルパスの変更私はこの問題を解決することができた@greenapsへ

Uri contentUri; 
if(Build.VERSION.SDK_INT == 24){ 
     contentUri = FileProvider.getUriForFile(MainActivity.this, 
       getApplicationContext().getPackageName() + ".provider", 
        file); 
} else{ 
     contentUri = Uri.fromFile(file); 
     } 
+0

私はすでにそれをやっているので、それは本当に任意の値を追加していない。 – althaus

1

私は同様の問題を抱えていましたが、自動的にファイルを開きませんが、「ダウンロード完了」通知を表示し、ユーザーが通知をクリックしたときにAndroidシステムにファイルを開くようにしました。

さらに、ダウンロードが完了したら、私はトーストを表示しています。

DownloadManager mManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); 

String url = "your URL"; 
String filename = "file.pdf"; 

// Set up the request. 
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url)) 
      .setTitle("Test") 
      .setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, filename) 
      .setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED) 
      .setDescription("Downloading...") 
      .setMimeType("application/pdf"); 

request.allowScanningByMediaScanner(); 
mManager.enqueue(request); 

BroadcastReceiver:

public class DownloadReceiver extends BroadcastReceiver { 
    @Override 
    public void onReceive(Context context, Intent intent) { 
     switch (intent.getAction()) { 
      case DownloadManager.ACTION_DOWNLOAD_COMPLETE: 
       Toast.makeText(context, "Download completed", Toast.LENGTH_SHORT).show(); 
       break; 
     } 
    } 

} 
関連する問題