如何在Android TV中利用Download Manager显示下载失败通知?
Hey there! Let's tackle your Android TV download notification issues. I see you're struggling with distinguishing between successful and failed downloads, plus the fact that Android TV doesn't have a status bar to show Download Manager progress. Let's break this down into manageable steps.
First: Fix the Broadcast Receiver Registration
Right now you're registering the receiver every time a button is clicked, which creates duplicate receivers and can cause unexpected behavior (like responding to clicks from other activities). Let's move the registration to onCreate() and unregister it in onDestroy() instead:
private BroadcastReceiver downloadReceiver; private IntentFilter downloadFilter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Initialize filter and receiver once downloadFilter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE); downloadReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { handleDownloadCompletion(context, intent); } }; // Register receiver here, not in onClick registerReceiver(downloadReceiver, downloadFilter); } @Override protected void onDestroy() { super.onDestroy(); // Unregister to avoid memory leaks if (downloadReceiver != null) { unregisterReceiver(downloadReceiver); } }
Second: Distinguish Download Success vs Failure
Next, we need to check the download status using the DownloadManager when the broadcast is received. We'll get the download ID from the intent, query the manager for its status, and then show the correct notification.
Add this helper method to handle the download completion:
private void handleDownloadCompletion(Context context, Intent intent) { long downloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1); if (downloadId == -1) { return; } DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE); DownloadManager.Query query = new DownloadManager.Query(); query.setFilterById(downloadId); Cursor cursor = dm.query(query); if (cursor.moveToFirst()) { int statusIndex = cursor.getColumnIndex(DownloadManager.COLUMN_STATUS); int status = cursor.getInt(statusIndex); String notificationTitle; String notificationText; switch (status) { case DownloadManager.STATUS_SUCCESSFUL: notificationTitle = "Download Complete!"; notificationText = "Your file has been downloaded successfully."; break; case DownloadManager.STATUS_FAILED: int reasonIndex = cursor.getColumnIndex(DownloadManager.COLUMN_REASON); int failureReason = cursor.getInt(reasonIndex); notificationTitle = "Download Failed"; // You can customize the failure message based on the reason notificationText = "Oops! Download failed. Reason: " + getFailureReason(failureReason); break; default: // Ignore other statuses (like paused, pending) cursor.close(); return; } // Show notification for Android TV showTvNotification(context, notificationTitle, notificationText); } cursor.close(); } // Helper to get readable failure reason private String getFailureReason(int reason) { switch (reason) { case DownloadManager.ERROR_FILE_NOT_FOUND: return "File not found"; case DownloadManager.ERROR_INSUFFICIENT_SPACE: return "Insufficient storage space"; case DownloadManager.ERROR_CANNOT_RESUME: return "Cannot resume download"; default: return "Unknown error"; } }
Third: Create Android TV-Friendly Notifications
Since Android TV doesn't have a status bar, we need to create a proper system notification that appears in the TV's notification center (accessible via the remote's menu/notification button). We'll also need to set up a notification channel (required for Android 8.0+):
private void showTvNotification(Context context, String title, String text) { // Create notification channel (for Android O+) String channelId = "download_notifications_tv"; String channelName = "Download Status"; NotificationChannel channel = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_DEFAULT); channel.setDescription("Notifications for download status on Android TV"); NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.createNotificationChannel(channel); // Build the notification NotificationCompat.Builder builder = new NotificationCompat.Builder(context, channelId) .setSmallIcon(R.drawable.ic_notification) // Replace with your app's icon .setContentTitle(title) .setContentText(text) .setPriority(NotificationCompat.PRIORITY_DEFAULT) .setAutoCancel(true); // Dismiss when user selects it // Show the notification notificationManager.notify((int) System.currentTimeMillis(), builder.build()); }
Fourth: Update Your OnClick Logic
Now clean up your onClick method—remove the receiver registration from here, since we already do that in onCreate():
@Override public void onClick(View view) { int id = view.getId(); DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE); if (id == R.id.myfile) { DownloadManager.Request request1 = new DownloadManager.Request( Uri.parse("https://myurl.zip")); request1.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "/mydir/myfile.zip"); dm.enqueue(request1); Toast.makeText(MainActivity.this, "You chose myfile.zip", Toast.LENGTH_SHORT).show(); } else if (id == R.id.myfile2) { DownloadManager.Request request2 = new DownloadManager.Request( Uri.parse("https://myurl2.zip")); request2.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "/mydir2/myfile2.zip"); dm.enqueue(request2); Toast.makeText(MainActivity.this, "You chose myfile2.zip.", Toast.LENGTH_SHORT).show(); } }
Important Notes
- Permissions: Make sure you have the required permissions in your
AndroidManifest.xml:- For Android 13+:
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> - For accessing external storage (if targeting Android 12 or lower):
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
- For Android 13+:
- Notification Icon: Use a simple, high-contrast icon for the notification—Android TV icons should be clear and easy to see from a distance.
- Avoid Toast: Toast messages are easy to miss on Android TV, so using system notifications is the better approach for status updates.
This setup will properly distinguish between successful and failed downloads, show clear notifications in the Android TV notification center, and fix the duplicate receiver issue you were facing.
内容的提问来源于stack exchange,提问作者jack tenor

