【问题标题】:How to Create Forground Service Never Stop when Application is Inactive如何在应用程序处于非活动状态时创建前台服务永不停止
【发布时间】:2018-06-08 09:33:59
【问题描述】:

我已经创建了一个应用程序,我想在其中启动服务 第一次打开应用程序。当应用程序在前台时 每 5 或 10 分钟接收一次本地通知。但仅在应用程序处于活动状态或最近的应用程序时收到通知。当清除最近的应用程序时应用通知未收到。我希望此服务继续在设备上运行。

创建服务和启动服务的示例代码: 启动服务:

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

服务:

    public class MyService extends Service {
    final static String TAG = MyService.class.getName();
    ReceiverCall receiverCall;


    private static final int NOTIFICATION_ID = 1;

    MyService (){
        super();
        }
    class Mythread implements Runnable {
        int service_id;

        Mythread(int service_id) {
            this.service_id = service_id;
        }

        @Override
        public void run() {
            int i = 0;
            synchronized (this) {
               // while (i < 10) {
                    try {
                        wait(2500);
                        i++;
                        processStartNotification(String.valueOf(i));
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
               // }
            }
        }
    }

    @Override
    public void onCreate() {
         receiverCall= new ReceiverCall();
            super.onCreate();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        super.onDestroy();
        Toast.makeText(getApplicationContext(), "Service Task destroyed", Toast.LENGTH_LONG).show();


        Intent myIntent = new Intent(getApplicationContext(), MyService.class);
        startService(myIntent);



    }

    @Override
    public void onTaskRemoved(Intent rootIntent) {
        super.onTaskRemoved(rootIntent);
        Intent myIntent = new Intent(getApplicationContext(), MyService.class);
        startService(myIntent);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

      Thread thread = new Thread(new Mythread(startId));
        thread.start();

        return START_STICKY;
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
    private void processStartNotification(String s) {
        // Do something. For example, fetch fresh data from backend to create a rich notification?

        final NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
        builder.setContentTitle("Scheduled Notification")
                .setAutoCancel(true)
                .setColor(getResources().getColor(R.color.colorAccent))
                .setContentText(" Notification Service"+s)
                .setSmallIcon(R.drawable.ic_launcher_background);
        builder.setDeleteIntent(receiverCall.getDeleteIntent(this));
        final NotificationManager manager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
        manager.notify(NOTIFICATION_ID, builder.build());

    }
    }

BroadcastReceiver Class :

    public class ReceiverCall extends BroadcastReceiver {
    private static final String ACTION_START_NOTIFICATION_SERVICE = "ACTION_START_NOTIFICATION_SERVICE";
    private static final String ACTION_DELETE_NOTIFICATION = "ACTION_DELETE_NOTIFICATION";
    private static final int NOTIFICATIONS_INTERVAL_IN_HOURS = 2;
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.i("Service Stops", "Ohhhhhhh");
        context.startService(new Intent(context, MyService.class));
    }
    public static PendingIntent getDeleteIntent(Context context) {
        Intent intent = new Intent(context, ReceiverCall.class);
        intent.setAction(ACTION_DELETE_NOTIFICATION);
        return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    }
    }   

清单声明:

      <service
            android:name=".MyService"
            android:exported="true"
            android:stopWithTask="false"></service>

         <receiver android:name=".ReceiverCall">
            <intent-filter>
                <action android:name="com.servicesex" />
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>

是否可以在应用程序暂停和其他任何情况下始终运行此服务。一段时间后,我的应用程序暂停,服务也暂停或停止。那么如何才能始终在后台运行此服务。

【问题讨论】:

    标签: android google-maps android-fragmentactivity


    【解决方案1】:

    您可以使用警报管理器在特定时间安排未来的任务,并在触发时再次设置。 Sample usage 或新的 api WorkManager 可以帮助运行任务,即使应用程序被杀死。

    但我认为当您的应用程序从系统任务中删除时保持服务运行是一种不好的做法,因为该服务会不断消耗内存和电力。最好关注这个Guideline

    【讨论】:

      【解决方案2】:
      public class MyService extends Service {
      static final int NOTIFICATION_ID = 100;
      
      public static boolean isServiceRunning = false;
      
      @Override
      public void onCreate() {
          super.onCreate();
          startServiceWithNotification();
      }
      
      @Override
      public int onStartCommand(Intent intent, int flags, int startId) {
          if (intent != null && intent.getAction().equals(C.ACTION_START_SERVICE)) {
              startServiceWithNotification();
          }
          else stopMyService();
          return START_STICKY;
      }
      
      // In case the service is deleted or crashes some how
      @Override
      public void onDestroy() {
          isServiceRunning = false;
          super.onDestroy();
      }
      
      @Override
      public IBinder onBind(Intent intent) {
          // Used only in case of bound services.
          return null;
      }
      
      
      void startServiceWithNotification() {
          if (isServiceRunning) return;
          isServiceRunning = true;
      
          Intent notificationIntent = new Intent(getApplicationContext(), MyActivity.class);
          notificationIntent.setAction(C.ACTION_MAIN);  // A string containing the action name
          notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
          PendingIntent contentPendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
      
          Bitmap icon = BitmapFactory.decodeResource(getResources(), R.drawable.my_icon);
      
          Notification notification = new NotificationCompat.Builder(this)
                  .setContentTitle(getResources().getString(R.string.app_name))
                  .setTicker(getResources().getString(R.string.app_name))
                  .setContentText(getResources().getString(R.string.my_string))
                  .setSmallIcon(R.drawable.my_icon)
                  .setLargeIcon(Bitmap.createScaledBitmap(icon, 128, 128, false))
                  .setContentIntent(contentPendingIntent)
                  .setOngoing(true)
      //                .setDeleteIntent(contentPendingIntent)  // if needed
                  .build();
          notification.flags = notification.flags | Notification.FLAG_NO_CLEAR;     // NO_CLEAR makes the notification stay when the user performs a "delete all" command
          startForeground(NOTIFICATION_ID, notification);
      }
      
      void stopMyService() {
          stopForeground(true);
          stopSelf();
          isServiceRunning = false;
      }
      }
      

      C = 必须以包名开头的字符串

      【讨论】:

      • Intent startIntent = new Intent(getApplicationContext(), MyService.class); startIntent.setAction(C.ACTION_START_SERVICE); startService(startIntent);
      • C 是什么意思
      • 这些是必须以包名开头的字符串。
      • public static final String ACTION_START_SERVICE="com.example.rakesh.demo.MainActivity";
      • 应用关闭或kill时没有收到通知
      猜你喜欢
      • 2023-04-02
      • 1970-01-01
      • 2014-03-12
      • 2013-05-08
      • 2018-03-27
      • 1970-01-01
      • 1970-01-01
      • 2020-01-26
      • 1970-01-01
      相关资源
      最近更新 更多