web-dev-qa-db-ja.com

DownloadManagerCOLUMN_LOCAL_FILENAMEは非推奨

Android N、例外が発生します。これはドキュメントによる既知の問題であり、ContentResolver.openFileDescriptor()を使用するように求められます。

https://developer.Android.com/reference/Android/app/DownloadManager.html#COLUMN_LOCAL_FILENAME

使い方がわかりません。ファイル名を取得するために使用できるContentResolverオブジェクトはどこにありますか?私はそれを使ったことがありません。だから、私はどんな助けにも感謝します。

08-04 11:20:59.765 7010 7290 W System.err:Java.lang.SecurityException:COLUMN_LOCAL_FILENAMEは非推奨です。代わりにContentResolver.openFileDescriptor()を使用してください

08-04 11:20:59.765 7010 7290 W System.err:Android.app.DownloadManager $ CursorTranslator.getString(DownloadManager.Java:1499)

これが私のコードです。

    DownloadManager.Query query = new DownloadManager.Query();
    query.setFilterById(id);
    Cursor cursor = downloadManager.query(query);

    final String downloadFilePath = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_FILENAME));
    cursor.close();

DownlaodManager.getFileUriを試しましたが、探しているものではありません。助けに感謝します。

ありがとう

11
techtinkerer

以下は私のために今働いています:

    String downloadFilePath = null;
    String downloadFileLocalUri = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
    if (downloadFileLocalUri != null) {
        File mFile = new File(Uri.parse(downloadFileLocalUri).getPath());
        downloadFilePath = mFile.getAbsolutePath();
    }
8
techtinkerer

私はこの問題を使用して解決します _DownloadManager.COLUMN_LOCAL_URI_ 代わりに _DownloadManager.COLUMN_LOCAL_FILENAME_

DownloadManager.COLUMN_LOCAL_URIは、「file://」を含むファイルパスを返すため、downloadFilePath = downloadFilePath.replace("file://","");を使用してdownloadFilePathから除外する必要があります。

この問題の1行の解決策は次のとおりです。

_String downloadFilePath = (c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI))).replace("file://","");
_

DownloadManagerの完全なコードを以下で確認してください。

DownloadFinishedReceiver.Java

_public class DownloadFinishedReceiver extends BroadcastReceiver {

    @Override
        public void onReceive(final Context context, Intent intent) {
            String action = intent.getAction();
            if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action) && intent.getExtras()!=null) {
                Bundle extras = intent.getExtras();
                DownloadManager.Query q = new DownloadManager.Query();
                long downloadId = extras.getLong(DownloadManager.EXTRA_DOWNLOAD_ID);
                q.setFilterById(downloadId);
                Cursor c = ((DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE)).query(q);
                if (c.moveToFirst()) {
                    int status = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));
                    if (status == DownloadManager.STATUS_SUCCESSFUL) {

                        String downloadFilePath = (c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI))).replace("file://","");
                        String downloadTitle = c.getString(c.getColumnIndex(DownloadManager.COLUMN_TITLE));
                        c.close();

                        Log.e("DownloadPath", downloadFilePath); // Print DownloadPath in Logcat
                        Log.e("DownloadTitle", downloadTitle); // Print DownloadTitle in Logcat
                    } else if (status == DownloadManager.STATUS_FAILED) {
                        removeTempOnFailure(context, downloadId);
                    }
                }
            }
        }

        // Remove temp/cache data
        private void removeTempOnFailure(Context con, long downloadId) {
                File cacheFileDir = new File(con.getCacheDir().getAbsolutePath());
                for (File f : cacheFileDir.listFiles()) {
                    if (f.getName().contains(String.valueOf(downloadId))) {
                        f.delete();
                        break;
                    }
                }
            }
}
_

BroadcastReceiverをAndroidMenifest.xmlファイルに登録します。

_        <receiver
            Android:name="com.example.receiver.DownloadFinishedReceiver"
            Android:exported="true"
            Android:process=".downloadFinished">
            <intent-filter>
                <action Android:name="Android.intent.action.DOWNLOAD_COMPLETE" />
            </intent-filter>
        </receiver>
_

以下のメソッドをActivityに入れて、適切な引数を渡します。

_     /**
     * 
     * @param downloadUrl -> Your file download url
     * @param downloadTitle -> Your file title to display in download manager
     * @param fileName -> filename with extension like music.mp3 it will store in download folder
     * @param hide -> true to hide downloadmanager in status bar, false to display it
     * @return -> it will return downloadId
     */
    private long downloadFromUrl(String downloadUrl, String downloadTitle, String fileName, boolean hide) {
        Uri uri = Uri.parse(downloadUrl);
        DownloadManager.Request request = new DownloadManager.Request(uri);
        request.setTitle(downloadTitle);
        if (hide) {
            request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN);
            request.setVisibleInDownloadsUi(false);
        } else
            request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);

        request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName);

        DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
        return manager != null ? manager.enqueue(request) : 0;
    }
_

上記のメソッドでhide = trueを渡す場合は、_AndroidManifext.xml_に次の権限を追加する必要があります

_<uses-permission Android:name="Android.permission.DOWNLOAD_WITHOUT_NOTIFICATION"/>
_
6
Viraj Patel

getUriForDownloadedFileを使用して、ダウンロードしたUriを取得します。

DownloadManager downloadManager = DownloadManager.class.cast(getSystemService(DOWNLOAD_SERVICE));
Uri uri = downloadManager.getUriForDownloadedFile(id);
2
Tom

commonsWareが指摘したように、ファイルURIを常に取得しているわけではなく、コンテンツURIを取得していることが多いため、techtinkererの回答も機能しませんでした。ただし、コンテンツURIからファイルを取得する方法はいくつかあります。

1)getContentResolver()。openInputStream(myContentUri)を呼び出して入力ストリームを取得し、外部ストレージまたは内部ストレージに作成したファイルに書き込むことができます。

2)getContentResolver()。openFileDescriptor(myContentUri、 "r")を呼び出して、読み取り専用のParcelFileDescriptorを開くことができます。 ParcelFileDescriptorから絶対ファイルパスを取得することはできませんが、ファイルまたはURIを受け入れる多くのメソッドはParcelFileDescriptorも受け入れます。

たとえば、DownloadManagerを使用してPDFをダウンロードし、コンストラクターがParcelFileDescriptorを受け入れるPdfRendererで開きます。

PdfRenderer renderer;
ParcelFileDescriptor pdfFileDescriptor = getContentResolver().openFileDescriptor(pdfUri, "r");
if (pdfFileDescriptor != null) renderer = new PdfRenderer(pdfFileDescriptor);
pdfFileDescriptor.close();

別の例として、BitmapFactoryにはParcelFileDescriptorをデコードするメソッドもあります。

https://developer.Android.com/guide/topics/providers/document-provider.html から)

private Bitmap getBitmapFromUri(Uri uri) throws IOException {
    ParcelFileDescriptor parcelFileDescriptor =
        getContentResolver().openFileDescriptor(uri, "r");
    FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
    Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor);
    parcelFileDescriptor.close();
    return image;
}

したがって、実行する内容によっては、ParcelFileDescriptorだけで十分な場合があります。

1
paralith

GradleでtargetSdkを24未満に減らすことができます。実際、このアプローチは推奨されるアプローチではありませんが、ターゲットSDK 23など(ただし24未満)を減らすことでこのエラーを克服できます。

0
Dhaval Shah

これが便利だと思う人のために

私は使用しなければなりませんでした_DownloadManager.COLUMN_URI_
_DownloadManager.COLUMN_LOCAL_URI_の代わりに


これがそれぞれの列の結果です

  1. c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI))->content:// downloads/my_downloads/46

  2. c.getString(c.getColumnIndex(DownloadManager.COLUMN_URI))->http://test-domain.com/files/encrypted/212125/bsd1e-411cd7-e3229fb-fdddsa12a974.pdf

  3. c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_FILENAME))->http://test-domain.com/files/encrypted/212125/bsd1e-411cd7-e3229fb-fdddsa12a974.pdf

0
Francois
String downloadFileLocalUri = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));

上記の方法により、 CursorIndexOutOfBoundsException 行のリストが空の場合。

カーソルは、最初のエントリの前に配置されるオブジェクトです。したがって、最初に結果があるかどうかを確認する必要があります。これが私の例です:

int index = cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI);

if (cursor.moveToFirst()) {
    String downloadFileLocalUri = cursor.getString(index);
    if (downloadFileLocalUri != null) {
        File mFile = new File(downloadFileLocalUri);

        downloadFileName = mFile.getName();
        downloadFilePath = mFile.getAbsolutePath();
    }
}
cursor.close();
0
Roman Shishkin