Android DownloadManager API-下载后打开文件?

Android DownloadManager API-下载后打开文件?,android,download-manager,Android,Download Manager,我面临通过DownloadManager API成功下载后打开下载文件的问题。在我的代码中: Uri uri=Uri.parse("http://www.nasa.gov/images/content/206402main_jsc2007e113280_hires.jpg"); Environment .getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) .mkdirs(); lastDownl

我面临通过DownloadManager API成功下载后打开下载文件的问题。在我的代码中:

Uri uri=Uri.parse("http://www.nasa.gov/images/content/206402main_jsc2007e113280_hires.jpg");

Environment
    .getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
    .mkdirs();

lastDownload = mgr.enqueue(new DownloadManager.Request(uri)
    .setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI |
                            DownloadManager.Request.NETWORK_MOBILE)
    .setAllowedOverRoaming(false)
    .setTitle("app update")
    .setDescription("New version 1.1")
    .setShowRunningNotification(true)
    .setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "a.apk"));

Cursor c=mgr.query(new DownloadManager.Query().setFilterById(lastDownload));

if(c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS)) == 8) {
    try {
        mgr.openDownloadedFile(c.getLong(c.getColumnIndex(DownloadManager.COLUMN_ID)));
    } catch (NumberFormatException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        Log.d("MGR", "Error");
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        Log.d("MGR", "Error");
    }
}
问题在于何时调用is
if(c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS))=8)
。我得到了状态-1和一个例外。有没有更好的方法,如何使用
DownloadManager API
打开下载的文件?在我的示例中,我正在下载一个大图像,在实际情况中,我将下载一个
APK
文件,我需要在udpate之后立即显示一个安装对话框

编辑:我发现status=8是在成功下载之后。您可能有不同的“检查成功下载”方法


谢谢

下载完成后,您需要注册接收器:

registerReceiver(onComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
还有一个接收器处理器

BroadcastReceiver onComplete=new BroadcastReceiver() {
    public void onReceive(Context ctxt, Intent intent) {
        // Do Something
    }
};
买吧,我建议你检查一下,不要让我把所有东西都偷走

编辑:

作为建议,我现在还不建议使用API9:
http://developer.android.com/resources/dashboard/platform-versions.html

有很多方法可以解决这个问题,比如像我一样创建自己的下载处理程序,因为我们不想疏远大部分android用户群,因此您需要: 创建用于处理文件下载的

我建议创建一个下载对话框(如果你说它是一个大文件,我会让它出现在通知区)

然后,您需要处理文件的打开:

protected void openFile(String fileName) {
    Intent install = new Intent(Intent.ACTION_VIEW);
    install.setDataAndType(Uri.fromFile(new File(fileName)),
            "MIME-TYPE");
    startActivity(install);
}

问题

Android DownloadManager API-下载后打开文件

解决方案

/**
 * Used to download the file from url.
 * <p/>
 * 1. Download the file using Download Manager.
 *
 * @param url      Url.
 * @param fileName File Name.
 */
public void downloadFile(final Activity activity, final String url, final String fileName) {
    try {
        if (url != null && !url.isEmpty()) {
            Uri uri = Uri.parse(url);
            activity.registerReceiver(attachmentDownloadCompleteReceive, new IntentFilter(
                    DownloadManager.ACTION_DOWNLOAD_COMPLETE));

            DownloadManager.Request request = new DownloadManager.Request(uri);
            request.setMimeType(getMimeType(uri.toString()));
            request.setTitle(fileName);
            request.setDescription("Downloading attachment..");
            request.allowScanningByMediaScanner();
            request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
            request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName);
            DownloadManager dm = (DownloadManager) activity.getSystemService(Context.DOWNLOAD_SERVICE);
            dm.enqueue(request);
        }
    } catch (IllegalStateException e) {
        Toast.makeText(activity, "Please insert an SD card to download file", Toast.LENGTH_SHORT).show();
    }
}

/**
 * Used to get MimeType from url.
 *
 * @param url Url.
 * @return Mime Type for the given url.
 */
private String getMimeType(String url) {
    String type = null;
    String extension = MimeTypeMap.getFileExtensionFromUrl(url);
    if (extension != null) {
        MimeTypeMap mime = MimeTypeMap.getSingleton();
        type = mime.getMimeTypeFromExtension(extension);
    }
    return type;
}

/**
 * Attachment download complete receiver.
 * <p/>
 * 1. Receiver gets called once attachment download completed.
 * 2. Open the downloaded file.
 */
BroadcastReceiver attachmentDownloadCompleteReceive = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) {
            long downloadId = intent.getLongExtra(
                    DownloadManager.EXTRA_DOWNLOAD_ID, 0);
            openDownloadedAttachment(context, downloadId);
        }
    }
};

/**
 * Used to open the downloaded attachment.
 *
 * @param context    Content.
 * @param downloadId Id of the downloaded file to open.
 */
private void openDownloadedAttachment(final Context context, final long downloadId) {
    DownloadManager downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
    DownloadManager.Query query = new DownloadManager.Query();
    query.setFilterById(downloadId);
    Cursor cursor = downloadManager.query(query);
    if (cursor.moveToFirst()) {
        int downloadStatus = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
        String downloadLocalUri = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
        String downloadMimeType = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_MEDIA_TYPE));
        if ((downloadStatus == DownloadManager.STATUS_SUCCESSFUL) && downloadLocalUri != null) {
            openDownloadedAttachment(context, Uri.parse(downloadLocalUri), downloadMimeType);
        }
    }
    cursor.close();
}

/**
 * Used to open the downloaded attachment.
 * <p/>
 * 1. Fire intent to open download file using external application.
 *
 * 2. Note:
 * 2.a. We can't share fileUri directly to other application (because we will get FileUriExposedException from Android7.0).
 * 2.b. Hence we can only share content uri with other application.
 * 2.c. We must have declared FileProvider in manifest.
 * 2.c. Refer - https://developer.android.com/reference/android/support/v4/content/FileProvider.html
 *
 * @param context            Context.
 * @param attachmentUri      Uri of the downloaded attachment to be opened.
 * @param attachmentMimeType MimeType of the downloaded attachment.
 */
private void openDownloadedAttachment(final Context context, Uri attachmentUri, final String attachmentMimeType) {
    if(attachmentUri!=null) {
        // Get Content Uri.
        if (ContentResolver.SCHEME_FILE.equals(attachmentUri.getScheme())) {
            // FileUri - Convert it to contentUri.
            File file = new File(attachmentUri.getPath());
            attachmentUri = FileProvider.getUriForFile(activity, "com.freshdesk.helpdesk.provider", file);;
        }

        Intent openAttachmentIntent = new Intent(Intent.ACTION_VIEW);
        openAttachmentIntent.setDataAndType(attachmentUri, attachmentMimeType);
        openAttachmentIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        try {
            context.startActivity(openAttachmentIntent);
        } catch (ActivityNotFoundException e) {
            Toast.makeText(context, context.getString(R.string.unable_to_open_file), Toast.LENGTH_LONG).show();
        }
    }
}
/**
*用于从url下载文件。
*

* 1. 使用下载管理器下载文件。 * *@param-url。 *@param fileName文件名。 */ 公共无效下载文件(最终活动活动、最终字符串url、最终字符串文件名){ 试一试{ if(url!=null&&!url.isEmpty()){ Uri=Uri.parse(url); activity.registerReceiver(附件下载CompleteReceive,新的意向过滤器( DownloadManager.ACTION_DOWNLOAD_COMPLETE); DownloadManager.Request=新的DownloadManager.Request(uri); setMimeType(getMimeType(uri.toString()); setTitle(文件名); request.setDescription(“下载附件”); request.allowScanningByMediaScanner(); request.setNotificationVisibility(DownloadManager.request.VISIBILITY\u VISIBLE\u NOTIFY\u完成); request.setDestinationNexternalPublicDir(Environment.DIRECTORY\u下载,文件名); DownloadManager dm=(DownloadManager)activity.getSystemService(Context.DOWNLOAD\u服务); dm.enqueue(请求); } }捕获(非法状态){ Toast.makeText(活动“请插入SD卡以下载文件”,Toast.LENGTH_SHORT.show(); } } /** *用于从url获取MimeType。 * *@param-url。 *@返回给定url的Mime类型。 */ 私有字符串getMimeType(字符串url){ 字符串类型=null; 字符串扩展名=MimeTypeMap.getFileExtensionFromUrl(url); if(扩展名!=null){ MimeTypeMap mime=MimeTypeMap.getSingleton(); type=mime.getMimeTypeFromExtension(扩展名); } 返回类型; } /** *附件下载完整的接收器。 *

* 1. 一旦附件下载完成,接收方将被调用。 * 2. 打开下载的文件。 */ BroadcastReceiver attachmentDownloadCompleteReceive=new BroadcastReceiver(){ @凌驾 公共void onReceive(上下文、意图){ String action=intent.getAction(); if(DownloadManager.ACTION\u DOWNLOAD\u COMPLETE.equals(ACTION)){ long downloadId=intent.getLongExtra( DownloadManager.EXTRA_DOWNLOAD_ID,0); openDownloadedAttachment(上下文,downloadId); } } }; /** *用于打开下载的附件。 * *@param上下文内容。 *@param downloaddid要打开的下载文件的Id。 */ 私有void opendownloadeAttachment(最终上下文上下文,最终长下载ID){ 下载管理器下载管理器=(下载管理器)context.getSystemService(context.DOWNLOAD\u服务); DownloadManager.Query Query=新建DownloadManager.Query(); query.setFilterById(下载ID); Cursor=downloadManager.query(查询); if(cursor.moveToFirst()){ int downloadStatus=cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)); String downloadLocalUri=cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI)); String downloadMimeType=cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_MEDIA_TYPE)); if((downloadStatus==DownloadManager.STATUS_SUCCESSFUL)&&downloadLocalUri!=null){ openDownloadedAttachment(上下文,Uri.parse(downloadLocalUri),downloadMimeType); } } cursor.close(); } /** *用于打开下载的附件。 *

* 1. Fire意图使用外部应用程序打开下载文件。 * * 2. 注: *2.a。我们不能直接将fileUri共享给其他应用程序(因为我们将从Android7.0获得FileUriExposedException)。 *2.b。因此,我们只能与其他应用程序共享内容uri。 *2.c。我们必须在清单中声明FileProvider。 *2.c。参考-https://developer.android.com/reference/android/support/v4/content/FileProvider.html * *@param上下文。 *@param attachmentUri要打开的下载附件的Uri。 *@param attachmentMimeType下载附件的MimeType。 */ 私有void opendownloadeAttachment(最终上下文上下文、Uri attachmentUri、最终字符串attachmentMimeType){ if(attachmentUri!=null){ //获取内容Uri。 if(ContentResolver.SCHEME_FILE.equals)(attachmentUri.getSche

<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="com.freshdesk.helpdesk.provider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_path"/>
</provider>
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="attachment_file" path="."/>
</paths>