不久前,我为Android 7.1开发了一个应用。由于使用startForeground(),尝试在其他智能手机(Android 9)上运行该应用程序失败。
Intent notificationIntent = new Intent(getApplicationContext(), MyService.class);
PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0,
notificationIntent, 0);
Notification notification = new Notification.Builder(getApplicationContext())
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("title")
.setContentText("Foreground-Service running")
.setContentIntent(pendingIntent).build();
startForeground(101, notification);
我遇到以下错误:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.test2app, PID: 14754
android.app.RemoteServiceException: Bad notification for startForeground: java.lang.RuntimeException: invalid channel for service notification: Notification(channel=null pri=0 contentView=null vibrate=null sound=null defaults=0x0 flags=0x40 color=0x00000000 vis=PRIVATE)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1737)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
我添加了此权限:
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
我该如何解决?
NotificationManager notificationmanager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
String str = "ch_id_i";
if (VERSION.SDK_INT >= 26) {
NotificationChannel notificationChannel = new NotificationChannel(str, "name",
NotificationManager.IMPORTANCE_LOW);
notificationChannel.enableLights(true);
notificationChannel.setLightColor(SupportMenu.CATEGORY_MASK);
notificationChannel.enableVibration(false);
notificationChannel.setShowBadge(false);
notificationmanager.createNotificationChannel(notificationChannel);
}
builder = new NotificationCompat.Builder(context, str);
它正在工作:
Intent notificationIntent = new Intent(getApplicationContext(), MyService.class);
PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0,
notificationIntent, 0);
createNotificationChannel();
NotificationCompat.Builder builder = new NotificationCompat.Builder(ctx, CHANNEL_ID);
builder.setSmallIcon(R.drawable.ic_launcher_background);
builder.setContentTitle("title");
builder.setContentText("text");
builder.setPriority(NotificationCompat.PRIORITY_DEFAULT);
builder.setContentIntent(pendingIntent);
startForeground(1, builder.build());
private void createNotificationChannel() {
// Create the NotificationChannel, but only on API 26+ because
// the NotificationChannel class is new and not in the support library
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = "Foregroundservice MyService.java";
String description = "Benachrichtigung über das Aktivieren des Foreground-Service";
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
channel.setDescription(description);
// Register the channel with the system; you can't change the importance
// or other notification behaviors after this
NotificationManager notificationManager = getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
}
良好参考:https://developer.android.com/training/notify-user/build-notification#java
它正在工作:
Intent notificationIntent = new Intent(getApplicationContext(), MyService.class);
PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0,
notificationIntent, 0);
createNotificationChannel();
NotificationCompat.Builder builder = new NotificationCompat.Builder(ctx, CHANNEL_ID);
builder.setSmallIcon(R.drawable.ic_launcher_background);
builder.setContentTitle("title");
builder.setContentText("text");
builder.setPriority(NotificationCompat.PRIORITY_DEFAULT);
builder.setContentIntent(pendingIntent);
startForeground(1, builder.build());
private void createNotificationChannel() {
// Create the NotificationChannel, but only on API 26+ because
// the NotificationChannel class is new and not in the support library
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = "Foregroundservice MyService.java";
String description = "Benachrichtigung über das Aktivieren des Foreground-Service";
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
channel.setDescription(description);
// Register the channel with the system; you can't change the importance
// or other notification behaviors after this
NotificationManager notificationManager = getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
}
良好参考:https://developer.android.com/training/notify-user/build-notification#java
类似的东西,但是要自己建立
private NotificationManager notifManager;
public void createNotification(String aTitle, String aMessage, int channelID, Context context, JobParameters params) {
NotificationManager notifManager;
Random rnd = new Random();
int dynamicRequestCode = rnd.nextInt(9999 - 1000) + 1000;
dynamicRequestCode += rnd.nextInt(100) + 1;
final int NOTIFY_ID = channelID;
String id = String.valueOf(channelID);
String title = "Channel Title";
Intent intent;
PendingIntent pendingIntent;
NotificationCompat.Builder builder;
if (notifManager == null) {
notifManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel mChannel = notifManager.getNotificationChannel(id);
if (mChannel == null) {
AudioAttributes att = new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_NOTIFICATION)
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.build();
mChannel = new NotificationChannel(id, title, importance);
mChannel.enableVibration(true);
mChannel.setVibrationPattern(new long[]{0, 250, 200, 250, 150, 150, 75, 150, 75, 150});
notifManager.createNotificationChannel(mChannel);
}
builder = new NotificationCompat.Builder(context, id);
intent = new Intent(context, your_activity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
pendingIntent = PendingIntent.getActivity(context, dynamicRequestCode, intent, 0);
builder.setContentTitle(aTitle)
.setSmallIcon(R.drawable.ic_event)
.setDefaults(Notification.DEFAULT_ALL)
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(aMessage))
.setContentText(aMessage)
.setAutoCancel(true)
.setContentIntent(pendingIntent)
.setTicker(aMessage)
.setVibrate(new long[]{0, 250, 200, 250, 150, 150, 75, 150, 75, 150});
} else {
builder = new NotificationCompat.Builder(context, id);
intent = new Intent(context, your_activity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
pendingIntent = PendingIntent.getActivity(context, dynamicRequestCode, intent, 0);
builder.setContentTitle(aTitle)
.setSmallIcon(R.drawable.ic_event)
.setDefaults(Notification.DEFAULT_ALL)
.setAutoCancel(true)
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(aMessage))
.setContentText(aMessage)
.setContentIntent(pendingIntent)
.setTicker(aMessage)
.setVibrate(new long[]{0, 250, 200, 250, 150, 150, 75, 150, 75, 150})
.setPriority(Notification.PRIORITY_DEFAULT);
}
Notification notification = builder.build();
Random random = new Random();
int num = random.nextInt(999 - 100) + 100;
num += random.nextInt(10) + 1;
notifManager.notify(num, notification);
我已经在我的上一个项目中做到了这一点。我已经做出了随机请求代码,以避免覆盖通知。
以及服务内的呼叫:
@Override
public boolean onStartJob(JobParameters params) {
Log.d(TAG, "onStartJob: Job Started");
doBackgroundWork(params);
return true;
}
private void doBackgroundWork(final JobParameters params) {
new Thread(new Runnable() {
@Override
public void run() {
notifiy(params);
}
}).start();
}
public void notifiy(JobParameters params) {
createNotification("Title", "Notification body", NOTIFICATION_CHANNEL_ID, getApplicationContext(), params);
jobFinished(params, false);
}