Click here to Skip to main content
15,894,825 members
Articles / Mobile Apps / Android

AutoRing Android Service Creation Walkthrough

Rate me:
Please Sign up or sign in to vote.
4.89/5 (23 votes)
30 Apr 2014CPOL19 min read 61.5K   2.8K   75  
Create a simple service which listens for connection changes
package droid.ar;

import droid.ar.R;
import android.app.Activity;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.MenuItem;
import android.view.View.OnCreateContextMenuListener;
import android.widget.TextView;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Toast;
import android.content.Intent;
import android.view.View;

public class AutoRingActivity extends Activity 
	//implement click listeners so we can use this class to process menu & button clicks
	implements MenuItem.OnMenuItemClickListener, View.OnClickListener {

	//class level variables
	AutoRingActivity mMainActivity;
	LinearLayout mMainView;
	Button btnConnectedOption, btnDisconnectedOption, btnStartStop;
	private int mConnectAction = 2; //default is Ring
	private int mDisconnectAction = 1; //default is Vibrate

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

		//housekeeping
		setContentView(R.layout.main);
		mMainView = (android.widget.LinearLayout) findViewById(R.id.main_view);
		AutoRingSvc.mMainActivity = this; //so service can update GUI
		mMainActivity = this; //for use in anonymous classes

		//get button objects
		btnConnectedOption = ((Button) findViewById(R.id.btnConnectedOption));
		btnDisconnectedOption = ((Button) findViewById(R.id.btnDisconnectedOption));
		btnStartStop = ((Button) findViewById(R.id.btnStartStop));

		//for Android 1.5 and less, we need to add the click listeners in code
		//after Android 1.5, these can be declared in main.xml (android:onClick="onClick")
		btnConnectedOption.setOnClickListener(this);
		btnDisconnectedOption.setOnClickListener(this);
		btnStartStop.setOnClickListener(this);       

		//get user preferences - use defaults if not set
		mConnectAction = getSharedPreferences("AutoRing", 0).getInt("ConnectAction", mConnectAction);
		mDisconnectAction = getSharedPreferences("AutoRing", 0).getInt("DisconnectAction", mDisconnectAction);

		UpdateSvcStatus(); //update text boxes and buttons
        
		//this is called when we pop up the context menu (openContextMenu)
		mMainView.setOnCreateContextMenuListener(new OnCreateContextMenuListener() {   		 
			@Override
			public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
				//we're using the same context menu for the Connect and Disconnect buttons
				Button btnCaller = (Button)v.getTag(); //we passed the calling button in the view tag
				//set menu heading according to calling button
				menu.setHeaderTitle(btnCaller == btnConnectedOption?"When Connected":"When Disconnected");
				//get action based on calling button and current setting
				int action = (v.getTag() == btnConnectedOption) ? mConnectAction : mDisconnectAction;
				//create the menu items according the mActionList string array
				//set the group id to the calling button id for later reference
				//all the menu items have the same listener
				for (int i=0; i<4; i++) 
					menu.add(btnCaller.getId(),i,0, AutoRingSvc.mActionList[i])
					 .setChecked(action == i) //set checked if this item matches current setting
					 .setOnMenuItemClickListener(mMainActivity); //we implemented OnMenuItemClickListener
				//set the menu items to checkable and exclusive so they appear as radio buttons
				menu.setGroupCheckable(btnCaller.getId(), true, true);
			}
		});
    } //onCreate
    
	//this is called when the user clicks a context menu item
	//this is the implementation of OnMenuItemClickListener
	public boolean onMenuItemClick(MenuItem item) {
		//the calling button instance was passed to the context menu
		//the groupid of the menu item is the calling button id
		//update service static value with new setting
		if (item.getGroupId() == R.id.btnConnectedOption)
			mConnectAction = item.getItemId();
		if (item.getGroupId() == R.id.btnDisconnectedOption)
			mDisconnectAction = item.getItemId();

		//store updated settings, these are read in AutoRingSvc.onCreate()
		getSharedPreferences("AutoRing", 0).edit()
		 .putInt("ConnectAction", mConnectAction)
		 .putInt("DisconnectAction", mDisconnectAction)
		 .commit();

		UpdateSvcStatus();	//update GUI
		return true;
	}
    
	//this is called when the user clicks a button on our GUI
	//OnClickListener implementation
	public void onClick(View view) {
		Button btn = (Button)view;
		if (btn.getId()== R.id.btnStartStop)
		{
			AutoRingSvc.mMainActivity = this; //so service can update GUI
			//store service state, this is read in RebootReceiver class
			//if user started service, we will need to restart on reboot
			getSharedPreferences("AutoRing", 0).edit()
			 .putBoolean("StartOnReboot", !AutoRingSvc.mSvcStarted).commit();
			//create service intent (or connect to running service)
			Intent svc = new Intent(mMainActivity, AutoRingSvc.class);
			if (!AutoRingSvc.mSvcStarted) //if not started
				getApplicationContext().startService(svc); //start service 
			else //already started, so attempt stop
				AutoRingSvc.mSvcStarted = !getApplicationContext().stopService(svc); //returns true if stopped successfully
			UpdateSvcStatus(); //update GUI
		}
		//if user clicked on an option button
		if (btn.getId()== R.id.btnConnectedOption || btn.getId()== R.id.btnDisconnectedOption)
		{
			mMainView.setTag(btn); //pass calling button to context menu so we get button id back
			openContextMenu(mMainView); //start option menu
		}
	}
	
	public void UpdateSvcStatus() {
		//update the GUI text fields with the battery and service status
		((TextView) findViewById(R.id.txtBattStatus)).setText(AutoRingSvc.mBatteryStatus);
		((TextView) findViewById(R.id.txtStatus)).setText("AutoRing is "+(AutoRingSvc.mSvcStarted? "running": "stopped"));
		//set text of Start\Stop button
		btnStartStop.setText((AutoRingSvc.mSvcStarted? "Stop": "Start") + " AutoRing"); 

		//if service is running disable the option buttons, else enable them
		btnConnectedOption.setEnabled(!AutoRingSvc.mSvcStarted);
		btnDisconnectedOption.setEnabled(!AutoRingSvc.mSvcStarted);

		//update option button text with current settings
		btnConnectedOption.setText("When Connected: " + AutoRingSvc.mActionList[mConnectAction]);
		btnDisconnectedOption.setText("When Disconnected: " + AutoRingSvc.mActionList[mDisconnectAction]);
		
		//Must be Android 1.6 or higher to add arrow icon to buttons
		if (Integer.parseInt(android.os.Build.VERSION.SDK) > 3) 
		{
			//add arrow icons to option buttons when enabled
			btnConnectedOption.setCompoundDrawablesWithIntrinsicBounds(0,0, btnConnectedOption.isEnabled()? R.drawable.downarrow: 0, 0);
			btnDisconnectedOption.setCompoundDrawablesWithIntrinsicBounds(0,0, btnDisconnectedOption.isEnabled()? R.drawable.downarrow: 0, 0);
		}
	}

	@Override
	public void onPause() { //app moved to background, no need for updates
		super.onPause();
		AutoRingSvc.mMainActivity = null; //disconnect from service
	}

	@Override
	public void onResume() { //app moved to foreground (also occurs at app startup)
		super.onResume();
		AutoRingSvc.mMainActivity = this; //reconnect to service
		UpdateSvcStatus();	//update GUI
	}
     
	@Override 
	public void onDestroy() {
		super.onDestroy();
		//show message so we know when the GUI app is gone and the service is still running
		Toast.makeText( mMainView.getContext(), " Goodbye GUI ", Toast.LENGTH_SHORT).show();
	}
} //AutoRingActivity

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

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


Written By
Architect Aon Insurance
United States United States
Mike Waddell

Professional C# developer who dabbles in web and mobile development. Currently working with C#, SQL Server, and Python.

I also spend too much time playing video games and watching movies.

Certifications in .Net, SQL Server, Java, and Python

Comments and Discussions