How to implement Service in Android

Service is an application component that can perform long-running operations in the background like for downloading files or whether to check internet calls or something else similar. A service does not have any UI so it can be called from other Android components and it can be in running state even if we switch applications.

A service has high priority than invisible activity or background activity but less priority than foreground Activity.

To create Service with priority equal to Foreground Activity we can create Foreground Service.

A service can be implemented in two ways:

  1. startService();
  2. bindService();

Let’s understand the behavior in startService()

When service is started using startService(intent) then the onCreate() method of service class will be called and then onStartCommand() method of Service will be called. Once the Service is running then calling startService() will call onStartCommand() again. So if this case can happen, then program onStartCommand accordingly.

In onStarComman() int is returned which describes the service restart behavior as follows:-

  1. Service.START_STICKY – Service is restarted if it gets terminated by the system in case of low resources.
  2. Service.START_NOT_STICKY – if this int flag is used service is not restarted. these are used for services which are called again or periodically.
  3. Service.START_REDELIVER_INTENT – if this int flag is used service is restarted and intent is re-delivered. it is similar to START_STICKY.

To stop a Service () call stopService() or stopSelf().

Let’s understand the behavior in bindService().

When bindService(Intent, ServiceConnection, Flag)  is called then the onBind() method of service is called and it returns the Binder object in onServiceConnection onServiceConnected() and when service is disconnected then onServicedisconnected method of ServiceConnection is called.

First Define a Service class as Follows-:

Service class to display current time, it will display toast with startService() and print timestamp with bindService();

BoundService.java

public class BoundService extends Service {
    private static String LOG_TAG = "BoundService";
    private IBinder mBinder = new MyBinder();

    @Override
    public void onCreate() {
        super.onCreate();
        Log.v(LOG_TAG, "in onCreate");
        Toast.makeText(getApplicationContext(),""+getTimestamp(),Toast.LENGTH_LONG).show();
    }

    @Override
    public IBinder onBind(Intent intent) {
        Log.v(LOG_TAG, "in onBind");
        return mBinder;
    }

    @Override
    public void onRebind(Intent intent) {
        Log.v(LOG_TAG, "in onRebind");
        super.onRebind(intent);
    }

    @Override
    public boolean onUnbind(Intent intent) {
        Log.v(LOG_TAG, "in onUnbind");
        return true;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.v(LOG_TAG, "in onDestroy");

    }

    public String getTimestamp() {
        long elapsedMillis = System.currentTimeMillis();
        SimpleDateFormat format=new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");
        Date date=new Date(elapsedMillis);

        return format.format(date);
    }

    public class MyBinder extends Binder {
        BoundService getService() {
            return BoundService.this;
        }
    }

}

Declare the Service in AndroidManifest.xml

<service android:name=".BoundService" >
       </service>

MainActivity.java as activity class

public class MainActivity extends AppCompatActivity {
    BoundService mBoundService;
    boolean mServiceBound = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        final TextView timestampText = (TextView) findViewById(R.id.timestamp_text);
        Button printTimestampButton = (Button) findViewById(R.id.print_timestamp);
        Button stopServiceButon = (Button) findViewById(R.id.stop_service);
        printTimestampButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mServiceBound) {
                    timestampText.setText(mBoundService.getTimestamp());
                }
            }
        });

        stopServiceButon.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mServiceBound) {
                    unbindService(mServiceConnection);
                    mServiceBound = false;
                }
                Intent intent = new Intent(MainActivity.this,
                        BoundService.class);
                stopService(intent);
            }
        });

    }

    @Override
    protected void onStart() {
        super.onStart();
        Intent intent = new Intent(this, BoundService.class);
        startService(intent);
        bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
    }

    @Override
    protected void onStop() {
        super.onStop();
        if (mServiceBound) {
            unbindService(mServiceConnection);
            mServiceBound = false;
        }
    }

    private ServiceConnection mServiceConnection = new ServiceConnection() {

        @Override
        public void onServiceDisconnected(ComponentName name) {
            mServiceBound = false;
        }

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            BoundService.MyBinder myBinder = (BoundService.MyBinder) service;
            mBoundService = myBinder.getService();
            mServiceBound = true;
        }
    };
}

it will display fist time from the onCreate method of service which will be called by startService() and print timestamp on click of a button with the help of bindService() method.

// layout for mainActivity

activity_main.xml

<RelativeLayout 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:background="#FFFFFF"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
     >
    <Button
        android:id="@+id/print_timestamp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="130dp"
        android:text="Print Timestamp" />

    <TextView
        android:id="@+id/timestamp_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/print_timestamp"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="120dp"
        android:text=""
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <Button
        android:id="@+id/stop_service"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/print_timestamp"
        android:layout_centerHorizontal="true"
        android:text="Stop Service" />

</RelativeLayout>

 

Output

servicesample    servicetimestamp