Automating the Emergency Responder

In the following example, you'll fill in the code behind the Setup Auto Responder button added in the previous example, to let the Emergency Responder automatically respond to status update requests.

1. Start by creating a new autoresponder.xml layout resource that will be used to lay out the automatic response configuration window. Include an EditText for entering a status message to send, a Spinner for choosing the auto-response expiry time, and a checkBox to let users decide whether they want to include their location in the automated responses.

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Respond With"/> <EditText android:id="@+id/responseText" android:layout_width="fill_parent" android:layout_height="wrap_content"/> <CheckBox android:id="@+id/checkboxLocation" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Transmit Location"/> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Auto Respond For"/> <Spinner android:id="@+id/spinnerRespondFor" android:layout_width="fill_parent"

android:layout_height="wrap_content" android:drawSelectorOnTop="true"/> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content"> <Button android:id="@+id/okButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Enable"/> <Button android:id="@+id/cancelButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Disable"/> </LinearLayout> </LinearLayout>

2. Update the application's string.xml resource to define a name for an application SharedPreference and strings to use for each of its keys.

<?xml version="1.0" encoding="utf-8"?> <resources>

<string name="app_name">Emergency Responder</string> <string name="respondAllClearButtonText">I am Safe and Well </string>

<string name="respondMaydayButtonText">MAYDAY! MAYDAY! MAYDAY! </string>

<string name="respondAllClearText">I am safe and well. Worry not! </string>

<string name="respondMaydayText">Tell my mother I love her. </string>

<string name="querystring">"are you ok?"</string> <string name="user_preferences">com.paad.emergencyresponder.preferences </string>

<string name="includeLocationPref">PREF_INCLUDE_LOC</string> <string name="responseTextPref">PREF_RESPONSE_TEXT</string> <string name="autoRespondPref">PREF_AUTO_RESPOND</string> <string name="respondForPref">PREF_RESPOND_FOR</string>

</resources>

3. Then create a new arrays.xml resource, and create arrays to use for populating the Spinner.

<resources>

<string-array name="respondForDisplayItems"> <item>- Disabled -</item> <item>Next 5 minutes</item> <item>Next 15 minutes</item> <item>Next 3 0 minutes</item> <item>Next hour</item> <item>Next 2 hours</item>

<item>Next 8 hours</item> </string-array>

<array name="respondForValues"> <item>0</item> <item>5</item> <item>15</item> <item>30</item> <item>60</item> <item>120</item> <item>480</item> </array> </resources>

4. Now create a new AutoResponder Activity, populating it with the layout you created in Step 1.

package com.paad.emergencyresponder;

import android.app.Activity;

import android.app.AlarmManager;

import android.app.PendingIntent;

import android.content.res.Resources;

import android.content.Context;

import android.content.Intent;

import android.content.IntentFilter;

import android.content.BroadcastReceiver;

import android.content.SharedPreferences;

import android.content.SharedPreferences.Editor;

import android.os.Bundle;

import android.view.View;

import android.widget.ArrayAdapter;

import android.widget.Button;

import android.widget.CheckBox;

import android.widget.EditText;

import android.widget.Spinner;

public class AutoResponder extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.autoresponder);

5. Update onCreate further to get references to each of the controls in the layout and wire up the Spinner using the arrays defined in Step 3. Create two new stub methods, savePreferences and updateUIFromPreferences, that will be updated to save the auto-responder settings to a named SharedPreference and apply the saved SharedPreferences to the current UI, respectively.

Spinner respondForSpinner; CheckBox locationCheckbox; EditText responseTextBox;

©Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.autoresponder);

5.1. Start by getting references to each View.

respondForSpinner = (Spinner)findViewById(R.id.spinnerRespondFor); locationCheckbox = (CheckBox)findViewById(R.id.checkboxLocation); responseTextBox = (EditText)findViewById(R.id.responseText);

5.2. Populate the Spinner to let users select the auto-responder expiry time.

ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, R.array.respondForDisplayItems, android.R.layout.simple_spinner_item);

adapter.setDropDownViewResource(

android.R.layout.simple_spinner_dropdown_item); respondForSpinner.setAdapter(adapter);

5.3. Now wire up the OK and Cancel buttons to let users save or cancel setting changes.

Button okButton = (Button) findViewById(R.id.okButton); okButton.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { savePreferences(); setResult(RESULT_OK, null); finish();

Button cancelButton = (Button) findViewById(R.id.cancelButton); cancelButton.setOnClickListener(new View.OnClickListener() { public void onClick(View view) {

respondForSpinner.setSelection(-l); savePreferences(); setResult(RESULT_CANCELED, null); finish();

5.4. Finally, make sure that when the Activity starts, it updates the GUI to represent the current settings.

// Load the saved preferences and update the UI updateUIFromPreferences();

5.5. Close off the onCreate method, and add the updateUIFromPreferences and savePreferences stubs. }

private void updateUIFromPreferences() {} private void savePreferences() {}

6. Next, complete the two stub methods from Step 5. Start with updateUIFromPreferences; it should read the current saved AutoResponder preferences and apply them to the UI.

private void updateUIFromPreferences() { // Get the saves settings

String preferenceName = getString(R.string.user_preferences); SharedPreferences sp = getSharedPreferences(preferenceName, 0);

String autoResponsePref = getString(R.string.autoRespondPref);

String responseTextPref = getString(R.string.responseTextPref);

String autoLocPref = getString(R.string.includeLocationPref);

String respondForPref = getString(R.string.respondForPref);

boolean autoRespond = sp.getBoolean(autoResponsePref, false); String respondText = sp.getString(responseTextPref, ""); boolean includeLoc = sp.getBoolean(includeLocPref, false); int respondForlndex = sp.getInt(respondForPref, 0);

// Apply the saved settings to the UI if (autoRespond)

respondForSpinner.setSelection(respondForlndex); else respondForSpinner.setSelection(O);

locationCheckbox.setChecked(includeLoc); responseTextBox.setText(respondText);

7. Complete the savePreferences stub to save the current UI settings to a Shared Preferences file.

private void savePreferences() {

// Get the current settings from the UI boolean autoRespond =

respondForSpinner.getSelectedItemPosition() > 0; int respondForlndex = respondForSpinner.getSelectedItemPosition(); boolean includeLoc = locationCheckbox.isChecked(); String respondText = responseTextBox.getText().toString();

// Save them to the Shared Preference file

String preferenceName = getString(R.string.user_preferences); SharedPreferences sp = getSharedPreferences(preferenceName, 0);

editor.putBoolean(getString(R.string.autoRespondPref), autoRespond);

editor.putString(getString(R.string.responseTextPref), respondText);

editor.putBoolean(getString(R.string.includeLocationPref), includeLoc );

editor.putInt(getString(R.string.respondForPref),respondForIndex); editor.commit();

// Set the alarm to turn off the autoresponder setAlarm(respondForlndex);

private void setAlarm(int respondForlndex) {}

8. The setAlarm stub from Step 7 is used to create a new Alarm that fires an Intent that should result in the AutoResponder's being disabled.

You'll need to create a new Alarm object and a BroadcastReceiver that listens for it before disabling the auto-responder accordingly.

8.1. Start by creating the action String that will represent the Alarm Intent.

public static final String alarmAction =

"com.paad.emergencyresponder.AUTO_RESPONSE_EXPIRED";

8.2. Then create a new Broadcast Receiver instance that listens for an Intent that includes the action specified in Step 8.1. When this Intent is received, it should modify the auto-responder settings to disable the automatic response.

private BroadcastReceiver stopAutoResponderReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(alarmAction)) {

String preferenceName = getString(R.string.user_preferences); SharedPreferences sp = getSharedPreferences(preferenceName,0);

editor.putBoolean(getString(R.string.autoRespondPref), false); editor.commit();

8.3. Finally, complete the setAlarm method. It should cancel the existing alarm if the auto-responder is turned off; otherwise, it should update the alarm with the latest expiry time.

PendingIntent intentToFire;

private void setAlarm(int respondForIndex) {

// Create the alarm and register the alarm intent receiver.

AlarmManager alarms =

(AlarmManager)getSystemService(ALARM_SERVICE);

Intent intent = new Intent(alarmAction); intentToFire =

PendingIntent.getBroadcast(getApplicationContext(),

IntentFilter filter = new IntentFilter(alarmAction); registerReceiver(stopAutoResponderReceiver, filter);

if (respondForIndex < 1)

// If "disabled" is selected, cancel the alarm. alarms.cancel(intentToFire);

// Otherwise find the length of time represented // by the selection and and set the alarm to // trigger after that time has passed. Resources r = getResources(); int[] respondForValues =

r.getIntArray(R.array.respondForValues); int respondFor = respondForValues [respondForIndex];

long t = System.currentTimeMillis(); t = t + respondFor*1000*60;

alarms.set(AlarmManager.RTC_WAKEUP, t, intentToFire);

9. That completes the AutoResponder, but before you can use it, you'll need to add it to your application manifest.

<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"

package="com.paad.emergencyresponder">

<application android:icon="@drawable/icon"

android:label="@string/app_name">

<activity android:name=".EmergencyResponder" android:label="@string/app_name"> <intent-filter>

<action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".AutoResponder" android:label="Auto Responder Setup"/> </application>

<uses-permission android:name="android.permission.ACCESS_GPS"/> <uses-permission android:name="android.permission.ACCESS_LOCATION"/>

<uses-permission android:name="android.permission.RECEIVE_SMS"/> <uses-permission android:name="android.permission.SEND_SMS"/> </manifest>

10. To enable the auto-responder, return to the Emergency Responder Activity and update the startAutoResponder method stub that you created in the previous example. It should open the AutoResponder Activity you just created.

private void startAutoResponder() {

startActivityForResult(new Intent(EmergencyResponder.this,

AutoResponder.class), 0);

11. If you start your project, you should now be able to bring up the Auto Responder Setup window to set the auto-response settings. It should appear as shown in Figure 12-4.

FIGURE 12-4

12. The final step is to update the requestReceived method in the Emergency Responder Activity to check if the auto-responder has been enabled.

If it has, the requestReceived method should automatically execute the respond method, using the message and location settings defined in the application's Shared Preferences.

public void requestReceived(String _from) { if (!requesters.contains(_from)) { lock.lock(); requesters.add(_from); aa.notifyDataSetChanged(); lock.unlock();

// Check for auto-responder

String preferenceName = getString(R.string.user_preferences); SharedPreferences prefs = getSharedPreferences(preferenceName,

String autoRespondPref = getString(R.string.autoRespondPref) boolean autoRespond = prefs.getBoolean(autoRespondPref, false);

if (autoRespond) {

String responseTextPref =

getString(R.string.responseTextPref); String includeLocationPref =

getString(R.string.includeLocationPref);

String respondText = prefs.getString(responseTextPref, ""); boolean includeLoc = prefs.getBoolean(includeLocationPref, false);

respond(_from, respondText, includeLoc);

All code snippets in this example are part of the Chapter 12 Emergency Responder 2 project, available for download at Wrox.com.

You should now have a fully functional interactive and automated emergency responder.

SUMMARY

The telephony stack is one of the fundamental technologies available on mobile phones. While not all Android devices will necessarily provide telephony APIs, those that do are particularly versatile platforms for person-to-person communication.

Using the telephony APIs you learned how to initiate calls directly and through the dialer. You also discovered how to read and monitor phone, network, data, and SIM states.

Android lets you use SMS to create applications that exchange data between devices and send and receive text messages for your users.

You also learned how to use Intents to allow the SMS applications already available on the phone to send SMS and MMS messages on your behalf.

Chapter 13 explores access to other device communication technologies. You'll investigate network management using Wi-Fi and explore the functionality available through the Bluetooth APIs.

Mobile Apps Made Easy

Mobile Apps Made Easy

Quick start guide to skyrocket your offline and online business success with mobile apps. If you know anything about mobile devices, you’ve probably heard that famous phrase coined by one of the mobile device’s most prolific creators proclaiming that there’s an app for pretty much everything.

Get My Free Training Guide


Post a comment