Android 8.0 Behavior Changes

Android 8.0 Behavior Changes

Introduction:

As everyone knows, a lot of changes made after API level 26 for optimizing Android system’s performance, the battery uses and other system-level problems which I am writing below:

1- Changes in Service.
2- Changes in Broadcast Reciever.
3- Changes in Push Notification

1-Changes in Broadcast Reciever:

So before understanding the changes in broadcast receiver let’s first understand two types of broadcast receivers in Android.

Implicit BroadCast Reciever: BroadCast Reciever that is provided by Android system like CONNECTIVITY_CHANGE, ACTION_BATTERY_LOW.

Explicit BroadCast Receiver: BroadCast Receiver which is created by the user by extending Broadcast Receiver class is Explicit BroadCast Reciever.

Now next thing is that you can register Broadcast Receiver in Android using two ways first using java code and second is in manifest.xml file. The difference is when you declare Broadcast Receiver using java code then this will not be triggered when your app is closed but if you declare in manifest.xml then this will be triggered even if your app is not running.

So after Oreo, you can not declare every implicit broadcast receiver in manifest.xml (Note: Not every Broadcast Reciever but few of them you can declare) and Android gives you a list of the implicit broadcast receiver which you can declare in manifest.xml even after Oreo. Besides that list, you can not declare any implicit broadcast receiver in manifest.xml file.

Ex- ACTION_LOCKED_BOOT_COMPLETED, ACTION_BOOT_COMPLETED

Android allows these broadcast because they are sent only once when system boot and too many apps need to receive this broadcast to schedule alarm, jobs and so forth.

List of implicit Broadcast Reciever allowed after oreo.

Reason: If you register an app to receive broadcast then the app’s receiver consumes resources every time the broadcast is sent. If too many apps are registered to receive broadcast then this can cause problems because every apps receiver consumes resources and it also impacts the user experience.

2-Changes in Service:

The main changes after Oreo are that Background Service is not allowed, only foreground service is allowed. First, let’s understand when services are considered as background service :

Case 1: When you start a service and put the app in the background and the user is not aware of your service.

Case 2: Your app is in the background and you are starting a service, eg an alarm manager which gives you a callback and you start a service.

In the above-mentioned cases, these services will be considered as background services. So if you run a background service then Android will kill your service after a certain amount of time, but remember if you are using your app means your app is in foreground then service will not be killed.

Reason:  After Oreo background service is not allowed because the developer’s start their services and the work done by the service gets completed, but the service still keeps running.  This leads to degradation in device performance and drains the battery. As I have mentioned above, there is no more background service after Oreo so you might think about the alternatives for it. Below I have stated the alternatives:

(a)-Foreground Service: Foreground service is if the user is aware that the service is running like displaying a notification attached to service for example in Ganna music application you will always see a notification while a song is playing.

(b)-Job Service: Another alternative for the background service is to use Job service which is similar to service but the difference is that it is not in your hands to start it. You will just create your JobService object and give this to Job Scheduler and Job scheduler will start this service when it will see that the resources are free. You can not force JobShedular to start your Job Service immediately, but you can just request the Job Scheduler to start in some specific time which is shown in the example below. JobShedular is similar to ThreadShedular and JobService is similar to Thread. You can also define different event for starting your job service. For example, the service will start when the device is connected to the internet or it is charging. You can also call Job Service as a combination of BroadCast Reciever and Service.

Events that you can attach with your Job Service.

//ExampleJobService code
public class PracticeJobService extends JobService
{
    @Override
    public boolean onStartJob(JobParameters params)
    {
        //Start here your thread and do your task
        return true;
    }

    @Override
    public boolean onStopJob(JobParameters params) {

        Log.d(TAG, "Your Job Stoped");
        return true;
    }
}
//MainActivity Code put this method in on create of your activiy.  
 public void scheduleJob()
{
        ComponentName componentObject = new ComponentName(this, PracticeJobService .class);

        JobInfo jobInfoObject = new JobInfo.Builder(101, componentObject )
                .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)//run when you connected to wifi
                .setPersisted(false)//also alive if you rebot you phone
                .setRequiresCharging(true) //Run when charging connect
                .setPeriodic(10 * 60 * 1000) //Request JobShedular to start with in this time it just a request JobShedular can also ignore this.
                .build();

        JobScheduler schedulerObject = (JobScheduler) getSystemService(JOB_SCHEDULER_SERVICE);
        int resultCodeValue = schedulerObject .schedule(jobInfoObject);
        if (resultCodeValue == JobScheduler.RESULT_SUCCESS) {
            Log.d(TAG, "Your Job scheduled");
        } else {
            Log.d(TAG, "Job scheduling failed");
        }
    }

    public void cancelJob() {
        JobScheduler jobSchedulerObject = (JobScheduler) getSystemService(JOB_SCHEDULER_SERVICE);
        jobSchedulerObject.cancel(101);
        Log.d(TAG, "Your Job cancelled");
    }

And now this will run even if your app is in the background.

Let’s understand some important things related to Service with the following points:

(I)- You start a Service with start service () method when your app is running means app is in foreground then Service will not be killed in any case.

(II)- When you are starting your Service with startService() method then in onStartCommand method of Service class,  call startForground() method and give a notification object and now a notification will show as long your Service will be running. As I have told you above after Oreo for displaying a notification please create a channel for notification. I will suggest you create the channel in the Application file of the project. The use of this notification channel is explained below.

@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
    //Get some value pass by intent
    String data= intent.getStringExtra("intentExtraInput");
    //Intent object
    Intent intentOject = new Intent(this, MainActivity.class);
    //Pending Intent object
    PendingIntent pendingIntentObject = PendingIntent.getActivity(this,
            0, intentOject , 0);
    //Notification Object
    Notification myNotificationObject = new NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle("My Foregorund Service")
            .setContentText(data)
            .setSmallIcon(R.drawable.ic_android_icon)
            .setContentIntent(pendingIntentObject)
            .build();
    //Start foreground method
    startForeground(1, myNotificationObject);
    //its for what happen with your when application is killed
    return START_NOT_STICKY;
}

Now, this is your foreground Service but If you will not call startForeground() method from onStartCommand() method and put your app in the background then after some Android will kill your Service.

(III)-You can use not StartService() method when your app is in the background after Oreo if you call this then Android will through IllegalStateException.

(IV)-If you are starting a Service when your app is in the background then use startForegroundService() method, and one more thing after calling startService() Method Android will give you 5 seconds to call startForeground() method from onStartCommand().If within 5 seconds you call this method then Android will continue your Service otherwise after 5 seconds it will be killed.

Note: Always use ContextCompat class and it will handle conditions related to Android version.

ContextCompat.startForegroundService(this, serviceIntent)

public static void startForegroundService(@NonNull Context context, @NonNull Intent intent)
{
    if (VERSION.SDK_INT < 26)
    {
       context.startService(intent);
    } 
    else
    {
      context.startForegroundService(intent);
    }
}


3-Changes in Notification:

After Oreo, you can divide your app’s notifications into channels. You can set different behavior on different channels. All notifications that are posted to the same channel have the same behavior. For example, I can create a channel for the most urgent notifications. By using the channel, every notification will have a different sound, vibration or a notification light. You can create more channels like this and can customize according to your requirements. So after Oreo, you have more control over your notifications.

We have one more chance after Oreo which are notification dots. Now after Oreo if your notifications appear then you will see dots or badges on app launcher icons. So for now if you want to know for a particular application if you have gotten a new notification then you can check the dots displayed along with the application’s icon. I will suggest you create notification channel in Application class of project like given in the code below-

public class MyApplication extends Application {
    public static final String NOTIFICATION_CHANNEL_ID = "exampleServiceChannel";

    @Override
    public void onCreate() {
        super.onCreate();

        createChannelForPushNotification();
    }

    private void createChannelForPushNotification() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channelObject = new NotificationChannel(
                    NOTIFICATION_CHANNEL_ID,
                    "Example Service Channel",
                    NotificationManager.IMPORTANCE_DEFAULT
            );
            //set the light for notification
            channelObject.setLightColor(Color.RED);
            //set the light with enable or not
            channelObject.enableLights(true);
            //Set vibration enable or not 
            channelObject.enableVibration(true);
          

            NotificationManager manager = getSystemService(NotificationManager.class);
            manager.createNotificationChannel(channelObject);
        }
    }
}

Now your notification channel is created with channel id “exampleServiceChannel” , you will use this channel id when you create you notification builder object like below:

Notification notificationObjet = new NotificationCompat.Builder(this, CHANNEL_ID)
        .setContentTitle("My Push Notificaion")
        .setContentText(input)
        .setSmallIcon(R.drawable.ic_android_icon)
        .setContentIntent(pendingIntentObject)
        .build();

Conclusion: I have tried to cover each and every point related to changes in Push Notification, Service and BroadCast Reciever after Oreo. I hope the concepts are easy to grasp and in case of any mistakes please feel free to comment below.

InnovationM is a globally renowned mobile app development company in India that caters a robust & secure Android app development, iOS app development, hybrid app development services. Our commitment & engagement towards our target gives us brighter in the world of technology and has led us to establish success stories consecutively. InnovationM is the top Android app development company in India.

Thanks for giving your valuable time. Keep reading and keep learning.

Leave a Reply