使用FileProvider在Android N上打开下载的文件 [英] Open downloaded file on Android N using FileProvider

查看:193
本文介绍了使用FileProvider在Android N上打开下载的文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于FileProvider的更改,我必须修复适用于Android N的应用程序.我基本上已经阅读了上一本有关该主题的所有文章,但是没有找到适合我的解决方案.

I've got to fix our App for Android N due to the FileProvider changes. I've basically read all about this topic for the last ours, but no solution found did work out for me.

这是我们先前的代码,可从我们的应用开始下载,将其存储在 Download 文件夹中,并在 DownloadManager 之后立即调用 ACTION_VIEW 意图>告诉他已完成下载:

Here's our prior code which starts downloads from our app, stores them in the Download folder and calls an ACTION_VIEW intent as soons as the DownloadManager tells he's finished downloading:

BroadcastReceiver onComplete = new BroadcastReceiver() {
    public void onReceive(Context ctxt, Intent intent) {
        Log.d(TAG, "Download commplete");

        // Check for our download
        long referenceId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
        if (mDownloadReference == referenceId) {
            DownloadManager.Query query = new DownloadManager.Query();
            query.setFilterById(mDownloadReference);
            Cursor c = mDownloadManager.query(query);
            if (c.moveToFirst()) {
                int columnIndex = c.getColumnIndex(DownloadManager.COLUMN_STATUS);
                if (DownloadManager.STATUS_SUCCESSFUL == c.getInt(columnIndex)) {
                    String localUri = c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
                    String fileExtension = MimeTypeMap.getFileExtensionFromUrl(localUri);
                    String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(fileExtension);

                    if (mimeType != null) {
                        Intent openFileIntent = new Intent(Intent.ACTION_VIEW);
                        openFileIntent.setDataAndTypeAndNormalize(Uri.parse(localUri), mimeType);
                        openFileIntent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);

                        try {
                            mAcme.startActivity(openFileIntent);
                        }
                        catch (ActivityNotFoundException e) {
                            // Ignore if no activity was found.
                        }
                    }
                }
            }
        }
    }
};

这在Android M上有效,但由于流行的 FileUriExposedException 而在N上中断.我现在已经尝试通过使用 FileProvider 来解决此问题,但是我无法使其正常工作.当我尝试获取内容URI时,它就破了:

This works on Android M, but breaks on N due to the popular FileUriExposedException. I've now tried to fix this by using the FileProvider, but I cannot get it to work. It's breaking when I try to get the content URI:

未能找到包含/file:/storage/emulated/0/Download/test.pdf

DownloadManager 返回的文件 localUri 是:

file:///storage/emulated/0/Download/test.pdf

Environment.getExternalStorageDirectory()返回/storage/emulated/0 ,这是转换代码:

The Environment.getExternalStorageDirectory() returns /storage/emulated/0 and this is the code for the conversion:

File file = new File(localUri);
Log.d(TAG, localUri + " - " + Environment.getExternalStorageDirectory());
Uri contentUri = FileProvider.getUriForFile(ctxt, "my.file.provider", file);

来自 AndroidManifest.xml

    <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="my.file.provider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths"/>
    </provider>

file_paths.xml :

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="external_path" path="." />
</paths>

并且我尝试了在该xml文件中可以找到的所有值.:(

And I've tried all values I could find in that xml file. :(

推荐答案

感谢@greenaps,我得以解决此问题.从 DownlodManager 检索到的本地URI的前缀为 file://.对于新的 FileProvider

Thanks to @greenaps I was able to solve the issue. The local URI retrieved from the DownlodManager was prefixed with file://. This has to be dropped for the new FileProvider:

if (localUri.substring(0, 7).matches("file://")) {
    localUri =  localUri.substring(7);
}
File file = new File(localUri);

这篇关于使用FileProvider在Android N上打开下载的文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆