【问题标题】:Unknown URL content://downloads/my_downloads未知 URL 内容://downloads/my_downloads
【发布时间】:2015-08-20 16:48:23
【问题描述】:

我正在使用下载管理器下载一些多媒体文件并对其进行分类。我也在使用 Crashlytics,这是我在不同设备和 Android 版本上经常遇到的错误:

java.lang.IllegalArgumentException: Unknown URL content://downloads/my_downloads
   at android.content.ContentResolver.insert(ContentResolver.java:862)
   at android.app.DownloadManager.enqueue(DownloadManager.java:1252)
   at com.myapp.LessonFragment$DownloadClickListener.onClick(SourceFile:570)
   at android.view.View.performClick(View.java:4262)
   at android.view.View$PerformClick.run(View.java:17351)
   at android.os.Handler.handleCallback(Handler.java:615)
   at android.os.Handler.dispatchMessage(Handler.java:92)
   at android.os.Looper.loop(Looper.java:137)
   at android.app.ActivityThread.main(ActivityThread.java:4921)
   at java.lang.reflect.Method.invokeNative(Method.java)
   at java.lang.reflect.Method.invoke(Method.java:511)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1038)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:805)
   at dalvik.system.NativeStart.main(NativeStart.java)

你可以在下面看到我的代码:

private class DownloadClickListener implements View.OnClickListener {
    @Override
    public void onClick(View view) {
        // Check if download manager available before request
        if (!DownloadHelper.isDownloadManagerAvailable(getActivity())) {
            // Build custom alert dialog
            AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
            builder.setMessage(R.string.download_manager_disabled);
            builder.setCancelable(false);
            builder.setPositiveButton(R.string.ok, (dialog, which) -> {
                dialog.dismiss();
            });
            // Create and display alert dialog
            AlertDialog dialog = builder.create();
            dialog.show();
            return;
        }

        // Display short toast on download clicked
        Toast.makeText(getActivity(), R.string.lesson_download_start, Toast.LENGTH_SHORT).show();

        // Get attach from view tag
        Attache attache = (Attache) view.getTag();

        // Get lesson using lesson id
        Lesson lesson = new Select().from(Lesson.class)
                .where(Condition.column("id").is(attache.getLessonId()))
                .querySingle();

        // Set file name from url and attache name
        Uri uri = Uri.parse(attache.getFile());
        String fileName = attache.getName() + '.'
                + MimeTypeMap.getFileExtensionFromUrl(attache.getFile());

        // Check if path directory not exist and create it
        String filePath = Environment.getExternalStorageDirectory() + "/myapp/" + lesson.getTitle() + "/";
        File path = new File(filePath);
        if (!path.exists() || !path.isDirectory()) {
            if (!path.mkdirs()) {
                Timber.e("Could not create path directory.");
            }
        }

        // Check if file exist and then delete it
        File file = new File(filePath, fileName);
        if (file.exists() && file.isFile()) {
            if (file.delete()) {
                Timber.v("%s just deleted.", fileName);
            }
        }

        // Create download manager request using url
        DownloadManager.Request request = new DownloadManager.Request(uri);
        request.setTitle(attache.getName());
        request.setDestinationInExternalPublicDir("/myapp/" + lesson.getTitle(), fileName);

        // Using DownloadManager for download attache file
        DownloadManager manager = (DownloadManager) getActivity().getSystemService(Context.DOWNLOAD_SERVICE);
        manager.enqueue(request);
    }
}

【问题讨论】:

  • 我猜attache.getFile() 返回content://downloads/my_downloads?在这种情况下,您可能存储了错误的值。您提供给下载管理器的链接是一个本地 URI,用于识别来自 Android 下载管理器的下载。
  • 谢谢,但实际上你的猜测是错误的。 attache.getFile()返回服务器上文件的url。
  • 您手机的“DownloadManager”进程有问题,最可能的问题是您的手机禁用了“DownloadManager”。参见“设置->应用程序->全部->DownloadManager”,如果禁用则启用它。
  • [请查看此链接。这个问题的非常好的解决方案](stackoverflow.com/questions/21551538/…)

标签: android download android-download-manager


【解决方案1】:

对于那些收到错误 Unknown URI: content://downloads/public_downloads 的人。 我通过@Commonsware 在this answer 中给出的提示设法解决了这个问题。我在 GitHub 上找到了 FileUtils 类。 这里InputStream方法用于从Download目录获取文件。

 // DownloadsProvider
            else if (isDownloadsDocument(uri)) {

                final String id = DocumentsContract.getDocumentId(uri);

                if (id != null && id.startsWith("raw:")) {
                    return id.substring(4);
                }

                String[] contentUriPrefixesToTry = new String[]{
                        "content://downloads/public_downloads",
                        "content://downloads/my_downloads",
                        "content://downloads/all_downloads"
                };

                for (String contentUriPrefix : contentUriPrefixesToTry) {
                    Uri contentUri = ContentUris.withAppendedId(Uri.parse(contentUriPrefix), Long.valueOf(id));
                    try {
                        String path = getDataColumn(context, contentUri, null, null);
                        if (path != null) {
                            return path;
                        }
                    } catch (Exception e) {}
                }

                // path could not be retrieved using ContentResolver, therefore copy file to accessible cache using streams
                String fileName = getFileName(context, uri);
                File cacheDir = getDocumentCacheDir(context);
                File file = generateFileName(fileName, cacheDir);
                String destinationPath = null;
                if (file != null) {
                    destinationPath = file.getAbsolutePath();
                    saveFileFromUri(context, uri, destinationPath);
                }

                return destinationPath;
            }

【讨论】:

  • 只是为了补充这个答案,提到两个 contentUriPrefixes 在我的情况下还不够,还必须添加"content://downloads/all_downloads"
  • 这取决于不同的手机。我们也可以将您的content://downloads/all_downloads 添加到此代码中。如果这些不起作用,那么我们使用 InputStream 函数。
  • 这不起作用,我用你在链接中提到的那个替换了我的 FileUtils。然后,我用您在上面提供的内容替换了 DowloadsProvider 部分。当我从 SD 卡中选择视频/mp4 时,Uri 为空。
  • 获取异常或空无异常?另外,我还没有测试过可移动 sd 卡。
  • @BipinBharti 这里是您的问题的答案github.com/coltoscosmin/FileUtils/blob/master/FileUtils.javaHappy Coding。
【解决方案2】:

我在从下载文件中获取文件时遇到了 java.lang.IllegalArgumentException: Unknown URI: content://downloads/public_downloads/7505 异常。这个解决方案对我有用。

else if (isDownloadsDocument(uri)) {
            String fileName = getFilePath(context, uri);
            if (fileName != null) {
                return Environment.getExternalStorageDirectory().toString() + "/Download/" + fileName;
            }

            String id = DocumentsContract.getDocumentId(uri);
            if (id.startsWith("raw:")) {
                id = id.replaceFirst("raw:", "");
                File file = new File(id);
                if (file.exists())
                    return id;
            }

            final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
            return getDataColumn(context, contentUri, null, null);
        }

这是获取文件路径的方法

   public static String getFilePath(Context context, Uri uri) {

    Cursor cursor = null;
    final String[] projection = {
            MediaStore.MediaColumns.DISPLAY_NAME
    };

    try {
        cursor = context.getContentResolver().query(uri, projection, null, null,
                null);
        if (cursor != null && cursor.moveToFirst()) {
            final int index = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DISPLAY_NAME);
            return cursor.getString(index);
        }
    } finally {
        if (cursor != null)
            cursor.close();
    }
    return null;
}

【讨论】:

  • 我在获取 Android 9 的文件名时遇到了问题 -> content://com.android.providers.downloads.documents -> * ,但其他内容路径提供了正确的文件名。该解决方案帮助我获得正确的文件名。谢谢!
【解决方案3】:

异常是由禁用下载管理器引起的。并且无法直接激活/停用下载管理器,因为它是系统应用程序,我们无权访问它。

唯一的替代方法是将用户重定向到下载管理器应用程序的设置。

try {
     //Open the specific App Info page:
     Intent intent = new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
     intent.setData(Uri.parse("package:" + "com.android.providers.downloads"));
     startActivity(intent);

} catch ( ActivityNotFoundException e ) {
     e.printStackTrace();

     //Open the generic Apps page:
     Intent intent = new Intent(android.provider.Settings.ACTION_MANAGE_APPLICATIONS_SETTINGS);
     startActivity(intent);
}

【讨论】:

    【解决方案4】:

    我遇到了同样的问题,经过大量的搜索,我找到了解决方案

    只需更改您的方法,尤其是 // DownloadsProvider 部分

    getpath()
    

    @SuppressLint("NewApi") public static String getPath(final Context context, final Uri uri) {

        final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
    
        // DocumentProvider
        if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
            // ExternalStorageProvider
            if (isExternalStorageDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];
    
                // This is for checking Main Memory
                if ("primary".equalsIgnoreCase(type)) {
                    if (split.length > 1) {
                        return Environment.getExternalStorageDirectory() + "/" + split[1];
                    } else {
                        return Environment.getExternalStorageDirectory() + "/";
                    }
                    // This is for checking SD Card
                } else {
                    return "storage" + "/" + docId.replace(":", "/");
                }
    
            }
            // DownloadsProvider
            else if (isDownloadsDocument(uri)) {
                String fileName = getFilePath(context, uri);
                if (fileName != null) {
                    return Environment.getExternalStorageDirectory().toString() + "/Download/" + fileName;
                }
    
                String id = DocumentsContract.getDocumentId(uri);
                if (id.startsWith("raw:")) {
                    id = id.replaceFirst("raw:", "");
                    File file = new File(id);
                    if (file.exists())
                        return id;
                }
    
                final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
                return getDataColumn(context, contentUri, null, null);
            }
            // MediaProvider
            else if (isMediaDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];
    
                Uri contentUri = null;
                if ("image".equals(type)) {
                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                } else if ("video".equals(type)) {
                    contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                } else if ("audio".equals(type)) {
                    contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                }
    
                final String selection = "_id=?";
                final String[] selectionArgs = new String[]{
                        split[1]
                };
    
                return getDataColumn(context, contentUri, selection, selectionArgs);
            }
        }
        // MediaStore (and general)
        else if ("content".equalsIgnoreCase(uri.getScheme())) {
    
            // Return the remote address
            if (isGooglePhotosUri(uri))
                return uri.getLastPathSegment();
    
            return getDataColumn(context, uri, null, null);
        }
        // File
        else if ("file".equalsIgnoreCase(uri.getScheme())) {
            return uri.getPath();
        }
    
        return null;
    }
    

    更多解决方案请点击此处链接

    https://gist.github.com/HBiSoft/15899990b8cd0723c3a894c1636550a8

    我希望你也会这样做!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-08-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多