Click here to Skip to main content
13,896,630 members
Click here to Skip to main content
Add your own
alternative version

Stats

45.7K views
46 bookmarked
Posted 29 Apr 2013
Licenced CPOL

Android Services and More

, 13 Mar 2019
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 do not need user interaction while they are being processed.

In this article, with the help of the pre-defined Android Alarm Service, we will create an application that 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, readers should know Java and Android platforms.

Using the Code

Before you start coding, the structure of the application should be clear in the 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 class
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, 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 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 information, 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 are performed in device are broadcasted. It can be imagined as a pool. Whatever an action does, it is information that 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 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 the onReceive() method.

Note: When a BroadcastReceiver is added to project, it is needed to be registered into 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 into vibrate mode.
  2. ToHourAlarmReceiver is responsible to change phone state into 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 is 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 that we wrote must be known by AndroidManifest.xml. To do that, the following code should be added 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>

Note 4: If a service is called when it is already running, probably it will crash. To prevent these 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
With my educational background and personality, I am a multidisciplinary person who has

interest in both computer security and embedded systems.

You may also be interested in...

Pro
Pro

Comments and Discussions

 
QuestionExcellent Article, however zip file is corrupt. Pin
xlr8ed14-Jan-14 13:50
memberxlr8ed14-Jan-14 13:50 
AnswerRe: Excellent Article, however zip file is corrupt. Pin
Safak Tarazan19-Jan-14 22:26
memberSafak Tarazan19-Jan-14 22:26 
QuestionUnable to Download the zip file ! PinPopular
Member 1021205215-Aug-13 9:52
memberMember 1021205215-Aug-13 9:52 
GeneralMy vote of 5 Pin
MythLove52024-May-13 0:24
memberMythLove52024-May-13 0:24 
GeneralMy vote of 5 Pin
Mihai MOGA10-May-13 18:23
professionalMihai MOGA10-May-13 18:23 
QuestionExcellent Pin
MAGAR16-May-13 7:16
memberMAGAR16-May-13 7:16 
GeneralMy vote of 5 Pin
Dheeraj Singh Bhadoria30-Apr-13 0:38
professionalDheeraj Singh Bhadoria30-Apr-13 0:38 
GeneralMy vote of 5 Pin
Sudhakar Shinde29-Apr-13 20:59
memberSudhakar Shinde29-Apr-13 20:59 

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

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

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web04 | 2.8.190306.1 | Last Updated 13 Mar 2019
Article Copyright 2013 by Safak Tarazan
Everything else Copyright © CodeProject, 1999-2019
Layout: fixed | fluid