1

I need to create simple application that runs always when phone runs. Application should talk to MQTT server and show main window when it gets message from server.

I have created new project with empty activity and text box on it. But how to ask system to start my application when system starts and run it in background?

vico
  • 17,051
  • 45
  • 159
  • 315
  • I think you are looking for WorkManager, https://developer.android.com/topic/libraries/architecture/workmanager – Kartik Shandilya Nov 20 '19 at 11:22
  • I expect you'll need a foreground service, which will require showing a persistent notification in the notification tray. If you aren't concerned about receiving messages immediately then `WorkManager` would be a better option. – PPartisan Nov 20 '19 at 11:33
  • You have a couple of stuffs to study and implement in your code. First is [Boot completed broadcast](https://stackoverflow.com/questions/17226410/android-boot-completed-not-received-when-application-is-closed). Second is [Background loop worker](https://stackoverflow.com/questions/26842675/continue-service-even-if-application-is-cleared-from-recent-app) (or many other links). Then you should [start your activity on event detected] (https://stackoverflow.com/questions/3606596/android-start-activity-from-service). Good luck! – Pier Giorgio Misley Nov 20 '19 at 11:35

3 Answers3

2

Here is a good answer on how to start your service on device boot: Android - Start service on boot

Depending on your needs it can be a good idea to use a Foreground service or a WorkManager. The latest Android SDKs have multiple restrictions on the background services, mainly not on what can be done in the service, but rather how long it can run in the background. Here are some details on that: https://developer.android.com/about/versions/oreo/background

Regarding opening an Activity after an event inside the service. This will not fit well with Android UX guidelines and limitations. Ideally, all UI events/changes should happen only after the user's actions. Here are the guidelines: https://developer.android.com/guide/components/activities/background-starts

For your case, I think the best solution would be to show a notification to the user, clicking which will open your app/activity.

Here you can see how to show a notification from a Service and how to handle user's actions on that notification: https://developer.android.com/training/notify-user/build-notification Sending a notification from a service in Android

0

You will have to make a background service to talk to MQTT server. Then you need to turn that background service into a foreground service, because of the limitations called Background Execution Limits that started from android Oreo.

Please check out this link for more better understanding: https://developer.android.com/about/versions/oreo/background

You should also make the receiver run on boot completed. This can be achieved in the AndroidManifest.

Something like this.

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

Hope this helps you and good luck!

Alex
  • 962
  • 4
  • 15
0

if I understand your request you wanted to create a service that runs in background and to start it at system start :

In manifest add this :

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

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

        }
    }
}

//schedule

 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;
    }
}
MrZ
  • 560
  • 2
  • 12