2

Android フォンの外部ストレージにファイルがあります (この場合はエミュレートされています)。それへのパスを知っている、および/またはそれをFile表すオブジェクトがある場合、を使用Intentして適切なアプリで開くにはどうすればよいですか?

私が最初に試したのは:

startActivity(new Intent(Intent.ACTION_VIEW, Uri.fromFile(file)));

私はそれをテストし、アプリの別の部分に移ったので、これはある時点で機能していたと確信しています. 今では常に をスローしActivityNotFoundExceptionます。file.exists()ファイルが戻ってきて、それが正しいファイルであることはわかっているため、ファイルは間違いなく存在しtrueますが、自発的にそれを開くアプリはありません。

この方法で開くことができるファイルの種類は .pdf だけです。Adobe Reader が選択されていますが、デバイスにインストールされている PDF リーダーはこれだけではなく、デフォルトに設定されていません。Adobe Reader は、オンラインにある PDF ファイルを開くこともできることに気付きました (これは、Chrome で PDF をダウンロードする代わりに表示されます)。これは、場所がリモートであると考えられているため、Adobe Reader のみが に一致するものとして検出されていることを示唆していIntentます (ただし、Chrome やその他のファイル ダウンロード アプリが代替としてリストされていないため、オンラインではありません)。

また、MIME タイプを明示的に記述しようとしました。

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), "application/msword");
startActivity(intent);

これにより、Intent適切なアプリに一致するようになりますが、それらはすべて実際にファイルを開くことができません。これは、MIME タイプのハードコードされた文字列とMimeTypeMap.getSingleton().getMimeTypeFromExtension(extension)、ファイル拡張子を渡す を使用してテストしました。さまざまな種類のファイルについて、適切なアプリが提案されましたが、それらはすべてファイルを開くことができませんでした。

編集:

MIME タイプを明示的に設定することはうまくいきますが、私は非常にばかげた間違いを犯しました。おそらく回答で説明する必要があります。

私が開こうとしたファイルはインターネットからのもので、DownloadManager. その機能を使用して、ダウンロードが完了すると通知を表示します。これらの通知のいずれかをクリックすると、ファイルが完全に開きます。完了通知がクリックされIntentたときに発生するソースコードを見つけようとしましたが、うまくいきませんでした。DownloadManager

また、ES File Explorer などのアプリは、ファイルがダウンロードされた場所に移動して問題なく開くことができます。私は何を間違っていますか?

外部ストレージ上のファイルを ACTION_VIEW できなくなっただけですか? 私のアプリは一時的にファイルを内部ストレージにダウンロードしますが、これらは問題なく開くことができます:

//This works for files on internal storage:
Uri uri = FileProvider.getUriForFile(context, AUTHORITY, file);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);

また、過去に機能していたものについては、Eclipse、SDK Tools プラグイン、および Android SDK 自体を更新すると、元のソリューションが機能しなくなった可能性がありますか?

4

1 に答える 1

3

私が試したときsetDataAndType、怠惰から私は去ったに違いありません:

Intent intent = new Intent(Intent.ACTION_VIEW, Uri.fromFile(file));

そして、作るために別の行を追加しました:

Intent intent = new Intent(Intent.ACTION_VIEW, Uri.fromFile(file));
intent.setType(theMimeType);

...次と同じであると仮定します。

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), theMimeType);

setDataAndTypeその時、私は実際にこの質問を書き込もうとしなかったことを忘れていたに違いありません。単独で使用すると、コンストラクターに引数として渡しsetTypeた I が削除されたようです。Uriログに記録されたインテントの詳細を表示するために LogCat を使用すると、MIME タイプを推論したままにしておくとタイプがsetTypeなくなるUriことUrisetDataAndTypeわかりました。Intent適切に動作するようにします。

したがって、私が間違っていたのは、を使用する代わりに、タイプとデータを別々に設定することでしたsetDataAndType

于 2014-10-30T12:22:12.770 に答える