Пользователи Android всегда в поиске приложений, которые могут изменить поведение своих устройств новыми и инновационными способами. Платформа Android дает разработчикам большую свободу в создании таких приложений. В этом руководстве вы узнаете, как создать приложение, которое рандомизирует мелодию звонка телефона Android при каждом получении вызова.
Предпосылки
Если вы хотите следовать, убедитесь, что у вас установлена последняя версия Android Studio. Вы можете получить его с сайта Android Developer .
Поскольку это промежуточное руководство, я не буду подробно останавливаться на основах. Я предполагаю, что вы уже создали одно или несколько приложений для Android и знакомы с основами Android SDK.
1. Создайте новый проект
Запустите Android Studio и создайте новый проект. Установите имя приложения в RingtoneRandomizer . Убедитесь, что вы выбрали уникальное имя пакета.
Это приложение может работать на всех телефонах с уровнем API 8 или выше, поэтому установите минимальный SDK для Android 2.2 .
Далее выберите « Добавить бездействие» и нажмите « Готово» .
2. Редактировать Манифест
Наше приложение будет нуждаться в следующих разрешениях:
-
android.permission.READ_PHONE_STATE
для обнаружения входящих звонков -
android.permission.WRITE_SETTINGS
чтобы изменить настройку рингтона по умолчанию -
android.permission.READ_EXTERNAL_STORAGE
чтобы получить список доступных мелодий
Добавьте следующее в AndroidManifest.xml :
1
2
3
|
<uses-permission android:name=»android.permission.READ_PHONE_STATE»/>
<uses-permission android:name=»android.permission.WRITE_SETTINGS»/>
<uses-permission android:name=»android.permission.READ_EXTERNAL_STORAGE»/>
|
Это приложение имеет одно действие, чтобы позволить пользователю активировать / деактивировать поведение изменения мелодии звонка.
1
2
3
4
5
6
|
<activity android:name=».MainActivity» >
<intent-filter>
<action android:name=»android.intent.action.MAIN» />
<category android:name=»android.intent.category.LAUNCHER» />
</intent-filter>
</activity>
|
Он также имеет BroadcastReceiver
для обнаружения изменений состояния вызова. Как показано ниже, намеренное действие, которое он слушает, является android.intent.action.PHONE_STATE
.
1
2
3
4
5
6
7
|
<receiver
android:name=».RingReceiver»
android:enabled=»true»>
<intent-filter>
<action android:name=»android.intent.action.PHONE_STATE»/>
</intent-filter>
</receiver>
|
3. Отредактируйте strings.xml
Файл strings.xml содержит строки, используемые приложением. Обновите values / strings.xml, как показано ниже:
1
2
3
4
5
6
7
8
9
|
<?xml version=»1.0″ encoding=»utf-8″?>
<resources>
<string name=»app_name»>Ringtone Randomizer</string>
<string name=»activate»>Activate Ringtone Randomizer</string>
<string name=»deactivate»>Deactivate Ringtone Randomizer</string>
<string name=»list_of_ringtones»>Ringtones available on this device:</string>
</resources>
|
4. Создайте макет деятельности
Activity
нужны следующие представления:
-
ToggleButton
для активации / деактивации рандомизатора рингтона -
ListView
для отображения всех доступных мелодий -
TextView
который действует как метка
Создайте файл с именем layout / activity_main.xml и замените его содержимое следующим. Как видите, макет довольно прост и понятен.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
<?xml version=»1.0″ encoding=»utf-8″?>
<LinearLayout xmlns:android=»http://schemas.android.com/apk/res/android»
android:orientation=»vertical» android:layout_width=»match_parent»
android:layout_height=»match_parent»
android:padding=»16dp»
>
<ToggleButton
android:layout_width=»match_parent»
android:layout_height=»wrap_content»
android:textOff=»@string/activate»
android:textOn=»@string/deactivate»
android:id=»@+id/toggle»
/>
<TextView
android:layout_width=»match_parent»
android:layout_height=»wrap_content»
android:text=»@string/list_of_ringtones»
android:textStyle=»bold»
/>
<ListView
android:layout_width=»match_parent»
android:layout_height=»match_parent»
android:id=»@+id/list_of_ringtones»
/>
</LinearLayout>
|
5. Создать RingtoneHelper
Helper Class
Чтобы избежать работы с RingtoneManager
непосредственно в Activity
или BroadcastReceiver
, мы собираемся создать вспомогательный класс с именем RingtoneHelper
.
1
2
3
|
public class RingtoneHelper {
}
|
Класс RingtoneHelper
будет иметь два статических метода, которые используют класс RingtoneManager
.
fetchAvailableRingtones
Метод fetchAvailableRingtones
извлекает список доступных рингтонов, возвращая объекты List
Ringtone
.
01
02
03
04
05
06
07
08
09
10
11
12
13
|
public static List<Ringtone> fetchAvailableRingtones(Context context){
List<Ringtone> ringtones = new ArrayList<>();
RingtoneManager mgr = new RingtoneManager(context);
mgr.setType(RingtoneManager.TYPE_RINGTONE);
int n = mgr.getCursor().getCount();
for(int i=0;i<n;i++){
ringtones.add(mgr.getRingtone(i));
}
return ringtones;
}
|
В методе fetchAvailableRingtones
мы начинаем с создания экземпляра класса RingtoneManager
. Объект RingtoneManager
может перечислить все звуки, доступные на устройстве. Это включает в себя звуки для сигналов тревоги и других уведомлений.
Мы используем метод setType
чтобы установить его тип в TYPE_RINGTONE
как нас интересуют только мелодии звонка.
Затем мы вызываем метод getCount
чтобы узнать, сколько рингтонов доступно, и вызываем метод getRingtone
в цикле for
, добавляя каждый рингтон в ringtones
.
changeRingtone
Метод changeRingtone
отвечает за изменение мелодии устройства, основной функции нашего приложения.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
public static void changeRingtone(Context context){
SharedPreferences preferences = context.getSharedPreferences(«randomizer», Context.MODE_PRIVATE);
if(!preferences.getBoolean(«active», false))
return;
RingtoneManager mgr = new RingtoneManager(context);
Random random = new Random(System.currentTimeMillis());
int n = random.nextInt(mgr.getCursor().getCount());
RingtoneManager.setActualDefaultRingtoneUri(context,
RingtoneManager.TYPE_RINGTONE, mgr.getRingtoneUri(n));
}
|
Сначала мы проверяем в SharedPreferences
ли пользователь рандомизатор рингтонов. Затем мы используем класс Random
чтобы выбрать случайное число, которое меньше количества доступных мелодий.
Метод getRingtoneUri
вызывается для извлечения URI соответствующего рингтона и передачи его в метод setActualDefaultRingtoneUri
для изменения рингтона.
6. Создайте широковещательный приемник
Создайте новый класс с именем RingReceiver
который наследуется от BroadcastReceiver
. Новый класс будет иметь только один метод с именем onReceive
. В этом методе все, что мы делаем, это вызываем метод changeRingtone
вспомогательного класса, если changeRingtone
следующие критерии:
- действие полученного
Intent
равноTelephonyManager.ACTION_PHONE_STATE_CHANGED
- значение ключа поиска
EXTRA_STATE
равноTelephonyManager.EXTRA_STATE_RINGING
Вот как должен выглядеть класс RingReceiver
:
01
02
03
04
05
06
07
08
09
10
11
12
13
|
public class RingReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(TelephonyManager.ACTION_PHONE_STATE_CHANGED)) {
String callState = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
if (callState.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
RingtoneHelper.changeRingtone(context);
}
}
}
}
|
7. Создать активность
Создайте новый класс с именем MainActivity
который наследуется от Activity
. Мы переопределяем метод onCreate
и выполняем следующие действия:
- вызовите
setContentView
для использования макета, определенного в activity_main.xml - вызовите метод
fetchAvailableRingtones
вспомогательного класса для заполненияList
мелодий - инициализировать
ListView
- инициализировать
ToggleButton
Класс MainActivity
теперь должен выглядеть примерно так:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
|
public class MainActivity extends Activity {
private ListView listOfRingtones;
private ToggleButton toggleRandomizer;
private List<Ringtone> ringtones;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listOfRingtones = (ListView)findViewById(R.id.list_of_ringtones);
toggleRandomizer = (ToggleButton)findViewById(R.id.toggle);
ringtones = RingtoneHelper.fetchAvailableRingtones(this);
initializeList();
initializeToggle();
}
}
|
initializeToggle
В методе initializeToggle
мы устанавливаем состояние кнопки переключения на основе boolean
значения с именем active в SharedPreferences
. Это значение установлено в false
по умолчанию.
Мы также добавляем OnCheckedChangeListener
к кнопке переключения, чтобы обновить значение в SharedPreferences
. Для этого putBoolean
методы putBoolean
и commit
Editor
.
01
02
03
04
05
06
07
08
09
10
11
12
|
private void initializeToggle(){
final SharedPreferences preferences = getSharedPreferences(«randomizer», Context.MODE_PRIVATE);
boolean active = preferences.getBoolean(«active», false);
toggleRandomizer.setChecked(active);
toggleRandomizer.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
preferences.edit().putBoolean(«active», isChecked).commit();
}
});
}
|
initializeList
Метод initializeList
создает Adapter
на основе List
мелодий звонка. Используйте android.R.layout.simple_list_item_1
в качестве макета элементов ListView
. Это не что иное, как TextView
. Он должен отображать заголовок рингтона, используя метод getTitle
класса getTitle
. Это должно быть сделано внутри метода getView
, после его переопределения.
Как только Adapter
будет готов, назначьте его ListView
с помощью метода setAdapter
в ListView
.
01
02
03
04
05
06
07
08
09
10
11
12
13
|
private void initializeList(){
ArrayAdapter<Ringtone> adapter = new ArrayAdapter<Ringtone>(this,
android.R.layout.simple_list_item_1, ringtones) {
@Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView item = (TextView)super.getView(position, convertView, parent);
item.setText(ringtones.get(position).getTitle(MainActivity.this));
return item;
}
};
listOfRingtones.setAdapter(adapter);
}
|
8. Скомпилируйте и запустите
Наше приложение готово для развертывания на телефоне Android. Вы должны видеть все мелодии звонка, доступные на вашем телефоне, при запуске приложения. Нажмите на кнопку переключения, чтобы активировать рандомизатор.
Позвони себе с другого телефона пару раз. При первом вызове будет воспроизводиться ваш оригинальный рингтон. Со следующего звонка вы услышите случайный рингтон каждый раз.
Обратите внимание, что это приложение меняет мелодию звонка по умолчанию вашего телефона. Если вы назначили определенную мелодию для контакта или группы контактов, эта мелодия будет по-прежнему использоваться.
Вывод
Теперь вы знаете, как использовать функциональность, доступную в классе RingtoneManager
. Вы также узнали, как обнаружить входящие звонки. Не стесняйтесь использовать это приложение для рандомизации других уведомлений аналогичным образом. Посетите веб-сайт Android Developer, чтобы узнать больше о классе RingtoneManager
.