NotificationCompat.Builder не работает
Я пытаюсь добавить action
в foreground service notification
, Но действие щелчка никогда не срабатывало pending intent
, Я попробовал два следующих подхода.
1-й подход
обслуживание
Intent stopActionIntent = new Intent(STOP_SERVICE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(MyService.this, 0, stopActionIntent,0);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID);
builder.addAction(0,"stop",pendingIntent);
манифест
<receiver android:name="com.myproject.receivers.ServiceActionReceiver">
<intent-filter >
<action android:name="com.myproject.services.myservice.STOP_SERVICE"/>
</intent-filter>
</receiver>
Приемник вещания
@Override
public void onReceive(Context context, Intent intent) {
if(intent != null && intent.getAction().equals(MyService.STOP_SERVICE)){
context.stopService(new Intent(context,MyService.class));
}
}
Но вещательный приемник никогда не звонил.
2-й подход
оказание услуг
if(intent != null && STOP_SERVICE.equals(intent.getAction())){
stopSelf();
return super.onStartCommand(intent,flags,startId);
}
else {
Intent stopActionIntent = new Intent(this,MyService.class);
stopActionIntent.setAction(STOP_SERVICE);
PendingIntent pendingIntent = PendingIntent.getActivity(MyService.this, 0, stopActionIntent,0);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID);
builder.addAction(0,"stop",pendingIntent);
}
Ни один подход не работает.
build.gradle
defaultConfig {
applicationId "com.myproject.project"
minSdkVersion 16
targetSdkVersion 27
versionCode 2
versionName "1.0.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
multiDexEnabled true
}
Примечание: уведомление и действие видны.
редактировать
Не работает на Android 8.0 или выше, работает другая версия.
3 ответа
В Android O обязательно использовать канал с вашим Notification Builder.
образец кода:
// Sets an ID for the notification, so it can be updated
int notifyID = 1;
String CHANNEL_`enter code here`ID = "my_channel_01";// The id of the channel.
CharSequence name = getString(R.string.channel_name);// The user-visible name of the channel.
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel mChannel = new NotificationChannel(CHANNEL_ID, name, importance);
// Create a notifi`enter code here`cation and set the notification channel.
Notification notification = new Notification.Builder(MainActivity.this)
.setContentTitle("New Message")
.setContentText("You've received new messages.")
.setSmallIcon(R.drawable.ic_notify_status)
.setChannelId(CHANNEL_ID)
.build();
@Shantanu, у тебя много проблем. Я предложу вам создать еще один новый и типовой проект, чтобы прояснить вашу концепцию и после ее использования использовать ее в существующем проекте. У вас есть несколько проблем, давайте решать один за другим
- Сделать Receiver, чтобы поймать конкретное событие
- Из приемника Запустите сервис (приоритетный сервис)
- Из службы, создавать уведомления
Посмотрите, прежде чем начать, у вас должен быть новый пример проекта с mainacctivity и макетом mainacctivity.
Manifest.xml: эти файлы должны иметь те разрешения, которые необходимы для нашего приложения. Ниже выкладываю образец файла, в котором я обрабатываю несколько разрешений, а по конкретному событию звоню получателю. Я хочу, чтобы мой приемник не спал и получал вызов при каждом исходящем и входящем или пропущенном вызове.
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.WRITE_SMS" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".WatchMan"
android:enabled="true"
android:exported="true" />
<receiver
android:name=".Receiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
<activity android:name=".developer_activity" />
<activity android:name=".WhiteListActivity" />
<activity android:name=".Contacts"></activity>
</application>
Не копируйте указанный выше файл как есть, просто посмотрите, где и как размещены разрешения. Если вы скопируете весь файл, он не будет работать. Просто разместите ваши разрешения выше application
тег. Это оно.
Теперь создайте сервис из-> проводника вашего проекта, в Android Studio / Eclipse. Щелкните правой кнопкой мыши на нем-> Выбрать new
-> выбрать service
-> service
это откроет диалог для вас и даст соответствующее имя вашему сервису.
Он создаст для вас класс обслуживания, а также изменит ваш файл manifest.xml. Вам не нужно редактировать файл manifest.xml для этого. Вы посмотрите на мой файл манифеста выше. service
тег. Он был создан для меня автоматически, когда я создал такой сервис.
Теперь, как создать приемник для перехвата определенного события, когда он запускается в системе Android:
Для этого снова перейдите в проводник проекта -> Правый клик -> new
-> other
-> broadcast receiver
, Это также откроет диалог для вас и даст имя вашему получателю. Опять же, вам не нужно изменять файл манифеста своими руками. Это изменит ваш manifest.xml автоматически. Вы можете снова обратиться к файлу манифеста выше. И взгляните на сервис, и приемник создан для меня..
Теперь, как позвонить этому получателю, когда начнется новый вызов. Посмотрите, как я разместил
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
в тегах получателя; Это означает, что мой получатель будет вызван для этих двух событий всегда.
Теперь Receiver.java:
В вашем onReceive функция получателя
Log.d("RECEIVER ","\SUCCESS : ");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
context.startForegroundService(new Intent(context, WatchMan.class));
}
else
{
context.startService(new Intent(context, WatchMan.class));
}
Снова здесь.. вам не нужно вручную кодировать функции здесь. Вы можете создавать образцы переопределенных функций, щелкнув правой кнопкой мыши на расширенном классе BroadcastReceiver
-> generate
- override methods
и выберите onReceive
, Он создаст для вас пример метода onReceive. В рамках которого вы должны вставить вышеуказанный код, как позвонить в ваш сервис (приоритетный сервис)
Сейчас сервис:
Перейти на сервис класс. Щелкните правой кнопкой мыши на расширенном классе service
-> generate
-> override methods
и какие бы методы вы ни потребовали. Должен быть пустой метод сервиса, oncreate, onStartCommand, onDestroy, onBind. Опять же, вы можете создать образцы стандартных методов, готовых для вас, используя тот же метод создания выше.
Теперь уведомления:
объявления класса обслуживания:
NotificationManager mNotifyManager;
NotificationCompat.Builder mBuilder;
NotificationChannel notificationChannel;
String NOTIFICATION_CHANNEL_ID = "2";
в методе OnCreate:
try
{
Intent intent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
mNotifyManager = (NotificationManager) getApplicationContext().getSystemService(NOTIFICATION_SERVICE);
mBuilder = new NotificationCompat.Builder(this, null);
mBuilder.setContentTitle("App name")
.setContentText("Notification text..")
.setTicker("Notification text..")
.setSmallIcon(R.drawable.ic_service_success)
.setPriority(Notification.PRIORITY_HIGH)
.setDefaults(Notification.DEFAULT_ALL)
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setContentIntent(pendingIntent);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "My Notifications", NotificationManager.IMPORTANCE_HIGH);
// Configure the notification channel.
notificationChannel.setDescription("Channel description");
notificationChannel.enableLights(true);
notificationChannel.setLightColor(Color.RED);
notificationChannel.setVibrationPattern(new long[]{0, 1000, 500, 1000});
notificationChannel.enableVibration(true);
notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
mNotifyManager.createNotificationChannel(notificationChannel);
}
mBuilder.setChannelId(NOTIFICATION_CHANNEL_ID);
startForeground(2, mBuilder.build());
}
catch(Exception e)
{
Log.d("xx", "EXCEPTION IN SHOWING NOTIFICATION...\n");
Log.e("xx", "Exception is : ", e);
}
Теперь из-за вызова для запуска на переднем плане он начнет работать ваш Onstartcommand
метод
В onstartcommand ваша логика и код идут туда... Это зависит от вас, чтобы реализовать runnable thread
или нет. Это необязательно.
Вы можете снова показать другие уведомления, такие как:
mBuilder.setContentText("Some success or failure...");
mBuilder.setTicker("Some success or failure...");
mBuilder.setChannelId(NOTIFICATION_CHANNEL_ID);
startForeground(2, mBuilder.build());
Это оно. Он должен делать все, что вы хотите.. разрешения, события, приемник, сервис (на переднем плане) и уведомления более 4,0-8,0 Android-устройств почти на 99,8 % устройств.
Попробуйте ниже код для уведомления:
public void heads_up_notification() {
Notification.Builder mBuilder = new Notification.Builder(this);
NotificationManager nNotificationManager = (NotificationManager) getSystemService("notification");
PendingIntent piDismiss = PendingIntent.getActivity(this, 0, new Intent(this, DirectReplyActivity.class), 0);
Intent snoozeIntent = new Intent(this, MainActivity.class);
snoozeIntent.setAction(NotificationCompat.CATEGORY_ALARM);
PendingIntent piSnooze = PendingIntent.getService(this, 0, snoozeIntent, 0);
mBuilder.setSmallIcon(C0220R.drawable.ic_launcher_background);
mBuilder.setContentTitle("Heads up Notification");
mBuilder.setContentText("heads up activated");
mBuilder.setDefaults(-1);
mBuilder.setPriority(1);
mBuilder.addAction(C0220R.mipmap.ic_dismiss, "Dismiss", piDismiss);
mBuilder.addAction(C0220R.mipmap.ic_stop, "Stop", piSnooze);
nNotificationManager.notify(2, mBuilder.build());
}