Android-реализация startForeground для сервиса?



поэтому я не уверен, где/как реализовать этот метод, чтобы мой сервис работал на переднем плане. В настоящее время я начинаю свою службу следующим образом в другом действии:



Intent i = new Intent(context, myService.class); 
context.startService(i);


а затем в myServices' onCreate () я пытаюсь startForeground ()...?



Notification notification = new Notification();
startForeground(1, notification);


Так что да я немного потерял и не уверен, как это реализовать.

2124   9  

9 ответов:

Я бы начал с полного заполнения Notification. вот пример проекта демонстрация использования startForeground().

из вашего основного вида деятельности, запустите службу со следующим кодом:

Intent i = new Intent(context, MyService.class); 
context.startService(i);

тогда к вашим услугам для onCreate() вы бы построить свое уведомление и установить его в качестве переднего плана, как так:

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);

Это мой код для установки службы на передний план:

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);

}

Мне нужно построить уведомление с помощью PendingIntent, чтобы я мог начать свою основную деятельность с уведомления.

чтобы удалить уведомление, просто вызовите stopForeground (true);

он вызывается в onStartCommand (). Пожалуйста, обратитесь к моему коду по адресу : https://github.com/bearstand/greyparrot/blob/master/src/com/xiong/richard/greyparrot/Mp3Recorder.java

решение для Oreo 8.1

я столкнулся с некоторыми проблемами, такими как RemoteServiceException из-за неверного идентификатора канала с самыми последними версиями Android. Вот как я решил это:

активность:

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

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;
    }
}

если вы хотите сделать IntentService службой переднего плана

затем вы должны переопределить onHandleIntent()такой

Override
protected void onHandleIntent(@Nullable Intent intent) {


    startForeground(FOREGROUND_ID,getNotification());     //<-- Makes Foreground

   // Do something

    stopForeground(true);                                // <-- Makes it again a normal Service                         

}

как сделать уведомление ?

простой. Вот это 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();
}

Более Глубокое Понимание

что происходит, когда служба становится основной услуги

это происходит

enter image description here

Что такое служба переднего плана ?

служба переднего плана,

  • гарантирует, что пользователь активно осознает, что что-то происходит в фоновом режиме путем предоставления уведомления.

  • (самое главное) не убивается системой, когда у нее заканчивается память

вариант использования службы переднего плана

реализация функции загрузки песни в музыкальном приложении

кроме Раве ответьте, это мир кода:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    startForegroundService(intent)
} else {
    startService(intent)
}

Вы можете изменить на:

ContextCompat.startForegroundService(context, yourIntent);

Если вы посмотрите внутри этого метода, то вы можете увидеть, что этот метод делает все проверки работы для вас.

в моем случае это было совершенно другое, так как у меня не было активности для запуска службы в Oreo.

Ниже приведены шаги, которые я использовал для решения этой проблемы-

публичный класс SocketService расширяет сервис { частный строковый тег = это.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;
}

}

и после этого для запуска этой службы я запустил ниже cmd -


adb-s "+ serial_id + " shell am startforegroundservice-N com.тест.разъем.образец./SocketService


Так что это помогает мне начать обслуживание без активности на устройствах Oreo:)

обрабатывать намерение на startCommand сервиса с помощью.

 stopForeground(true)

этот вызов удалить службу из состояния переднего плана, что позволяет его убить, если требуется больше памяти. это не останавливает службу запуск. Для этого вам нужно позвонить stopSelf() или связанные методы.

передает значение правда или ложные указывается, если вы хотите удалить уведомление или не.

val ACTION_STOP_SERVICE = "stop_service"
val NOTIFICATION_ID_SERVICE = 1
...  
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
    super.onStartCommand(intent, flags, startId)
    if (ACTION_STOP_SERVICE == intent.action) {
        stopForeground(true)
        stopSelf()
    } else {
        //Start your task

        //Send forground notification that a service will run in background.
        sendServiceNotification(this)
    }
    return Service.START_NOT_STICKY
}

обрабатывать вашу задачу, когда на уничтожить называется stopSelf().

override fun onDestroy() {
    super.onDestroy()
    //Stop whatever you started
}

создайте уведомление, чтобы служба работала на переднем плане.

//This is from Util class so as not to cloud your service
fun sendServiceNotification(myService: Service) {
    val notificationTitle = "Service running"
    val notificationContent = "<My app> is using <service name> "
    val actionButtonText = "Stop"
    //Check android version and create channel for Android O and above
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        //You can do this on your own
        //createNotificationChannel(CHANNEL_ID_SERVICE)
    }
    //Build notification
    val notificationBuilder = NotificationCompat.Builder(applicationContext, CHANNEL_ID_SERVICE)
    notificationBuilder.setAutoCancel(true)
            .setDefaults(NotificationCompat.DEFAULT_ALL)
            .setWhen(System.currentTimeMillis())
            .setSmallIcon(R.drawable.ic_location)
            .setContentTitle(notificationTitle)
            .setContentText(notificationContent)
            .setVibrate(null)
    //Add stop button on notification
    val pStopSelf = createStopButtonIntent(myService)
    notificationBuilder.addAction(R.drawable.ic_location, actionButtonText, pStopSelf)
    //Build notification
    val notificationManagerCompact = NotificationManagerCompat.from(applicationContext)
    notificationManagerCompact.notify(NOTIFICATION_ID_SERVICE, notificationBuilder.build())
    val notification = notificationBuilder.build()
    //Start notification in foreground to let user know which service is running.
    myService.startForeground(NOTIFICATION_ID_SERVICE, notification)
    //Send notification
    notificationManagerCompact.notify(NOTIFICATION_ID_SERVICE, notification)
}

дайте кнопку остановки на уведомление, чтобы остановить службу, когда пользователь нуждается.

/**
 * Function to create stop button intent to stop the service.
 */
private fun createStopButtonIntent(myService: Service): PendingIntent? {
    val stopSelf = Intent(applicationContext, MyService::class.java)
    stopSelf.action = ACTION_STOP_SERVICE
    return PendingIntent.getService(myService, 0,
            stopSelf, PendingIntent.FLAG_CANCEL_CURRENT)
}

Comments

  1. 222222222
    222222222 5 лет назад
    <p><strong><em>666666666666666666666666666666666666666666666666666666666666666666666</em></strong></p>

    <p> </p>

    <p><strong><em>333333333333333333333333333333333333333333333333333333333333333333333</em></strong></p>

    <p> </p>

    <p><strong><em>000000000000000000000000000000000000000000000000000000000000000000000</em></strong></p>