检查下载管理器是否已经下载了文件

3
如何检查文件是否已下载并运行其安装程序?以下是代码示例:
public void downloadUpdate(String url){

    DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
    request.setDescription("Downloading...");
    request.setTitle("App Update");
    request.allowScanningByMediaScanner();
    request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);

    String name = URLUtil.guessFileName(url, null, MimeTypeMap.getFileExtensionFromUrl(url));

    request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, name);

    DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
    manager.enqueue(request);
}
3个回答

10

为了检查下载管理器是否已经下载文件,您必须实现自己的BroatcastReceiver。

@Override
public void onReceive(Context context, Intent intent) {
    String action = intent.getAction();
    if (action.equals(DownloadManager.ACTION_DOWNLOAD_COMPLETE)) {
        DownloadManager.Query query = new DownloadManager.Query();
        query.setFilterById(intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, 0));
        DownloadManager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
        Cursor cursor = manager.query(query);
        if (cursor.moveToFirst()) {
            if (cursor.getCount() > 0) {
                int status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
                if (status == DownloadManager.STATUS_SUCCESSFUL) {
                    String file = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_FILENAME));
                    // So something here on success
                } else {
                    int message = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_REASON));
                    // So something here on failed.
                }
            }
        }
    }
}

我不确定您是否可以以程序化的方式安装APK。出于安全原因,我认为您不能这样做。对于应用程序更新,我认为您应该使用Google版本控制。当您使用不同版本号重新部署应用程序时,用户应该能够自动更新(除非用户在Google Play上关闭了此功能)。希望这会有所帮助。

更新

您不需要调用我提到的方法。您只需要在清单xml文件中声明广播接收器,DownloadManager将在下载完成后调用它。XML看起来像下面这样:

    <receiver
        android:name=".BroadcastReceiver"
        android:enabled="true"
        android:exported="true" >
        <intent-filter>
            <action android:name="android.intent.action.DOWNLOAD_COMPLETE" />
            <action android:name="android.intent.action.DOWNLOAD_NOTIFICATION_CLICKED" />
        </intent-filter>
    </receiver>

如何调用这个方法? - user4516999
你不需要调用,只需扩展BroadcastReceiver并在清单xml中进行配置。我已经更新了答案以提供更多细节。 - Joey Chong
可以请问如何检查多个文件是否已下载?我认为我们需要使用while循环,但我不知道如何使用,请更新答案以解决多个文件的问题。 - Gowthaman M

0

这是一个相对简单的方法。它对我有效: 您需要在清单文件中添加<receiver>标签,如下所示:

 <application>
 <receiver
            android:name= "com.example.checkDownloadComplete" <!-- add desired full name here --> 
            android:exported="true" >
            <intent-filter>
                <action android:name="android.intent.action.DOWNLOAD_COMPLETE" />
            </intent-filter>
 </receiver>
 </application>

这将为下载完成的事件注册广播接收器。一旦下载完成,它将调用您的类中的onReceive()方法。请记住,您需要扩展 BroadcastReceiver 类,而不是实现它。我声明了一个布尔变量作为切换来检查下载是否完成。因此,您的Java类将类似于:

public static class checkDownloadComplete extends BroadcastReceiver{

     public static boolean isDownloadComplete= false;

     @Override
     public void onReceive(Context context, Intent intent) {
         isDownloadComplete = true;
         Log.i("Download completed?", String.valueOf(isDownloadComplete));
     }

}

如果想要在其他类中等待或检查下载是否完成,请在适当的位置使用以下简单代码:

while(!checkDownloadComplete.isDownloadComplete){

    // add necessary code to be executed before completion of download
}
//code after completion of download

但是请记住,如果您需要在项目中多次检查它,则需要事先重置isDownloadComplete的值。


0
如果您想让系统在下载完成时通知您,可以使用 BroadcastReceiver 解决方案。
但是,如果您想手动获取下载状态,可以使用此代码,无需将接收器添加到清单文件中。
注意:界面仅用于测试目的,如果您愿意,可以将其丢弃。

interface Downloader {
    fun downloadFile(url: String,folderName:String,fileName:String): Long
}

class AndroidDownloader(
    private val context: Context
): Downloader {

    private val downloadManager = context.getSystemService(DownloadManager::class.java)

    override fun downloadFile(url: String,folderName:String,fileName:String): Long {
        val request = DownloadManager.Request(url.toUri())
            .setMimeType("image/jpeg")
            .setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN)
            .setTitle(fileName)
            .setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "$folderName/$fileName")
        return downloadManager.enqueue(request)
    }


    fun is_download_complete(downloadId: Long): Boolean {
        val query = DownloadManager.Query()
        query.setFilterById(downloadId)
        val cursor = downloadManager?.query(query)
        if (cursor == null) {
            return false
        }
        if (!cursor.moveToFirst()) {
            cursor.close()
            return false
        }
        val columnIndex = cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)
        val status = cursor.getInt(columnIndex)
        cursor.close()
        return status == DownloadManager.STATUS_SUCCESSFUL || status == DownloadManager.STATUS_FAILED
    }
}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接