新しいStorage Access Framework API をアプリに実装しています。1 つの細かい点を除いて、すべてがうまく機能しているようです。ドキュメント ピッカーを使用して自分のアプリケーションから (たとえば、アプリ内の別のアカウントから) ファイルを開くと、メイン スレッドで実装が呼び出されますopenDocument
。DocumentsProvider
要求されたファイルがローカルにキャッシュされている場合はこれで問題ありませんが、そうでない場合はネットワーク要求が行われ、NetworkInMainThreadException
. 興味深いことに、ドキュメントには「この方法でネットワーク操作を行ってドキュメントをダウンロードしても問題ありません」と記載されています。これは既知のバグですか?もしそうなら、誰かがこれを回避する方法を知っていますか?
ピッカーを起動するコードは次のとおりです。
Intent target = new Intent(Intent.ACTION_OPEN_DOCUMENT);
target.setType("*/*");
target.addCategory(Intent.CATEGORY_OPENABLE);
final Intent intent = Intent.createChooser(target, getString(R.string.document_choose));
try {
startActivityForResult(intent, SELECT_FILE_REQUEST_CODE);
} catch (ActivityNotFoundException e) {
e.printStackTrace();
}
次に、ユーザーがファイルを選択したとき、これは大まかに次のように処理しopenDocument
ます。
@Override
public ParcelFileDescriptor openDocument(final String documentId, String mode,
CancellationSignal signal) throws FileNotFoundException {
final File file = getFileFromId(documentId);
if(!file.exists()) {
// This is where I have problems
if("main".equalsIgnoreCase(Thread.currentThread().getName())) {
throw new FileNotFoundException("File has not been cached locally.");
} else {
downloadFile(app, file, document, folder);
}
}
}
メイン スレッドで呼び出されるかどうかのチェックに注意してください。openDocument
これは、バックグラウンド スレッドで呼び出されるように、外部アプリが私のアプリを使用してファイルを選択する場合には発生しません。自分のアプリからファイルを選択しようとしているときにのみ発生します(ただし、別のアカウントから、したがって別のROOTから)。
しかし、Google ドライブで同じことを試してみたところ (つまり、アプリを起動し、独自のピッカーを使用してファイルを選択)、アプリをクラッシュさせることなく、ネットワーク経由でファイルをダウンロードできたようです。