Saleh Refaai
Saleh Refaai

Reputation: 709

Android Listener stop running when app in background

I am developing an app where the app will detect Bluetooth signals (Sensoro Smart Beacon device) and open the activity. But I want the app to still be able to detect the signal even when the application on the background or even when killed. I used a foreground service, it detects the signal when I open the application and move between activities but when sending the app to the background and opening other applications, the listener stops although the service still working. I am printing the logs. System.out.println("Sensoro 2" ); keeps printing even when I kill the application or open another application. But the printing logs in BeaconManagerListener are not working. I tried to use background service but it didn't work also. Can you please advise if there is a way to make the listener works in a service when the app in background or killed? Here is the service code:

public class MyService extends Service {
    public static final String CHANNEL_ID = "ForegroundServiceChannel";
    int service_timer=0;
    Timer timer = new Timer();
    SensoroManager sensoroManager;
    @Override
    public void onCreate() {
        super.onCreate();
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        sensoroManager = SensoroManager.getInstance(MyService.this);
        String input = intent.getStringExtra("inputExtra");
        System.out.println("Sensoro 2" );
        createNotificationChannel();
        Intent notificationIntent = new Intent(this, MainActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(this,
                0, notificationIntent, 0);
        Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
                .setContentTitle("Foreground Service")
                .setContentText(input)
                .setSmallIcon(R.drawable.ic_launcher_background)
                .setContentIntent(pendingIntent)
                .build();
        startForeground(1,notification);
        //do heavy work on a background thread
        //stopSelf();
                if (sensoroManager.isBluetoothEnabled()) {
                    sensoroManager.setCloudServiceEnable(true);
                    /**
                     * Enable SDK service
                     **/
                    try {
                        sensoroManager.startService();

                    } catch (Exception e) {
                        e.printStackTrace(); // Fetch abnormal info
                    }
                }
                else
                {
                    Toast.makeText(MyService.this,"Bluetooth off",Toast.LENGTH_LONG).show();
                }
        new Timer().scheduleAtFixedRate(new TimerTask() {
            @Override
           public void run() {
                //your method
                System.out.println("Sensoro 2" );


                BeaconManagerListener beaconManagerListener = new BeaconManagerListener() {

                    @Override
                    public void onUpdateBeacon(ArrayList<Beacon> beacons) {
                        // Refresh sensor info
                        for (Beacon beacon : beacons
                        ) {
                            System.out.println("Sensoro 3" );
                           // System.out.println("Sensoro" +beacon.getAccuracy());
                        }
                    }

                    @Override
                    public void onNewBeacon(Beacon beacon) {

                        if (beacon.getSerialNumber().equals("0117C59B243C")){
                            System.out.println("Sensoro 3" );
                            System.out.println("Sensoro acc" +beacon.getAccuracy());
                }
            }

                    @Override
                    public void onGoneBeacon(Beacon beacon) {

                        if (beacon.getSerialNumber().equals("0117C59B243C")){
                            System.out.println("Sensoro acc gone");
                            System.out.println("Sensoro acc Timer" +service_timer);
                        }
                    }
                };
                sensoroManager.setBeaconManagerListener(beaconManagerListener);
            }
        }, 0, 2000);



        return START_NOT_STICKY;
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
       // timer.cancel();
    }
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
    private void createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel serviceChannel = new NotificationChannel(
                    CHANNEL_ID,
                    "Foreground Service Channel",
                    NotificationManager.IMPORTANCE_DEFAULT
            );
            NotificationManager manager = getSystemService(NotificationManager.class);
            manager.createNotificationChannel(serviceChannel);
        }
    }


}

Here is where I call it:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        startService();
        }


    public void startService() {
        Intent serviceIntent = new Intent(this, MyService.class);
        serviceIntent.putExtra("inputExtra", "Foreground Service Example in Android");
        System.out.println("Sensoro 1 ");
        ContextCompat.startForegroundService(this, serviceIntent);
    }
    public void stopService() {
        Intent serviceIntent = new Intent(this, MyService2.class);
        stopService(serviceIntent);
    }


    public void movingg(View view) {
        Intent intent=new Intent(this,Usermain.class);
       startActivity(intent);    }
}

Upvotes: 10

Views: 1120

Answers (5)

Taranmeet Singh
Taranmeet Singh

Reputation: 1239

I see there are two issues with your approach here.

First you should your check for specific beacon serial number could be causing issue.

Secondly you are using a Timer that goes off every 2 seconds and every time it does it adds a new BeaconManagerListener which should not be the case you should extract the listener outside maybe make it a class member and then use the same listener every time instead of continuously creating new listener which then replaces the old one.

Also why add listener after 2 seconds I think is should be added before calling sensoroManager.startService()

Lastly if the task is not needed to be repeated every few seconds and can be done with an interval >= 15 mins then consider using Periodic Work Manager instead.

Upvotes: 0

Pratik Satani
Pratik Satani

Reputation: 1205

This is not 100% a match with what are you searching but this is near to what are you want.

You can use WorkManager that is working even application in the background. There are two types of WorkManager. 1) OneTimeWorkRequest 2) PeriodicWorkRequest.

So you can you PeriodicWorkRequest which will call every 15 min(minimum interval) and you can add your code in WorkManager to detect Bluetooth signals. So you can able to detect Bluetooth single at every 15 mins of intervals.

I hope this will help you solve your problem.

Upvotes: 2

Ali Elahi
Ali Elahi

Reputation: 151

you can use BroadcastReceiver. if your app is killed or in the background ,the broadcast receiver is catch the event of bluetoth

Upvotes: 0

Amir
Amir

Reputation: 212

I looked at the Android rules and regulations page

According to Google documents, from Android 8 onwards, all applications that do not have a Google-approved signature will be removed from the background after a few minutes.

But the solutions:

  1. The first solution is to run the application in debug mode
  2. The second solution is to assign a signature to the application and send it to Google for approval

recommend:

  1. The third solution is to remove the google play service application from the emulator or android phone

Upvotes: 0

Dev
Dev

Reputation: 9

I don't know if this will help you, but here's my answer:

public void startService() {
      Intent serviceIntent = new Intent(this, MyService.class);
      serviceIntent.putExtra("inputExtra", "Foreground Service Example in Android");
      System.out.println("Sensoro 1 ");
      startService(serviceIntent);
  }

Upvotes: 0

Related Questions