服务应用程序在后台运行

时间:2019-11-20 11:19:32

标签: android

我需要创建一个在手机运行时始终运行的简单应用程序。应用程序应该与MQTT服务器通信,并在从服务器获取消息时显示主窗口。

我创建了一个新项目,上面有空的活动和文本框。但是,如何要求系统在系统启动时启动我的应用程序并在后台运行它?

3 个答案:

答案 0 :(得分:2)

关于如何在设备启动时启动服务,以下是一个很好的答案: Android - Start service on boot

根据您的需求,最好使用前景服务或WorkManager。最新的Android SDK对后台服务有多个限制,主要不是在服务中可以做什么,而是可以在后台运行多长时间。以下是一些详细信息: https://developer.android.com/about/versions/oreo/background

关于在服务内部发生事件后打开活动。这不太适合Android UX准则和限制。理想情况下,所有UI事件/更改都应仅在用户的操作之后发生。以下是准则: https://developer.android.com/guide/components/activities/background-starts

对于您而言,我认为最好的解决方案是向用户显示通知,单击该通知将打开您的应用/活动。

在这里,您可以查看如何显示来自服务的通知以及如何处理用户对该通知的操作: https://developer.android.com/training/notify-user/build-notification Sending a notification from a service in Android

答案 1 :(得分:0)

您将必须提供后台服务才能与MQTT服务器对话。然后,由于从Android Oreo开始的称为“后台执行限制”的限制,您需要将该后台服务转换为前台服务。

请查看此链接以进一步了解:https://developer.android.com/about/versions/oreo/background

您还应该使接收器在启动时完成运行。这可以在AndroidManifest中实现。

这样的事情。

<receiver android:name="com.example.StartUpBootReceiver" android:enabled="true" android:exported="true">
    <intent-filter>
         <action android:name="android.intent.action.BOOT_COMPLETED" />
         <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>            
</receiver>

希望这对您有帮助,祝您好运!

答案 2 :(得分:0)

如果我理解您的请求,那么您想创建一个在后台运行并在系统启动时启动的服务:

在清单中添加以下内容:

  <receiver
            android:name=".StartSysytemReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <action android:name="android.intent.action.QUICKBOOT_POWERON" />
            </intent-filter>
  </receiver>

创建您的BroadcastReceiver:

public class StartSysytemReceiver extends BroadcastReceiver {

    private static final String BOOT_COMPLETED = "android.intent.action.BOOT_COMPLETED";
    private static final String QUICKBOOT_POWERON = "android.intent.action.QUICKBOOT_POWERON";


    @Override
    public void onReceive(Context context, Intent intent) {
        if (BOOT_COMPLETED.equals(intent.getAction()) ||
                QUICKBOOT_POWERON.equals(intent.getAction())) {


            //schedule your  background service 
            scheduleJob(context);

        }
    }
}

//时间表

 public  void scheduleJob(Context context) {
            FirebaseJobDispatcher dispatcher = new FirebaseJobDispatcher(new GooglePlayDriver(context));
            RetryStrategy retryStrategy = dispatcher.newRetryStrategy(2, 300, 1800);
            Builder jobBuilder = dispatcher.newJobBuilder().setService(BackgroundJobService.class)
           .setTag("scheduleJob_112").setReplaceCurrent(true)
           .setRecurring(false).setLifetime(2)
           .setRetryStrategy(retryStrategy).setConstraints(new int[]{2});
            Job myJob = jobBuilder.build();
            dispatcher.mustSchedule(myJob);
          }

// backgroundJobService

public class BackgroundJobService extends JobService {
    private static final String TAG = "BackgroundJobService";
    boolean isWorking = false;
    boolean jobCancelled = false;

    public BackgroundJobService () {
    }

    public boolean onStartJob(JobParameters jobParameters) {
        this.isWorking = true;
         this.doWork(jobParameters);
        return this.isWorking;
    }

    private void doWork(JobParameters jobParameters) {
        if (!this.jobCancelled) {
          //callYour service her
            this.getBaseContext().startService(new Intent(this.getBaseContext(), ServiceToCall.class));
            this.isWorking = false;
            this.jobFinished(jobParameters, true);
        }
    }

    public boolean onStopJob(JobParameters jobParameters) {
        this.jobCancelled = true;
        boolean needsReschedule = this.isWorking;
        this.jobFinished(jobParameters, this.isWorking);
        return needsReschedule;
    }
}