Services and Broadcast Receivers
Services and Broadcast Receivers
Statement Purpose:
Activity Outcomes:
After completing this chapter we will be able to understand the following topics.
- Introduction to Services
- Lifecycle of a Service
- Managing Services
- Introduction to Broadcast Receivers
- Types of Broadcast Receivers
- Creating and Registering Broadcast Receivers
Instructor Note:
Students must read and have best practice of past labs.
Introduction
Introduction to Services
Service can be described as long running background app without any user interface (UI). The services will be running as a separate thread, while any other activity and task is running on fore ground. It can be managed by app component such as activity. While developing android app, we should be able to manage different task simultaneously. For example, playing music in background while playing games. Such simultaneous tasks are managed by services. To interact with services we need to create an activity. For example, service might interact with a content provider, music player and so on. All these tasks will be running in the background.
Forms of Services
Services are used for regularly updating the data source in background. The updated data source is used by activities running on foreground. Services are mainly used for triggering notifications such as email or message arrival. Services are controlled (i.e. Started/stopped) from other android app components such as broadcast receivers, activities and other service components. Services are classified into two types. They are
- Unbound Services
- Bound Services
a) UnBound Service
The unbound service is also known as started service. The startService() method is used to start the service,onces the service is started it will be running in background for indefinite period of time, even if we destroy the started component. Started service performs the intended operation and does not return any result to the caller component.
When we open the game, music starts playing in background automatically till we exit the game.
b) Bound Services
Bound Service can be referred as client–server approach . The bound services allow the app components to interact with each other. It allows the appl components to send request and getresult using inter process communication(IPC). Bound service uses bindService() method to bind with one or more app components. Bound service will be running until another component is bound to it. Multiple components can be binded to the service at a time. The service will be destroyed when the bind components are unbind.
Lifecycle of a Service
The lifecycle of a service can follow two different paths depending on the form of the service, which can be either unbound or bound.
To understand the lifecycle of a service, consider the example like playing games. When we open the game app, an activity is started. During the lifetime of this app, activity may invoke a service.
i.e. service to enable or disable the music by changing the game or exiting the game. If user exits the game app, all service components acquired by the app are released and destroyed.
Lifecycle of UnBound (Started) Service
To invoke the service component startService() method need to be called. Once the service is started, it is running in background for indefinite period of time :
- The service stops itself by calling the stopSelf()
- Another app component stops the service by calling the stopService() When a service is stopped, when the system destroys service components and its resources.
The figure depicts the Callback method Executed during the Lifecycle of a started service or unbound service. Lifecycle of Bound Service We can create bound service from another components by calling bindService() method. While calling the bindService() method, the service is bind to the components. We can bind multiple components with a service. Bound services communicate through IBinder interface. It can be unbind by calling unbindService() method. Service need not to be explicitly stopped, it is automatically stopped and destroy all
the resources which are bind to that service component. Stopping services automatically, is a good practice in app development because if a service is not stopped itself, optimization of resources cannot be achieved.
Starting a Service
When the service component call the startService() method, it will check whether the service is running or not, if service is not running the android system will call onCreate() method, if service is already running in background then android system will call onStartCommand() method.When multiple components start a service, thay call onStartcommand() method then each start request is called individually.
The service will start running after receiving request from the component. It will continue running, until it stopSelf() or stopService() method is called. We have to note one point that even multiple requests made to the startService() method, the call to the startService() method will not be nested. No matter how many requests or calls to the startService() method made, but the service will be stopped once the stopService() or stopSelf() method is called. . In bound service, the component that starts the service can create a Pendinglntent[it is a token that is given to another app (e.g. NotificationManager, AlarmManager, Home Screen AppWidgetManager), which allows that app to use current app‘s permissions to execute a predefined piece of code] object and pass this intent object to the caller service components. The service can then use this object to send a result back to the calling component.
Stopping a Service
As discussed previously service is independent block of code, it needs to be manage its own lifetime. The service will be running in the background until android platform regain the memory occupied by the service. When service is ideal for long time, it has to be stopped by itself by calling stopSelf() callback method. To destroy the service explicitly we need to call the stopServcie(Intent Service) callback method. Unlike the onStartCommand() method, only one call to the stopService or stopSelf() method destroys the service.
Introduction to Broadcast Receivers
In an android device, broadcast message is generated, to inform the currently running app that certain event has occurred.
Broadcasts can be generated in two ways:
The system-level event broadcast:
The broadcast message generated by the system is known as system-level event broadcast, such as the screen is being turned off, the battery is low, or an SMS has arrived.
An app-level event broadcast:
The broadcast message generated by an app is known as app-level event broadcast, For example, an app that is downloading some data may want to inform other apps that the
data has been downloaded and ready to use. By using app-level event broadcast, we can inform other apps that some event has occurred. This can be achieved using a broadcast receiver, which enables the apps to register themselves to receive a notification whenever a new feed is available.
Normal Broadcasts
The broadcasts messenger sends message in undefined order to all the registered receivers at the same time. For example, the broadcasts, such as battery low (ACTION_BATTERYLOW) or timezone changed (ACTION_TIMEZONE_CHANGED) will be received by all the registered receivers at the same time. This type of broadcasts are sent using the sendBroadcast() method of the android.content.Context class.
Ordered Broadcasts
The broadcast messenger sends message to all the registered receivers in an ordered manner, which means that a broadcast is delivered to one receiver at a time. When a receiver receives a broadcast, it can either propagate the broadcast to the next receiver or it can completely abort the broadcast. If a broadcast message is aborted by a receiver, it will not be passed to other receivers.
Creating and Registering a Broadcast Receiver
- Creating the Broadcast Receiver
Each broadcast is delivered in the form of an intent object. Broadcast receivers enable apps to receive intents object that are either broadcasted by the system or by other apps. A broadcast receiver is implemented as a subclass of Broadcast Receiver class and overriding the onReceive() method where each message is received as a Intent object parameter.
The onReceive() method is called when a broadcast receiver receives a broadcast intent object. This method must include the code that needs to be executed when a broadcast is received. This method is usually called within the main thread of its process. Therefore, we should not perform long-running operations in this method. The system allows a timeout of 10 seconds before considering the receiver to be blocked. The system can kill a receiver that has been blocked. Also, we cannot launch a pop-up dialog in our onReceive ( ) method implementation. The signature of the onReceive () method is:
public abstract void onReceive (Context context, Intent intent)
Registering a Broadcast Receiver
To register the broadcast receiver, app‘s broadcast intent has to be registered in AndroidManifest.xml file.
To declare a broadcast receiver in the manifest file, you need to add a <receiver> element as a child of the <application> element by specifying the class name of the broadcast receiver
to register. The <receiver> element also needs to include an <intent-filter> element that specifies the action string being listened for.
Broadcaster receivers can be registered by either one the two methods.
- Statically
- Dynamically
By using the method registerReceiver() a broadcast receiver is registered dynamically. If the manifest file is used for registering the broadcast receiver, it is known as static method.
Dynamic Registering
We can register a broadcast receiver using the registerReceiver() method. The registerReceiver() method is called with a broadcast intent that matches the filter in the main app thread. The signature of the registerReceiver() method is :
public abstract Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter)
Activities:
Activity 1:
Creating a New project:
- Open Android Studio and then click on File -> New -> New project.
- Then type the Application name as “no.11″ and click Next.
- Then select the Minimum SDK as shown below and click Next.
- Then select the Empty Activity and click
- Finally click Finish.
- It will take some time to build and load the
- After completion it will look as given
Creating Second Activity for the Android Application:
- Click on File -> New -> Activity -> Empty
- Type the Activity Name as AlarmReceiver and click Finish
- Thus Second Activity For the application is created.
Designing layout for the Android Application:
- Click on app -> res -> layout -> xml.
- Now click on Text as shown
- Then delete the code which is there and type the code as given
Code for Activity_main.xml:
<?xml version=”1.0″ encoding=”utf-8″?>
<LinearLayout android:layout_width=”match_parent” android:layout_height=”match_parent” android:orientation=”vertical”>
<TimePicker
android:id=”@+id/timePicker” android:layout_width=”wrap_content” android:layout_height=”wrap_content” android:layout_gravity=”center” />
<ToggleButton
android:id=”@+id/toggleButton” android:layout_width=”wrap_content” android:layout_height=”wrap_content” android:layout_gravity=”center” android:layout_margin=”20dp” android:checked=”false” android:onClick=”OnToggleClicked” />
</LinearLayout>
- Now click on Design and your application will look as given
- So now the designing part is
Changes in Manifest for the Android Application: Click on app ->
manifests -> AndroidManifest.xml
- Now change the activity tag to receiver tag in the xml file as shown below
Code for AndroidManifest.xml:
<?xml version=”1.0″ encoding=”utf-8″?>
<manifest package=”com.example.exno11″ >
<application
android:allowBackup=”true” android:icon=”@mipmap/ic_launcher” android:label=”@string/app_name” android:supportsRtl=”true” android:theme=”@style/AppTheme” >
<activity android:name=”.MainActivity” >
<intent-filter>
<action android:name=”android.intent.action.MAIN” />
<category android:name=”android.intent.category.LAUNCHER” />
</intent-filter>
</activity>
<receiver android:name=”.AlarmReceiver” >
</receiver>
</application>
</manifest>
- So now the changes are done in the
Java Coding for the Android Application:
Java Coding for Main Activity:
- Click on app -> java -> example.exno11 -> MainActivity.
- Then delete the code which is there and type the code as given
Code for MainActivity.java:
package com.example.exno11;
import android.app.AlarmManager; import android.app.PendingIntent; import android.content.Intent; import android.os.Bundle;
import android.support.v7.app.AppCompatActivity; import android.view.View;
import android.widget.TimePicker; import android.widget.Toast;
import android.widget.ToggleButton; import java.util.Calendar;
public class MainActivity extends AppCompatActivity
{
TimePicker alarmTimePicker; PendingIntent pendingIntent; AlarmManager alarmManager;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);
alarmTimePicker = (TimePicker) findViewById(R.id.timePicker); alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
}
public void OnToggleClicked(View view)
{
long time;
if (((ToggleButton) view).isChecked())
{
Toast.makeText(MainActivity.this, “ALARM ON”, Toast.LENGTH_SHORT).show();
Calendar calendar = Calendar.getInstance(); calendar.set(Calendar.HOUR_OF_DAY,
alarmTimePicker.getCurrentHour());
calendar.set(Calendar.MINUTE, alarmTimePicker.getCurrentMinute());
Intent intent = new Intent(this, AlarmReceiver.class); pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
time=(calendar.getTimeInMillis()- (calendar.getTimeInMillis()%60000));
if(System.currentTimeMillis()>time)
{
if (calendar.AM_PM == 0)
time = time + (1000*60*60*12);
else
}
time = time + (1000*60*60*24);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, time, 10000, pendingIntent);
}
else
{
alarmManager.cancel(pendingIntent); Toast.makeText(MainActivity.this, “ALARM OFF”,
Toast.LENGTH_SHORT).show();
}
}
}
- So now the Coding part of Main Activity is
Java Coding for Alarm Receiver:
- Click on app -> java -> example.exno11 -> AlarmReceiver.
- Then delete the code which is there and type the code as given
Code for AlarmReceiver.java:
package com.example.exno11;
import android.content.BroadcastReceiver; import android.content.Context;
import android.content.Intent; import android.media.Ringtone;
import android.media.RingtoneManager; import android.net.Uri;
import android.widget.Toast;
public class AlarmReceiver extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent)
{
Toast.makeText(context, “Alarm! Wake up! Wake up!”, Toast.LENGTH_LONG).show();
Uri alarmUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
if (alarmUri == null)
{
alarmUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
}
Ringtone ringtone = RingtoneManager.getRingtone(context, alarmUri); ringtone.play();
}
}
- So now the Coding part of Alarm Receiver is also completed.
- Now run the application to see the
Output:
Result:
Thus Android Application that creates Alarm Clock is developed and executed successfully.
Home Activities:
Activity 1:
Auto alarm generator for next hour.