Need help?

BLE Issues In Android 7 And Above

I had worked with many BLE scanning applications in the previous versions of android. There were no limitations for the scanning time out or scanning in the background.

When I upgraded the old version APK with the latest Android versions I faced some issues like my application is not scanning for a long time in the background, even in the foreground, BLE scanning got stopped after some time.

Here I am trying to explain to you what kind of issues I had faced and how I had solved them:

1. BLE Scanning Issue

During my implementation, I faced one issue that is like BLE scanning is working properly in all devices except Samsung phones with android version 8 or above. In other cases, I was able to scan in Samsung with older android versions like android 6 or below.

As of Android 8, unfiltered Bluetooth scans are blocked when the screen is turned off. The new 8.1 operating system code simply verifies that any scans active when the screen off has at least one scan filter. If those conditions are met the scan results are delivered as in Android 8.0.x and earlier.

Just to resolve this issue you can set a filter with any unique identifier like CompanyId or ManufactureId of your BLE device. And it can also scan only those devices which uniquely identify you have set with filters so that it’ll ignore other random BLE electronic devices.

private BluetoothLeScanner mBluetoothScanner;

private List<ScanFilter> filters;

filters = new ArrayList<>();

settings = new ScanSettings.Builder().setScanMode(

       ScanSettings.SCAN_MODE_LOW_LATENCY).build();

mBluetoothScanner = BluetoothAdapter.getDefaultAdapter().getBluetoothLeScanner();

ScanFilter.Builder builder = new ScanFilter.Builder();

builder.setManufacturerData(“your company id (0x020f

)”, new byte[] {});

ScanFilter filter = builder.build();

filters.add(filter);

mBluetoothScanner.startScan(filters, settings, getInstance()._scanCallback);



2. BLE Scanning Will Stop While App Is Running In The Background From Android 8

Even in the background, I wanted to continue my functionality and I need to show local notifications when some conditions are met. But from Android 8, I was not able to get BLE packets while the app is in the background. Then I read about Doze mode and foreground service which helps me to understand why this is happening and how I can solve this problem.

If your app is running in the background then the user is not able to interact with activity and app Standby allows the system to determine that an app is idle. The system makes this determination when the user does not touch the app for a certain period of time and the app goes to doze mode.

In this type of scenario, the App has some process running in the foreground (either as an activity or foreground service, or in use by another activity or foreground service).

If your app is running in the background then activity interaction is not possible. So There is only one option, that is foreground service. You should start foreground service while the app goes in background and again stop while the app comes to the foreground.

public class MyApplication extends Application implements Application.ActivityLifecycleCallbacks {

   public void onCreate() {

       super.onCreate();

       registerActivityLifecycleCallbacks(this);

   }

   @Override

   public void onActivityResumed(@NonNull Activity activity) {

       if (activity instanceof YourActivity) {

           Intent intent = new Intent(this, ForegroundService.class);

           stopService(intent);

       }

   }

   @Override

   public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) {

       if (activity instanceof YourActivity) {

           if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

               Intent intent = new Intent(this, ForegroundService.class);

               ContextCompat.startForegroundService(this, intent);

           }

       }

   }

   @Override

   public void onActivityDestroyed(@NonNull Activity activity) {

       if (activity instanceof YourActivity) {

           if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

               Intent intent = new Intent(this, ForegroundService.class);

               stopService(intent);

           }

       }

   }

}

public class ForegroundService extends Service {

   @Override

   public void onCreate() {

       super.onCreate();

       createNotification();

   }

   private void createNotification() {

       VulcanUtil.getInstance().setChannelLowImportance(getApplicationContext());

       Notification notification = new NotificationCompat.Builder(this, Constants.CHANNEL_ID_FOREGROUND)

               .setContentTitle(getApplicationContext().getResources().getString(R.string.app_name))

               .setSmallIcon(R.mipmap.ic_notification)

               .setOngoing(true)

               .setCategory(NotificationCompat.CATEGORY_SERVICE)

               .setPriority(Notification.PRIORITY_MIN)

               .build();

       startForeground(101, notification);

   }

   @Override

   public void onDestroy() {

       stopForeground(true);

       stopSelf();

       super.onDestroy();

   }




   @Nullable

   @Override

   public IBinder onBind(Intent intent) {

       return null;

   }

}



A foreground service must provide a notification for the status bar, which is placed under the Ongoing heading. This means that the notification cannot be dismissed unless the service is either stopped or removed from the foreground.

You can check foreground service here:

3. BLE Scanning Will Stop After 30  Mins Even App Is In Foreground

It might be possible that the user is using the application for so long, even more than 30 minutes. But if the user is active on Android 7 or above, then BLE scanning will stop automatically and the user can not see the update after 30 minutes.

Android 7+ will block scanning that lasts for 30 minutes or more without stopping. So if you have a betweenScanPeriod of 0, and you scan for 30 minutes, the operating system will cut off your scan on Android 7or above.

In Beacon Android, version 2.0-2.9 has the above problem with 30 minutes scanning period but in version 2.10 they have resolved this issue and automatically restarted the scanning. So if you are using the Beacon library then you just need to update the library version.

If you are not using the Beacon Android library then you will have to manage by yourself. For that, You can set a handler for 30 minutes which will stop scanning and again start scanning after every 30 minutes.

 

Are You Looking For Bluetooth Low Energy App Development Service

Wrapping Up!

So, if you are updating your app with the latest versions then make sure you are checking all the cases like you are testing your app with latest versions as well as older versions And also you are checking your app in the foreground and background with all the possible cases like the screen on/off.

 

Subscribe To Our Newsletter

Krupa Maradiya

A forward-thinking developer with skills like designing, building integrating, testing, and supporting android mobile applications. Also known for writing efficient, maintainable and reusable code.

Leave a Reply

Your email address will not be published. Required fields are marked *