0

I am aware of the answer here. The solution is to use a broadcast receiver and starting a service inside of it, then registering it in the manifest. The problem is that I am coding in react-native but had to write some native code. I do have a broadcast receiver but its defined inside my ReactContextBaseJavaModule as following:

public class PhonePositionModule extends ReactContextBaseJavaModule {
  public PhonePositionModule(ReactApplicationContext reactContext) {
    super(reactContext);
    BroadcastReceiver phonePositionReceiver = new BroadcastReceiver() {
      @Override
      public void onReceive(Context context, Intent intent) {
        float[] message = intent.getFloatArrayExtra("message");;
        PhonePositionModule.this.sendEvent(message);
      }
    };
    LocalBroadcastManager.getInstance(getReactApplicationContext()).registerReceiver(phonePositionReceiver, new IntentFilter("PhonePosUpdate"));
  } 

What I did is create a new class that extends the broadcast receiver and started the service from there, but I do not like this approach because this means that I am starting a service with two ways (or two different codes).

1) The user starts it by calling a react method:

@ReactMethod
  public void startService(Promise promise) {
    String result = "Success";
    try {
      Intent intent = new Intent(PhonePositionService.FOREGROUND); ///////
      intent.setClass(this.getReactApplicationContext(), PhonePositionService.class);
      getReactApplicationContext().startService(intent);
    } catch (Exception e) {
      promise.reject(e);
      return;
    }
    promise.resolve(result);
  }

2) It starts after boot up by the custom made broadcast receiver:

public class BootCompletedIntentReceiver extends BroadcastReceiver {
 @Override
 public void onReceive(Context context, Intent intent) {
  if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
   Intent pushIntent = new Intent(context, PhonePositionService.class);
   context.startService(pushIntent);
  }
 }
}

I think this is the reason my app crashes somethings on entry. Is there a way to call startService when booting up rather than creating the additional class like above?

Mostafa Arian Nejad
  • 1,278
  • 1
  • 19
  • 32
Sarah cartenz
  • 1,313
  • 2
  • 14
  • 37
  • 1
    `the reason my app crashes` - what is the crash? – brandall Mar 12 '18 at 18:51
  • post your crash detail – Anbarasu Chinna Mar 13 '18 at 07:22
  • the App stops suddenly, no logs are available. But that is not my concern, my concern is that I want to start the service the same way whether its from the react native side or on boot up. In other words, I want to define only one broadcast Receiver, not two. Is there a way? – Sarah cartenz Mar 13 '18 at 09:34
  • if the app stops suddenly it doesn't mean that it crashed, maybe the system (or another app) just killed it – lelloman Mar 13 '18 at 20:52
  • What exactly do you find wrong with the approach? Considering the boot event will not be fired always, it is once in a blue moon when you receive the event and start your service. I don't find anything wrong with this. Even starting an already running service isn't going to cause an issue. Software development is more like doing the things right, not doing the way you like! And I think the way you have done is appropriate, if not the best way to do it! – Rahul Shukla Mar 14 '18 at 00:54

2 Answers2

1

I cannot tell what else is in your code and/or which parts are working and/or which parts are crashing. But your reply to @brandall indicates that you don't care about the crash(es) and just want to use only one Broadcast Receiver. Then, is there a reason why you are not using the same BootCompletedIntentReceiver as the only receiver? Assuming everything is working (or you know how to get them to work), can you just use one receiver and modify the BootCompletedIntentReceiver to filter for PhotoPostUpdate as well, like:

public class BootCompletedIntentReceiver extends BroadcastReceiver { 
 @Override
 //this is your code
 public void onReceive(Context context, Intent intent) {
  if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
   Intent pushIntent = new Intent(context, PhonePositionService.class);
   context.startService(pushIntent);
  }
  //this part is added
  if ("PhonePosUpdate".equals(intent.getAction())) {
    //below is the same code you are using in phonePositionReceiver
    float[] message = intent.getFloatArrayExtra("message");;
    PhonePositionModule.this.sendEvent(message);
  }
 }
}

Or maybe I am misunderstanding the comment/question.

Kaamel
  • 1,852
  • 1
  • 19
  • 25
-1

Try this:

public class BootCompletedIntentReceiver extends BroadcastReceiver {
 @Override
 public void onReceive(Context context, Intent intent) {
    if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
       Intent pushIntent = new Intent(context, PhonePositionService.class);
       pushIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); //New line added
       context.startService(pushIntent);
    }
  }
}

For broadcast receivers you need to sometimes set up flags, yours maybe is one of those cases.