Главная » Разработка для Android » Автоматизация приложения Emergency Responder

0

В следующем примере1  вы добавите функциональность к кнопке Setup Auto Responder,  созданной  ранее. С ее помощью ваше приложение сможет автоматически отвечать на полученные сообщения.

1. Начните  с создания нового ресурса разметки autoresponder.xml, в котором  будет описано  окно с настройками для автоматических ответов. Добавьте туда элементы  EditText для ввода текста сообще- ния, Spinner  для выбора времени, в течение которого будет отослан

1     Все фрагменты  кода в этом примере — часть проекта Emergency  Responder  2 из главы 12, их можно загрузить с сайта Wrox.com.

автоматический ответ, и CheckBox, чтобы пользователь мог выбрать, нужно добавлять в ответ свое местоположение или нет.

<?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. Отредактируйте ресурс string.xml, определив имя Активности как

SharedPreference и строки для каждого из ее ключей.

<?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. Создайте новый ресурс arrays.xml, который будет содержать массив для заполнения данными элемента Spinner.

<resources>

<string-array name="respondForDisplayItems">

<item>- Disabled -</item>

<item>Next 5 minutes</item>

<item>Next 15 minutes</item>

<item>Next 30 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. Создайте новую Активность AutoResponder и привяжите ее к разметке из пункта 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. Отредактируйте заглушку onCreate, чтобы получить ссылки на каждое Представление внутри разметки  и заполнить элемент Spinner  данны- ми из массива, заданного  в пункте  3. Создайте  два новых метода- заглушки  — savePreferences и updateUIFromPreferences. С помощью первого  настройки будут сохраняться в объект SharedPreferences, с помощью второго — применяться для текущего пользовательского интерфейса.

Spinner respondForSpinner; CheckBox locationCheckbox; EditText responseTextBox;

@Override

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

5.1.Получите  ссылки на каждое Представление.

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

5.2.Заполните данными  элемент Spinner, чтобы пользователи могли выбирать  время, в течение которого отсылается  автоматический ответ.

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.Теперь добавьте обработку нажатий  для кнопок ?? и Cancel, чтобы пользователи могли сохранять или отменять изменения в настрой- ках.

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(-1); savePreferences(); setResult(RESULT_CANCELED, null); finish();

}

});

5.4.В завершение  сделайте  так, чтобы состояние  пользовательского интерфейса Активности при запуске соответствовало текущим на- стройкам.

// Загрузите сохраненные настройки и обновите пользовательский интерфейс updateUIFromPreferences();

5.5.Закончив с методом onCreate, следует добавить две заглушки  —

updateUIFromPreferences и savePreferences.

}

private void updateUIFromPreferences() {}

private void savePreferences() {}

6. Наполните их кодом. Начните  с метода updateUIFromPreferences.

Он должен считывать  текущие настройки Активности AutoResponder и применять их к пользовательскому интерфейсу.

private void updateUIFromPreferences() {

// Получите сохраненные настройки

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 respondForIndex = sp.getInt(respondForPref, 0);

// Примените сохраненные настройки к пользовательскому интерфейсу if (autoRespond)

respondForSpinner.setSelection(respondForIndex);

else respondForSpinner.setSelection(0);

locationCheckbox.setChecked(includeLoc);

responseTextBox.setText(respondText);

}

7. Заполните кодом заглушку savePreferences, чтобы сохранять текущее состояние пользовательского интерфейса в файл Общих настроек.

private void savePreferences() {

// Получите текущее состояние пользовательского интерфейса boolean autoRespond =

respondForSpinner.getSelectedItemPosition() > 0;

int respondForIndex = respondForSpinner.getSelectedItemPosition();

boolean includeLoc = locationCheckbox.isChecked();

String respondText = responseTextBox.getText().toString();

// Сохраните его в файл Общих Настроек

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

Editor editor = sp.edit();

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();

// Отмените автоматические ответы с помощью метода setAlarm setAlarm(respondForIndex);

}

private void setAlarm(int respondForIndex) {}

8. Заглушка setAlarm из предыдущего пункта нужна для создания новой Сигнализации. Она должна активизировать Намерение, которое отклю- чит автоматические ответы.

Вам необходимо  создать новый объект BroadcastReceiver, который будет отслеживать Намерения, посланные  Сигнализацией, прежде чем отключить  автоответ.

8.1.Начните  с создания строкового поля для действия, которое будет представлять Намерение для Сигнализации.

public static final String alarmAction = "com.paad.emergencyresponder.AUTO_RESPONSE_EXPIRED";

8.2.Создайте новый экземпляр BroadcastReceiver, который будет от- слеживать  Намерение, содержащее действие из пункта 8.1. Полу- чив Намерение, он должен соответствующим образом изменить настройки автоответчика.

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 editor = sp.edit(); editor.putBoolean(getString(R.string.autoRespondPref), false); editor.commit();

}

}

};

8.3.Закончите метод setAlarm. Он должен отменять Сигнализацию, если автоматический ответ уже выключен; в противном  случае нужно будет задать для Сигнализации временной  интервал, по истечении которого она должна сработать.

PendingIntent intentToFire;

private void setAlarm(int respondForIndex) {

// Создайте Сигнализацию и зарегистрируйте

// для нее Приемник широковещательных намерений.

AlarmManager alarms = (AlarmManager)getSystemService(ALARM_SERVICE);

if (intentToFire == null) {

Intent intent = new Intent(alarmAction);

intentToFire = PendingIntent.getBroadcast(getApplicationContext(),

0,intent,0);

IntentFilter filter = new IntentFilter(alarmAction);

registerReceiver(stopAutoResponderReceiver, filter);

}

if (respondForIndex < 1)

// Если автоответчик отключен, отмените Сигнализацию. alarms.cancel(intentToFire);

else {

// В ином случае получите временной интервал,

// выбранный в настройках, и сделайте так, чтобы

// Сигнализация сработала по его истечении. 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. На этом написание Активности AutoResponder завершается. Но прежде чем использовать,  необходимо добавить ее в манифест приложения.

<?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. Для того чтобы включить автоматический ответ, вернитесь к Активности EmergencyResponder и отредактируйте заглушку startAutoResponder, созданную в предыдущем примере. Она должна открывать Активность AutoResponder, написание которой вы только что закончили.

private void startAutoResponder() {

startActivityForResult(new Intent(EmergencyResponder.this, AutoResponder.class), 0);

}

11. Теперь, запустив  проект, вы сможете открыть  окно с настройками и изменить поведение автоматического ответа. Выглядеть это должно, как на рис. 12.4.

Рис. 12.4.

12. И последний  шаг: отредактируйте метод requestReceived из Актив- ности EmergencyResponder, чтобы проверять,  включена  ли функция автоматического ответа.

В случае положительного ответа должен автоматически запуститься метод respond с использованием настроек для сообщения  и местопо- ложения,  заданных в Общих настройках приложения.

public void requestReceived(String _from) {

if (!requesters.contains(_from)) { lock.lock(); requesters.add(_from); aa.notifyDataSetChanged(); lock.unlock();

// Проверьте настройки автоответчика

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

0);

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);

}

}

}

Теперь  у вас есть полнофункциональное интерактивное приложение, способное автоматически отвечать на экстренные  сообщения.

Резюме

Телефонный стек — одна из фундаментальных технологий на мобильных телефонах.  И хотя не все устройства  под управлением Android должны ее поддерживать, она стала основой для универсальной платформы, обеспе- чивающей связь между людьми.

Используя API для телефонии,  вы научились  делать звонки  вручную и через стандартное приложение. Вы также узнали, как считывать и отсле- живать состояния телефона, сети (в том числе сети для передачи данных) и SIM-карты.

Android позволяет  использовать SMS для создания приложений, обес- печивающих  обмен данными  между устройствами и передачу сообщений между пользователями.

Вы также узнали, как использовать Намерения, чтобы с помощью систем- ных приложений, изначально установленных на телефоне, отправлять SMS и MMS от своего имени.

В главе 13 рассмотрены другие коммуникационные технологии, доступ- ные на устройствах.  Вы изучите управление  сетевыми подключениями на примере Wi-Fi  и исследуете  возможности программных  интерфейсов для работы с Bluetooth.

Источник: Майер P. Android 2 : программирование приложений для планшетных компьютеров и смартфонов : [пер. с англ. ] / Рето Майер. — М. : Эксмо, 2011. — 672 с. — (Мировой компьютерный бестселлер).

По теме:

  • Комментарии