Click here to Skip to main content
Click here to Skip to main content

Android Services and More

, 29 Apr 2013 CPOL
Rate this:
Please Sign up or sign in to vote.
Usage of services, alarm manager and broadcast receivers.

Introduction

Almost in all platforms there are lots of pieces of process running background and they are called services. Likely, in Android platform there are services to perform longer-running operations that not need user interaction while they are being processing.  

In this article, with the help of the pre-defined Android Alarm Service, we will create an application that’s changes the telephone mode to vibrate mode in the desired time interval. In addition to this, we will write our own Service class and call it on specific time. Moreover the following questions will be answered by this demo application:

  • How to use Alarm Manager?
  • How to start an Intent by Alarm Manager?
  • How to use BroadcastReceiver?
  • How to use Services?
  • How to register services and receivers to the AndroidManifest.xml?
  • How to change phone ringer mode?

Background

To understand this article, reader should know the Java and Android platform.

Using the Code

Before start coding, the structure of the application should be clear on coder’s mind. For this demo application we may follow the simple steps shown below:

  1. Get the time interval from user on the MainActivity
  2. According to time intervals, set the Alarm to broadcast it
  3. Write BroadcastReceivers to receive the alarm and perform your operation or call a service.

In this demo, there are 4 classes:

MainActivity             // main calss

FromHourAlarmReceiver    //BroadcastReceiver

ToHourAlarmReceiver      //BroadcastReceiver

MyService                //Service Class

1-Getting the Time Intervals From User In MainActivity

a) MainActivity.class

public class MainActivity extends Activity {

 private EditText editText1;    //create the objects
 private EditText editText2;
 private Button btn1;
 private int hourFrom;
 private int hourTo;
             
       @Override
       protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
         
          editText1 = (EditText) findViewById(R.id.editText1); //bind the object
          editText2 = (EditText) findViewById(R.id.editText2);
          btn1 = (Button) findViewById(R.id.btn1);
                      
          btn1.setOnClickListener(new OnClickListener() { //click listener for btn
                
                 @Override
                 public void onClick(View v) {
          });
       }
 
       @Override
       public boolean onCreateOptionsMenu(Menu menu) {
          // Inflate the menu; this adds items to the action bar if it is present.
          getMenuInflater().inflate(R.menu.main, menu);
          return true;
       }
 
}

b) main_activity.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    tools:context=".MainActivity" >
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Enter The Desired Time Interval For To Changed In Vibrate Mode" />
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="From (24 Hour Format)" />
    <EditText
        android:id="@+id/editText1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:numeric="integer"
        />
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="To (24 Hour Format)" />
    <EditText
        android:id="@+id/editText2"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:numeric="integer"
        />
    <Button
        android:id="@+id/btn1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Set the Service"/>
 
</LinearLayout>

2-According to Intervals Setting the Alarm Manager

Before creating the Alarm Manager we need to create our intents to call them by AlarmManager:

Intent intent1 = new Intent(getBaseContext(), FromHourAlarmReceiver.class);
final PendingIntent sender1 = PendingIntent.getBroadcast(this, 192837, intent1, PendingIntent.FLAG_UPDATE_CURRENT);

Intent intent2 = new Intent(getBaseContext(), ToHourAlarmReceiver.class);
final PendingIntent sender2 = PendingIntent.getBroadcast(this, 192837, intent2, PendingIntent.FLAG_UPDATE_CURRENT);

In here, Intent is the name of the operation to be performed. Since we will call a class, FromHourAlarmReceiver, that class needs to know what’s going on, why it’s called, who is the caller and etc. For this reason we need to send the context by the Intent object [1].

There is another term called PendingIntent here and this has 2 important points. The first one indicates that the intent that we wrote is going to start later. The second is by using PendingIntent we tell android platform that we are communicating with 3rd party application or services on android platform. In this demo that is AlarmManager Service. (For more info please check http://developer.android.com/reference/android/app/PendingIntent.html)

We have created two intents because we will set 2 alarms, the first one will change the phone state into vibrate mode and the other will change it to normal mode. So we need 2 calendar objects to set the time.

Calendar cal1 = Calendar.getInstance();
cal1.set(Calendar.HOUR,hourFrom);
                                  
Calendar cal2 = Calendar.getInstance();
cal2.set(Calendar.HOUR,hourTo);

After we have all the objects and information to set the alarm:

AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);am.set(AlarmManager.RTC_WAKEUP,
cal1.getTimeInMillis(), sender1);am.set(AlarmManager.RTC_WAKEUP,
cal2.getTimeInMillis(), sender2);

Finally our MainActivity will look like this:

public class MainActivity extends Activity {

 private EditText editText1;
 private EditText editText2;
 private Button btn1;
 private int hourFrom;
 private int hourTo;
             
   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
     
      editText1 = (EditText) findViewById(R.id.editText1);
      editText2 = (EditText) findViewById(R.id.editText2);
      btn1 = (Button) findViewById(R.id.btn1);
     
       Intent intent1 = new Intent(getBaseContext(), FromHourAlarmReceiver.class);
       final PendingIntent sender1 = PendingIntent.getBroadcast(
         this, 192837, intent1, PendingIntent.FLAG_UPDATE_CURRENT);
       
       Intent intent2 = new Intent(getBaseContext(), ToHourAlarmReceiver.class);
       final PendingIntent sender2 = PendingIntent.getBroadcast(
         this, 192837, intent2, PendingIntent.FLAG_UPDATE_CURRENT);
     
      btn1.setOnClickListener(new OnClickListener() {
            
             @Override
             public void onClick(View v) {
                  
             try{
                   hourFrom = Integer.parseInt(editText1.getText().toString());
                   hourTo = Integer.parseInt(editText2.getText().toString());
             } catch(Exception e){}
                   if((0<hourFrom&&hourFrom<24)&&
                             (0<hourTo&&hourTo<24)){
                         
                       Calendar cal1 = Calendar.getInstance();
                       cal1.set(Calendar.HOUR,hourFrom);
                       
                       Calendar cal2 = Calendar.getInstance();
                       cal2.set(Calendar.HOUR,hourTo);
                       
                       AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
                       am.set(AlarmManager.RTC_WAKEUP, cal1.getTimeInMillis(), sender1);
                        am.set(AlarmManager.RTC_WAKEUP, cal2.getTimeInMillis(), sender2);

                       Toast.makeText(getBaseContext(), 
                         "Phone Mode Will Be Changed Automatically !",Toast.LENGTH_LONG).show();
                   }
                   else{
                      Toast.makeText(getBaseContext(), 
                        "Please enter hour in between 1-23 !",Toast.LENGTH_LONG).show();
                   }     
             }
      });
   }
 
   @Override
   public boolean onCreateOptionsMenu(Menu menu) {
      // Inflate the menu; this adds items to the action bar if it is present.
      getMenuInflater().inflate(R.menu.main, menu);
      return true;
   }
}

3-Implementation of the BroadcastReceivers

In android platform almost all the actions that performed in device are broadcasted. It can be imagined as a pool. Whatever an action does, it is information is sent in to that pool. So that, you can check what’s going on in the device and perform your operations according to them.

In our demo, the AlarmManager will broadcast that there is an alarm is going on and to catch this alert, we need to write a BroadcastReceiver as shown below:

public class FromHourAlarmReceiver extends BroadcastReceiver{
   @Override
   public void onReceive(Context context, Intent intent) {
      }
}

The desired operations can be performed in tie onReceive() method.

Note: When a BroadcastReceiver is added to project, it is needed to be registered in to the AndroidManifest.xml. The following code is for that:

<receiverandroid:process=":remote" android:name="FromHourAlarmReceiver"></receiver>
<receiverandroid:process=":remote" android:name="ToHourAlarmReceiver"></receiver>

So we have 2 BroadcastReceivers:

  1. FromHourAlarmReceiver is responsible to change phone state in to vibrate mode.
  2. ToHourAlarmReceiver is responsible to change phone state in to normal mode.

FromHourAlarmReceiver.class

public class FromHourAlarmReceiver extends BroadcastReceiver{

   @Override
   public void onReceive(Context context, Intent intent) {
      AudioManager am= (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
      am.setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
      Toast.makeText(context, "Phone Mode Is Changed to Vibrate Mode", Toast.LENGTH_LONG).show();
   }
}

ToHourAlarmManager.class

public class ToHourAlarmReceiver extends BroadcastReceiver{

   @Override
   public void onReceive(Context context, Intent intent) {
      AudioManager am= (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
      am.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
      Toast.makeText(context, "Phone Mode Is Changed to Normal Mode", Toast.LENGTH_LONG).show();
      Log.d("warnning", "something is happend...");
   }
}

Note 2: When an alarm alert received by a BroadCastReceiver, you may call your own service class as shown below:

Intent myServiceIntent = new
Intent(context,MyService.class);
context.startService(myServiceIntent);

Note 3: Don’t forget to register the Service class to AndroidManifest.xml :

<service class=".MyService" android:name="MyService">
 <intent-filter>
   <action android:value="com.javaorigin.android.sample.service.MY_SERVICE"
           android:name=".MyService" />       
 </intent-filter>
</service>

MyService.class

public class MyService extends Service{

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

    }

    @Override
       public int onStartCommand(Intent intent, int flags, int startId) {
           Toast.makeText(getApplicationContext(), 
            "*** I am called by BroadcastReceiver ***", Toast.LENGTH_LONG).show();
                 return startId;
    }
     @Override
      public void onDestroy() {
          super.onDestroy();  
      }
   @Override
   public IBinder onBind(Intent arg0) {
          // TODO Auto-generated method stub
          return null;
   }
}

2. Registration of the Service Class

As known, AndroidManifest.xml is responsible for all permissions, services, intents, and so on. So the service is that we wrote must be known by AndroidManifest.xml. To do that, the following code should be added to AndroidManifes.xml:

<service class=".MyService" android:name="MyService">
 <intent-filter>
   <action android:value="com.javaorigin.android.sample.service.MY_SERVICE"
           android:name=".MyService" />       
   </intent-filter>
</service>

Note 4: If a service is called when it is already running, probably it will crash. To prevent this kind of errors, please check the flag types of the onStartCommand method.

Node 5: Most the system application services are not visible to user. If you want to write an invisible service, you should make your "apk" as if it is a system application.

References 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Safak Tarazan
Software Developer Information Technologies
Turkey Turkey
No Biography provided

Comments and Discussions

 
QuestionExcellent Article, however zip file is corrupt. Pinmemberxlr8ed14-Jan-14 14:50 
AnswerRe: Excellent Article, however zip file is corrupt. PinprofessionalSafak Tarazan19-Jan-14 23:26 
QuestionUnable to Download the zip file ! PinmemberMember 1021205215-Aug-13 10:52 
GeneralMy vote of 5 PinmemberMythLove52024-May-13 1:24 
GeneralMy vote of 5 PinmemberMihai MOGA10-May-13 19:23 
QuestionExcellent PinmembervJjurado6-May-13 8:16 
GeneralMy vote of 5 PinmemberDheeraj Singh Bhadoria30-Apr-13 1:38 
GeneralMy vote of 5 PinmemberSudhakar Shinde29-Apr-13 21:59 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.1411019.1 | Last Updated 29 Apr 2013
Article Copyright 2013 by Safak Tarazan
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid