11

Android 4.2以降、ユーザーがブラウザにファイルをダウンロードすると、DownloadManagerが使用されます。ユーザーが「ダウンロード完了」通知をクリックすると、インテントが起動され、常に起動されます。Android 4.2より前では、インテントはダウンロードされたファイルのパスをコンテンツに含めるために使用されていました。

intent.getData()

などの文字列を返しfile:///storage/emulated/0/Download/some_file.extます。ただし、Android 4.2以降、ダウンロードマネージャーはcontent、などのスキームをブロードキャストして意図していcontent://downloads/all_downloads/2334ます。

ダウンロードしたファイルのローカルファイルパスを取得するにはどうすればよいですか?

私は次のことを試しました:

public static String getRealPathFromURI(Uri contentUri, Activity activity) {
    DownloadManager downloadManager = (DownloadManager) activity.getSystemService(Activity.DOWNLOAD_SERVICE);
    String[] contentParts = contentUri.getEncodedPath().split("/");
    Cursor q = downloadManager.query(new DownloadManager.Query().setFilterById(Integer.parseInt(contentParts[contentParts.length - 1])));
    if (q == null) {
        // Download no longer exists
        return null;
    }
    q.moveToFirst();
    return q.getString(q.getColumnIndex(DownloadManager.COLUMN_LOCAL_FILENAME));
}

ただし、カーソルが行を返すことはありません(q.getCount() == 0したがって、最後のreturnステートメントは例外をスローします)。また、URIからのダウンロードファイルIDを解析することによるハッキングは奇妙に思えます。

更新:私も試しました:

input = getActivity().getContentResolver().openInputStream(contentUri);

しかし、これは次のようなエラーを返します

権限の拒否:com.android.providers.downloads.DownloadProvider uri content:// downloads / all_downloads / 2334 from pid = 30950、uid = 10064にはandroid.permission.ACCESS_ALL_DOWNLOADS、またはgrantUriPermission()が必要です。

明らかに、ダウンロードを介してダウンロードにアクセスすることはできません(私のアプリはダウンロードを開始しませんでした-ブラウザーは開始しました)ContentProvider

4

3 に答える 3

5

これがうまくいったことです。まず、botteaapが正しく指摘しているように、ファイルパスを取得することはできません(また、取得したくないはずです)。(私を正しい道に導いてくれた彼の功績です。)代わりに、以下を使用して、ファイルの内容にアクセスするための一時的な許可を自動的に取得します。

InputStream input = getContentResolver().openInputStream(intent.getData());

InputStreamこれは、Javaの他の製品と同じように読むことができます。ファイル名を取得する方法がないようです。ファイルが必要な場合は、最初に入力ストリームを(一時)ファイルに書き込みます。

SecurityException一時的なアクセスが取り消されたときにスローされます。これは、以前に誤って読み込もうとした一部のファイルで発生しました。具体的には、アクティシティでインテントが取得されたときに発生しましたonNewIntent

于 2013-01-17T14:42:38.397 に答える
2

コンテンツリゾルバーを介してそれを取得することは正しいことです。すべてのコンテンツURLがファイルになるわけではありません。たとえば、Galleryアプリは、ソースに応じてネットワーク呼び出しまたはローカルファイルに変換されるURIを提供します。

実際のファイルパスにたどり着いたとしても、ファイルのアクセス許可が原因で、おそらくそれを読み取ることはできませんが、幸運にも外部ストレージにある可能性があります。例外が示唆するように、アプリに追加してみましたか?android.permission.ACCESS_ALL_DOWNLOADS 権限は署名レベルであるため、これは機能しません:(

于 2013-01-17T11:55:31.323 に答える
2

これを理解するのに数時間かかったので、@erickokからの回答に追加したいと思います。@jcesarmobileが述べているように、フルパスではなく、ファイルの名前とサイズのみを取得できることが保証されています。

次のように名前とサイズを取得して、一時ファイルに保存できます。

String filename = null;
Long filesize = null;
Cursor cursor = null;
try {
    cursor = this.getContentResolver().query(intent.getData(), new String[] {
        OpenableColumns.DISPLAY_NAME, OpenableColumns.SIZE}, null, null, null );
    if (cursor != null && cursor.moveToFirst()) {
        filename = cursor.getString(0);
        filesize = cursor.getLong(1);
    }
} finally {
    if (cursor != null)
        cursor.close();
}
于 2014-09-22T11:28:45.533 に答える