关于android下载管理器的小问题.这是我第一次使用它并成功下载了多个文件并打开了它们.但我的问题是如何检查下载是否完成.
情况是我下载一个PDF文件并打开它,通常文件很小,它在打开之前完成.但是如果文件有点大,我如何在打开之前检查下载管理器是否完成了下载.
我如何下载:
Intent intent = getIntent(); DownloadManager downloadManager = (DownloadManager)getSystemService(DOWNLOAD_SERVICE); Uri Download_Uri = Uri.parse(intent.getStringExtra("Document_href")); DownloadManager.Request request = new DownloadManager.Request(Download_Uri); //Restrict the types of networks over which this download may proceed. request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE); //Set whether this download may proceed over a roaming connection. request.setAllowedOverRoaming(false); //Set the title of this download, to be displayed in notifications. request.setTitle(intent.getStringExtra("Document_title")); //Set the local destination for the downloaded file to a path within the application's external files directory request.setDestinationInExternalFilesDir(this,Environment.DIRECTORY_DOWNLOADS,intent.getStringExtra("Document_title") + ".pdf"); //Enqueue a new download and same the referenceId Long downloadReference = downloadManager.enqueue(request);
我如何打开文件
Uri uri = Uri.parse("content://com.app.applicationname/" + "/Download/" + intent.getStringExtra("Document_title") + ".pdf"); Intent target = new Intent(Intent.ACTION_VIEW); target.setDataAndType(uri, "application/pdf"); target.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); startActivity(target);
所以在下载和打开文件之间的某个地方,我想要一个if语句来检查它是否应该继续或等待文件.
下载完成后由下载管理器发送的广播意图操作,因此您需要在下载完成时注册接收方:
注册接收器
registerReceiver(onComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
和BroadcastReciever处理程序
BroadcastReceiver onComplete=new BroadcastReceiver() { public void onReceive(Context ctxt, Intent intent) { // your code } };
您还可以创建AsyncTask来处理大文件的下载
创建某种下载对话框以显示通知区域中的下载,并处理文件的打开:
protected void openFile(String fileName) { Intent install = new Intent(Intent.ACTION_VIEW); install.setDataAndType(Uri.fromFile(new File(fileName)),"MIME-TYPE"); startActivity(install); }
您还可以查看示例链接
示例代码
我花了一个多星期的时间研究如何使用DownloadManager下载和打开文件,从来没有找到一个对我来说非常完美的答案,所以我应该采取点点滴滴来找到有效的方法.我确保尽我所能记录我的代码.如果有任何问题,请随时留在答案下方的评论中.
另外,不要忘记将此行添加到AndroidManifest.xml文件中!
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
我的下载经理:
import android.app.DownloadManager; import android.content.ActivityNotFoundException; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.net.Uri; import android.os.Environment; import android.webkit.CookieManager; import android.webkit.DownloadListener; import android.widget.Toast; import java.util.regex.Matcher; import java.util.regex.Pattern; public class MyDownloadListener implements DownloadListener { private Context mContext; private DownloadManager mDownloadManager; private long mDownloadedFileID; private DownloadManager.Request mRequest; public MyDownloadListener(Context context) { mContext = context; mDownloadManager = (DownloadManager) mContext .getSystemService(Context.DOWNLOAD_SERVICE); } @Override public void onDownloadStart(String url, String userAgent, String contentDisposition, final String mimetype, long contentLength) { // Function is called once download completes. BroadcastReceiver onComplete = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { // Prevents the occasional unintentional call. I needed this. if (mDownloadedFileID == -1) return; Intent fileIntent = new Intent(Intent.ACTION_VIEW); // Grabs the Uri for the file that was downloaded. Uri mostRecentDownload = mDownloadManager.getUriForDownloadedFile(mDownloadedFileID); // DownloadManager stores the Mime Type. Makes it really easy for us. String mimeType = mDownloadManager.getMimeTypeForDownloadedFile(mDownloadedFileID); fileIntent.setDataAndType(mostRecentDownload, mimeType); fileIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); try { mContext.startActivity(fileIntent); } catch (ActivityNotFoundException e) { Toast.makeText(mContext, "No handler for this type of file.", Toast.LENGTH_LONG).show(); } // Sets up the prevention of an unintentional call. I found it necessary. Maybe not for others. mDownloadedFileID = -1; } }; // Registers function to listen to the completion of the download. mContext.registerReceiver(onComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)); mRequest = new DownloadManager.Request(Uri.parse(url)); // Limits the download to only over WiFi. Optional. mRequest.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI); // Makes download visible in notifications while downloading, but disappears after download completes. Optional. mRequest.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE); mRequest.setMimeType(mimetype); // If necessary for a security check. I needed it, but I don't think it's mandatory. String cookie = CookieManager.getInstance().getCookie(url); mRequest.addRequestHeader("Cookie", cookie); // Grabs the file name from the Content-Disposition String filename = null; Pattern regex = Pattern.compile("(?<=filename=\").*?(?=\")"); Matcher regexMatcher = regex.matcher(contentDisposition); if (regexMatcher.find()) { filename = regexMatcher.group(); } // Sets the file path to save to, including the file name. Make sure to have the WRITE_EXTERNAL_STORAGE permission!! mRequest.setDestinationInExternalFilesDir(mContext, Environment.DIRECTORY_DOWNLOADS, filename); // Sets the title of the notification and how it appears to the user in the saved directory. mRequest.setTitle(filename); // Adds the request to the DownloadManager queue to be executed at the next available opportunity. mDownloadedFileID = mDownloadManager.enqueue(mRequest); } }
只需将此行添加到WebView类中,即可将其添加到现有WebView中:
webView.setDownloadListener(new MyDownloadListener(webView.getContext()));
礼貌:Android DonwnloadManager示例
接受的答案并不完全正确.接收ACTION_DOWNLOAD_COMPLETE广播并不意味着您的下载已完成.请注意,下载完成后,DownloadManager将广播ACTION_DOWNLOAD_COMPLETE.它并不一定意味着它是您正在等待的相同下载
解决方案是在开始下载时保存enqueue()返回的下载ID.这个长下载ID在整个系统中是唯一的,可用于检查下载状态
DownloadManager downloadManager= (DownloadManager) getSystemService(DOWNLOAD_SERVICE); long downloadID = downloadManager.enqueue(request);// enqueue puts the download request in the queue.
下载完成后,您可以通过以下三个步骤获得通知
创建一个BroadcastReceiver,如下面的片段所示.在接收器旁边,我们只需通过将收到的下载ID与我们的排队下载进行匹配来检查收到的广播是否适用于我们的下载.
private BroadcastReceiver onDownloadComplete = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { //Fetching the download id received with the broadcast long id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1); //Checking if the received broadcast is for our enqueued download by matching download id if (downloadID == id) { Toast.makeText(MainActivity.this, "Download Completed", Toast.LENGTH_SHORT).show(); } } };
创建BroadcastReceiver后,您可以在活动的onCreate方法中注册ACTION_DOWNLOAD_COMPLETE.
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); registerReceiver(onDownloadComplete,new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)); }
在onDestroy中取消注册BroadcastReceiver也很重要.这样可以确保只要活动处于活动状态,您就只能收听此广播
@Override public void onDestroy() { super.onDestroy(); unregisterReceiver(onDownloadComplete); }
我敦促你在这里阅读完整的例子