Donc, je ne sais pas où/comment implémenter cette méthode pour que mon service s'exécute au premier plan. Actuellement, je commence mon service par les éléments suivants dans une autre activité:
Intent i = new Intent(context, myService.class);
context.startService(i);
Et puis dans onCreate () de myServices, j'essaie startForeground () ...?
Notification notification = new Notification();
startForeground(1, notification);
Alors oui, je suis un peu perdu et incertain de la façon de mettre en œuvre cela.
Je commencerais par remplir complètement la Notification
. Voici un exemple de projet démontrant l'utilisation de startForeground()
.
Depuis votre activité principale, démarrez le service avec le code suivant:
Intent i = new Intent(context, MyService.class);
context.startService(i);
Ensuite, dans votre service pour onCreate()
, vous construirez votre notification et la définirez au premier plan, comme ceci:
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
notificationIntent, 0);
Notification notification = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.app_icon)
.setContentTitle("My Awesome App")
.setContentText("Doing some work...")
.setContentIntent(pendingIntent).build();
startForeground(1337, notification);
Ceci est mon code pour définir le service au premier plan:
private void runAsForeground(){
Intent notificationIntent = new Intent(this, RecorderMainActivity.class);
PendingIntent pendingIntent=PendingIntent.getActivity(this, 0,
notificationIntent, Intent.FLAG_ACTIVITY_NEW_TASK);
Notification notification=new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentText(getString(R.string.isRecording))
.setContentIntent(pendingIntent).build();
startForeground(NOTIFICATION_ID, notification);
}
Je dois créer une notification à l'aide de PendingIntent, afin de pouvoir démarrer mon activité principale à partir de la notification.
Pour supprimer la notification, appelez simplement stopForeground (true);
Il est appelé dans onStartCommand (). S'il vous plaît se référer à mon code à: https://github.com/bearstand/greyparrot/blob/master/src/com/xiong/richard/greyparrot/Mp3Recorder.Java
J'ai rencontré des problèmes tels que RemoteServiceException en raison d'un identifiant de canal non valide avec les versions les plus récentes d'Android. Voici comment je l'ai résolu:
Activité :
override fun onCreate(savedInstanceState: Bundle?) {
val intent = Intent(this, BackgroundService::class.Java)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(intent)
} else {
startService(intent)
}
}
BackgroundService:
override fun onCreate() {
super.onCreate()
startForeground()
}
private fun startForeground() {
val service = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val channelId =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
createNotificationChannel()
} else {
// If earlier version channel ID is not used
// https://developer.Android.com/reference/Android/support/v4/app/NotificationCompat.Builder.html#NotificationCompat.Builder(Android.content.Context)
""
}
val notificationBuilder = NotificationCompat.Builder(this, channelId )
val notification = notificationBuilder.setOngoing(true)
.setSmallIcon(R.mipmap.ic_launcher)
.setPriority(PRIORITY_MIN)
.setCategory(Notification.CATEGORY_SERVICE)
.build()
startForeground(101, notification)
}
@RequiresApi(Build.VERSION_CODES.O)
private fun createNotificationChannel(): String{
val channelId = "my_service"
val channelName = "My Background Service"
val chan = NotificationChannel(channelId,
channelName, NotificationManager.IMPORTANCE_HIGH)
chan.lightColor = Color.BLUE
chan.importance = NotificationManager.IMPORTANCE_NONE
chan.lockscreenVisibility = Notification.VISIBILITY_PRIVATE
val service = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
service.createNotificationChannel(chan)
return channelId
}
Java EQUIVALENT
public class YourService extends Service {
// Constants
private static final int ID_SERVICE = 101;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
return START_STICKY;
}
@Override
public void onCreate() {
super.onCreate();
// do stuff like register for BroadcastReceiver, etc.
// Create the Foreground Service
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
String channelId = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ? createNotificationChannel(notificationManager) : "";
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, channelId);
Notification notification = notificationBuilder.setOngoing(true)
.setSmallIcon(R.mipmap.ic_launcher)
.setPriority(PRIORITY_MIN)
.setCategory(NotificationCompat.CATEGORY_SERVICE)
.build();
startForeground(ID_SERVICE, notification);
}
@RequiresApi(Build.VERSION_CODES.O)
private String createNotificationChannel(NotificationManager notificationManager){
String channelId = "my_service_channelid";
String channelName = "My Foreground Service";
NotificationChannel channel = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_HIGH);
// omitted the LED color
channel.setImportance(NotificationManager.IMPORTANCE_NONE);
channel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
notificationManager.createNotificationChannel(channel);
return channelId;
}
}
En plus deRAWAanswer, cette paix de code:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(intent)
} else {
startService(intent)
}
Vous pouvez changer pour:
ContextCompat.startForegroundService(context, yourIntent);
Si vous regardez à l'intérieur de cette méthode, vous constaterez que cette méthode effectue tout le travail de vérification pour vous.
alors vous devriez remplacer onHandleIntent()
like ceci
Override
protected void onHandleIntent(@Nullable Intent intent) {
startForeground(FOREGROUND_ID,getNotification()); //<-- Makes Foreground
// Do something
stopForeground(true); // <-- Makes it again a normal Service
}
simple. Voici la méthode getNotification()
public Notification getNotification()
{
Intent intent = new Intent(this, SecondActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this,0,intent,0);
NotificationCompat.Builder foregroundNotification = new NotificationCompat.Builder(this);
foregroundNotification.setOngoing(true);
foregroundNotification.setContentTitle("MY Foreground Notification")
.setContentText("This is the first foreground notification Peace")
.setSmallIcon(Android.R.drawable.ic_btn_speak_now)
.setContentIntent(pendingIntent);
return foregroundNotification.build();
}
Ça arrive
Un service de premier plan,
s'assure que l'utilisateur est activement conscient du fait que quelque chose se passe en arrière-plan en fournissant la notification.
(le plus important) n'est pas tué par le système lorsqu'il manque de mémoire
Implémentation de la fonctionnalité de téléchargement de morceau dans une application musicale
Ajouter un code donné à la classe de service pour "OS> = Build.VERSION_CODES.O" in onCreate ()
@Override
public void onCreate(){
super.onCreate();
.................................
.................................
//For creating the Foreground Service
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
String channelId = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ? getNotificationChannel(notificationManager) : "";
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, channelId);
Notification notification = notificationBuilder.setOngoing(true)
.setSmallIcon(R.mipmap.ic_launcher)
// .setPriority(PRIORITY_MIN)
.setCategory(NotificationCompat.CATEGORY_SERVICE)
.build();
startForeground(110, notification);
}
@RequiresApi(Build.VERSION_CODES.O)
private String getNotificationChannel(NotificationManager notificationManager){
String channelId = "channelid";
String channelName = getResources().getString(R.string.app_name);
NotificationChannel channel = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_HIGH);
channel.setImportance(NotificationManager.IMPORTANCE_NONE);
channel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
notificationManager.createNotificationChannel(channel);
return channelId;
}
Ajouter cette permission dans le fichier manifeste:
<uses-permission Android:name="Android.permission.FOREGROUND_SERVICE" />
Dans mon cas, c'était totalement différent, car je n'avais pas d'activité pour lancer le service à Oreo.
Voici les étapes que j'ai utilisées pour résoudre ce problème de service de premier plan -
public class SocketService extends Service {
private String TAG = this.getClass().getSimpleName();
@Override
public void onCreate() {
Log.d(TAG, "Inside onCreate() API");
if (Build.VERSION.SDK_INT >= 26) {
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this);
mBuilder.setSmallIcon(R.drawable.ic_launcher);
mBuilder.setContentTitle("Notification Alert, Click Me!");
mBuilder.setContentText("Hi, This is Android Notification Detail!");
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// notificationID allows you to update the notification later on.
mNotificationManager.notify(100, mBuilder.build());
startForeground(100, mBuilder.mNotification);
}
Toast.makeText(getApplicationContext(), "inside onCreate()", Toast.LENGTH_LONG).show();
}
@Override
public int onStartCommand(Intent resultIntent, int resultCode, int startId) {
Log.d(TAG, "inside onStartCommand() API");
return startId;
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "inside onDestroy() API");
}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
Et après cela, pour lancer ce service, j’ai déclenché en dessous de cmd -
adb -s "+ ID_serveur +" Shell à commencer par le service principal -n com.test.socket.sample/.SocketService
Cela m'aide donc à démarrer le service sans activité sur les appareils Oreo :)
Remarque: si votre application cible une API de niveau 26 ou supérieur, le système impose des restrictions quant à l'utilisation ou la création de services en arrière-plan, sauf si l'application est au premier plan.
Si une application doit créer un service de premier plan, elle doit appeler startForegroundService()
. Cette méthode crée un service en arrière-plan, mais la méthode indique au système que le service se présentera au premier plan.
Une fois le service créé, le service doit appeler sa startForeground() method within five seconds.