web-dev-qa-db-ja.com

Android 7-表示できませんPDF(pdf_nameの形式が無効です)

Android 4、5、6で正常に動作しているアプリがあります。そのアプリはサーバー内のリモートファイルを一覧表示し、サーバーからダウンロードできるようにします(PDFファイル)。ファイルを「AndroidDownloadsフォルダー」にダウンロードし、完了するとデフォルトのPDFリーダーで開きます。

問題は、Android 7の同じコードが失敗し、次のエラーが発生することです:「PDF(pdf_nameは無効な形式です)」を表示できません」。

それは面白い理由です:

  • ダウンロードフォルダにアクセスしてダウンロードしたファイルをクリックすると、正しく開きます。
  • ダウンロードが完了すると、通知が表示され、クリックすると正しく開きます。

そのため、同じアプリがダウンロード後にファイルを自動的に開こうとした場合にのみ、問題が発生します。

ダウンロードの方法:

fileName="file.pdf";
request = new DownloadManager.Request(Uri.parse(Constants.GetURL()));
request.setMimeType(mime)
    .setTitle(fileName).setVisibleInDownloadsUi(true)
    .setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE)
    .setDescription(mContext.getString(R.string.app_name))
    .setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
    .setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName);
enqueue = dm.enqueue(request);

ダウンロードしたら:

    Uri path = Uri.parse(c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI)));
//path contains the route where file was downloaded. Something like: file:///storage/emulated/0/Download/file.pdf
    Intent pdfOpenintent = IntentHelper.getViewPDFIntent(path);                                            
    mContext.startActivity(pdfOpenintent);

開く方法:

public static Intent getViewPDFIntent(Uri path){
    Intent i = new Intent(Intent.ACTION_VIEW);
    i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    pdfOpenintent.setDataAndType(path, "application/pdf");
    return i;
}

FileProviderについて:FileProviderを使用して実装しましたが、問題は同じです。これはアクセス許可とは関係ありません。ダウンロードフォルダーはパブリックフォルダーであり、SecurityExceptionの発生やアクセス許可に関連するその他の例外はありません。

ドキュメントを送信するためにGmailと同じ共有が行われるため、PDFアプリとは関係ありません。

Extrange behaviour:アプリを段階的にデバッグすると、完全に機能します。通常実行すると失敗します。スリープ状態または5秒の遅延を設定すると、機能しません。したがって、デバッグのみが機能します。

About Android 7:Android 7(- https://developer.Android.com/about/versions/nougat/Android-7.0-changes.html )動作するはずですが、これ以上この方法はお勧めしません。それ以外の場合は動作しません。

新しいアイデアはありますか?

6
Christian

数日間の調査と関係者の数日後、AndroidはAndroid 7でDownloadManagerの動作を変更して、FileProviderの権限を追加するという結論に達しました。 (Android 7変更ログで説明)

私の感じでは、Android Android 7(および7.1)なので、おそらくファイルを一時フォルダーに保存してから、Broadcast FileDownloadedSuccessfullyを送信してから、ファイルを最終的な宛先フォルダーに移動します。

FileDownloaded Broadcastはファイルが移動される前にジャンプするため、ファイルを開くことができません。そのため、デバッグ中または10秒間スリープ状態にすると、動作します。

DownloaderManagerをダウンロードして開くのをやめて自分で実装する以外に、この問題の解決策は見つかりませんでした。 (他のアクションを伴わずに、ファイルのダウンロードにのみ使用されます)。

この問題を見つけた次の人に役立つことを願っています。

4
Christian