Jusqu'ici, j'ai ajusté mon code pour utiliser ContextCompat.startForegroundService(context, intentService);
pour démarrer mon service. De cette façon, cela fonctionne sur Android <26 et sur Android 26 (Oreo) également.
Je vois toujours une différence, dans Android oreo, je ne vois pas ma notification de premier plan personnalisée (je ne vois que la notification "L'application fonctionne en arrière-plan"). Dois-je ajuster quoi que ce soit là? ainsi que?
Mon service ressemble à ceci:
public class BaseOverlayService extends Service {
@Override
public void onCreate() {
super.onCreate();
moveToForeground();
}
private void moveToForeground() {
Notification notification = ...;
super.startForeground(NOTIFICATION_ID, notification);
}
}
Exemple officiel
Cet exemple ( https://github.com/googlesamples/Android-play-location/blob/master/LocationUpdatesForegroundService/app/src/main/Java/com/google/Android/gms/location/sample/locationuplatesforgroundservice /LocationUpdatesService.Java#L2 ) indique comme commentaire que je devrais utiliser ce qui suit, mais startServiceInForeground
n'existe pas ...
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.O) {
NotificationManager mNotificationManager = ((NotificationManager) getSystemService(NOTIFICATION_SERVICE));
mNotificationManager.startServiceInForeground(new Intent(this, BaseOverlayService.class), NOTIFICATION_ID, notification);
} else {
startForeground(NOTIFICATION_ID, notification);
}
Modifier
Ma notification est créée comme ceci, qui fonctionne sur des milliers de Android appareils avec API <26 jusqu'à maintenant:
protected Notification foregroundNotification(int notificationId)
{
boolean paused = MainApp.getPrefs().sidebarServicePaused();
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setSmallIcon(R.drawable.icon_not);
builder.setContentIntent(notificationIntent());
builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.icon));
builder.setContentTitle(getString(R.string.derived_app_name));
builder.setContentText(getString(checkStatus() ? (paused ? R.string.service_notification_text_paused : R.string.service_notification_text_running) : R.string.service_notification_text_preparing));
builder.setColor(Color.parseColor("#25baa2"));
if (MainApp.getPrefs().hideNotificationIcon())
builder.setPriority(NotificationCompat.PRIORITY_MIN);
else
builder.setPriority(NotificationCompat.PRIORITY_MAX);
if (paused)
builder.addAction(R.drawable.ic_play_arrow_black_24dp, getString(R.string.resume), resumeIntent(this));
else
builder.addAction(R.drawable.ic_pause_black_24dp, getString(R.string.pause), pauseIntent(this));
return builder.build();
}
Vous devrez peut-être définir le canal de notification pour votre application. Consultez le journal, il devrait y avoir un avertissement. Vérifiez this pour l'introduction
Je vais vous donner un exemple, ce serait en kotin. Commencez par faire un cours comme celui-ci. Vous devrez appeler createMainNotificationChannel () une fois au début de votre application.
class NotificationManager(private val context: Context) {
companion object {
private val CHANNEL_ID = "YOUR_CHANNEL_ID"
private val CHANNEL_NAME = "Your human readable notification channel name"
private val CHANNEL_DESCRIPTION = "description"
}
@RequiresApi(Build.VERSION_CODES.O)
fun getMainNotificationId(): String {
return CHANNEL_ID
}
@RequiresApi(Build.VERSION_CODES.O)
fun createMainNotificationChannel() {
val id = CHANNEL_ID
val name = CHANNEL_NAME
val description = CHANNEL_DESCRIPTION
val importance = Android.app.NotificationManager.IMPORTANCE_LOW
val mChannel = NotificationChannel(id, name, importance)
mChannel.description = description
mChannel.enableLights(true)
mChannel.lightColor = Color.RED
mChannel.enableVibration(true)
val mNotificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as Android.app.NotificationManager
mNotificationManager.createNotificationChannel(mChannel)
}
}
Ensuite, vous pouvez utiliser util comme ceci
fun createNotificationCompatBuilder(context: Context): NotificationCompat.Builder {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
return NotificationCompat.Builder(context, NotificationManager(context).mainNotificationId)
} else {
return NotificationCompat.Builder(context)
}
}
Code en kotlin
private fun customNotification(title: String,notificationID: Int) {
val intent = Intent(this, MainActivity::class.Java)
val pendingIntent = PendingIntent.getActivity(this, 0 /* request code */, intent, PendingIntent.FLAG_UPDATE_CURRENT)
val builder = NotificationCompat.Builder(this, title)
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
.setContentText("Notification description")
.setSmallIcon(R.drawable.ic_mark_map)
.setContentIntent(pendingIntent)
.setOnlyAlertOnce(true)
val mNotificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(title,
"Channel human readable title",
NotificationManager.IMPORTANCE_DEFAULT)
mNotificationManager.createNotificationChannel(channel)
}
val notification = builder.build()
startForeground(notificationID, notification)
}
Utilisation:
customNotification("Title",101)
// Since Android Oreo notification channel is needed.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(channelId,
getString(R.string.app_name),
NotificationManager.IMPORTANCE_HIGH);
AudioAttributes attributes = new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_NOTIFICATION)
.build();
channel.setDescription(data.get("body"));
channel.enableLights(true);
channel.enableVibration(true);
channel.setSound(SoundUri, attributes); // This is IMPORTANT
notificationManager.createNotificationChannel(channel);
}