问题
Currently I am using below code snippet to download a file using DownloadManager:
String servicestring = Context.DOWNLOAD_SERVICE;
DownloadManager downloadmanager;
downloadmanager = (DownloadManager) getSystemService(servicestring);
Uri uri = Uri
.parse("some url here");
DownloadManager.Request request = new Request(uri);
Using this code I am getting below notification.

My question is, can we add some cross button in this notification so that if user click that button it will cancel download?
Expected output:
(user must be able to cancel download when click on this red cross icon)
Please suggest some way if any. Thank you
回答1:
can we add some cross button in this notification so that if user click that button it will cancel download?
Not directly. That Notification
is not being displayed by your app; you have no control over its behavior.
The most likely solution is to not use DownloadManager
, but instead download the content yourself. Then, you can display whatever you want as a Notification
.
Middle ground would be to use DownloadManager
but set up the flags and permissions to allow you to request downloads that do not display a Notification
. Then, you can have your own Notification
. The downside here is that you may not be able to reproduce all features of the system-supplied Notification
(e.g., percent-complete progress indicator).
回答2:
I am using NotificationManager to show downloading percentage and cancel button.
Create pending intent to handle Cancel button click event.
mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mBuilder = new NotificationCompat.Builder(getApplicationContext());
mBuilder.setContentTitle("Extracting link")
.setContentText("Please wait")
.setSmallIcon(R.drawable.notification_icon_new)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))
.setColor(getResources().getColor(R.color.colorAccent))
.setSound(defaultSoundUri)
.addAction(R.drawable.ic_pause_circle_filled_black_24dp, "Pause", pendingIntentPause)
.addAction(R.drawable.ic_cancel_black_24dp, "Cancel", pendingIntentCancel)
.setContentIntent(pendingIntent)
.setCategory(NotificationCompat.CATEGORY_MESSAGE)
.setProgress(0, 0, true);
mNotifyManager.notify(randomNumber, mBuilder.build());
Looper mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
initDownload(urlString, randomNumber, mServiceHandler);
download logic and update notification progress.
private void initDownload(String downloadUrl, int notificationId, ServiceHandler mServiceHandler) {
try {
URL url = new URL(downloadUrl);
URLConnection connection = url.openConnection();
connection.connect();
// this will be useful so that you can show a typical 0-100% progress bar
int fileLength = connection.getContentLength();
String fileExtension = MimeTypeMap.getFileExtensionFromUrl(downloadUrl);
fileName = System.currentTimeMillis() + "." + fileExtension;
// download the file
InputStream input = new BufferedInputStream(connection.getInputStream());
OutputStream output = new FileOutputStream(Environment.getExternalStorageDirectory().toString() + "/" + AppConstant.APP_FOLDER_NAME + "/" + fileName);
byte data[] = new byte[1024];
long total = 0;
int count;
int previousProgress = 0;
while ((count = input.read(data)) != -1) {
total += count;
int progress = (int) (total * 100 / fileLength);
output.write(data, 0, count);
if (progress == 100 || progress > previousProgress + 4) {
// Only post progress event if we've made progress.
previousProgress = progress;
Message msg = mServiceHandler.obtainMessage();
Bundle bundle = new Bundle();
bundle.putInt("ID", notificationId);
bundle.putInt("PROGRESS", progress);
msg.setData(bundle);
mServiceHandler.sendMessage(msg);
}
}
output.flush();
output.close();
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private final class ServiceHandler extends Handler {
ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
try {
int mNotificationId = msg.getData().getInt("ID");
int mProgress = msg.getData().getInt("PROGRESS");
if (mProgress == -1) {
mBuilder.setContentTitle("Download fail")
.setContentText("Try another one")
.setAutoCancel(true)
.setOngoing(false)
.setProgress(0, 0, false);
} else {
mBuilder.setContentTitle("Downloading...")
.setContentText(mProgress + " % downloaded")
.setProgress(100, mProgress, false);
if (mProgress == 100) {
mBuilder.setContentTitle(fileName)
.setContentText("Download complete, Tap to view")
.setAutoCancel(true)
.setOngoing(false)
.setProgress(0, 0, false);
}
}
mNotifyManager.notify(mNotificationId, mBuilder.build());
} catch (Exception e) {
Log.d("shams", " Exception---> " + e);
HashMap<String, String> parameters11 = new HashMap<>();
parameters11.put("error_message", e.getMessage());
FlurryAgent.logEvent("video_download_fail_exception", parameters11);
e.printStackTrace();
}
}
}
回答3:
add RemoteView
in notification Here is Sample
RemoteViews remoteViews = new RemoteViews(getPackageName(),
R.layout.widget);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
this).setSmallIcon(R.drawable.ic_launcher).setContent(
remoteViews);
// Creates an explicit intent for an Activity in your app
Intent resultIntent = new Intent(this, test.class);
// The stack builder object will contain an artificial back stack for
// the
// started Activity.
// This ensures that navigating backward from the Activity leads out of
// your application to the Home screen.
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
// Adds the back stack for the Intent (but not the Intent itself)
stackBuilder.addParentStack(test.class);
// Adds the Intent that starts the Activity to the top of the stack
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0,
PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.button1, resultPendingIntent);
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// mId allows you to update the notification later on.
mNotificationManager.notify(100, mBuilder.build());
widget.xml
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
android:orientation="horizontal" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="DJ notification"
android:textAppearance="?android:attr/textAppearanceMedium" />
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Close Me" />
</LinearLayout>
The NotificationCompat.Builder is the most easy way to create Notifications on all Android versions. You can even use features that are available with Android 4.1. If your app runs on devices with Android >=4.1 the new features will be used, if run on Android <4.1 the notification will be an simple old notification.
for < 11 API use http://www.framentos.com/en/android-tutorial/2012/02/20/how-to-create-a-custom-notification-on-android/
来源:https://stackoverflow.com/questions/23236488/can-we-have-custom-notification-for-android-os-downloadmanager