Намерение запустить приложение часов на Android
Я столкнулся с проблемой с виджетом часов, который я сделал. Я хочу, чтобы пользователь коснулся часов и запустил приложение часов на телефоне. это код:
//this worked on my nexus 2.1
if(VERSION.SDK.equals("7")){
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);
Intent AlarmClockIntent = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_LAUNCHER).setComponent(new ComponentName("com.android.deskclock", "com.android.deskclock.DeskClock"));
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, AlarmClockIntent, 0);
views.setOnClickPendingIntent(R.id.Widget, pendingIntent);
AppWidgetManager.getInstance(context).updateAppWidget(intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS), views);
}
//this worked on my nexus +froyo2.2
else if(VERSION.SDK.equals("8")){
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);
Intent AlarmClockIntent = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_LAUNCHER).setComponent(new ComponentName("com.google.android.deskclock", "com.android.deskclock.DeskClock"));
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, AlarmClockIntent, 0);
views.setOnClickPendingIntent(R.id.Widget, pendingIntent);
AppWidgetManager.getInstance(context).updateAppWidget(intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS), views);
}
//this worked on my htc magic with 1.5 and 1.6
else{
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);
Intent AlarmClockIntent = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_LAUNCHER).setComponent(new ComponentName("com.android.alarmclock", "com.android.alarmclock.AlarmClock"));
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, AlarmClockIntent, 0);
views.setOnClickPendingIntent(R.id.Widget, pendingIntent);
AppWidgetManager.getInstance(context).updateAppWidget(intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS), views);
}
Я сделал выше, поэтому, когда я касаюсь часов, открывает настройки будильника. Но не универсален. Я обнаружил, что на дроидах с 2.2 не работает. Должно быть лучшее решение, чем создание оператора if для каждого аромата телефона в мире. Плюс я не знаю названия пакетов для всех. Кто-нибудь знает, как преодолеть это, пожалуйста, помогите.
8 ответов
Этот код работает для моего виджета часов.
PackageManager packageManager = context.getPackageManager();
Intent alarmClockIntent = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_LAUNCHER);
// Verify clock implementation
String clockImpls[][] = {
{"HTC Alarm Clock", "com.htc.android.worldclock", "com.htc.android.worldclock.WorldClockTabControl" },
{"Standar Alarm Clock", "com.android.deskclock", "com.android.deskclock.AlarmClock"},
{"Froyo Nexus Alarm Clock", "com.google.android.deskclock", "com.android.deskclock.DeskClock"},
{"Moto Blur Alarm Clock", "com.motorola.blur.alarmclock", "com.motorola.blur.alarmclock.AlarmClock"},
{"Samsung Galaxy Clock", "com.sec.android.app.clockpackage","com.sec.android.app.clockpackage.ClockPackage"} ,
{"Sony Ericsson Xperia Z", "com.sonyericsson.organizer", "com.sonyericsson.organizer.Organizer_WorldClock" },
{"ASUS Tablets", "com.asus.deskclock", "com.asus.deskclock.DeskClock"}
};
boolean foundClockImpl = false;
for(int i=0; i<clockImpls.length; i++) {
String vendor = clockImpls[i][0];
String packageName = clockImpls[i][1];
String className = clockImpls[i][2];
try {
ComponentName cn = new ComponentName(packageName, className);
ActivityInfo aInfo = packageManager.getActivityInfo(cn, PackageManager.GET_META_DATA);
alarmClockIntent.setComponent(cn);
debug("Found " + vendor + " --> " + packageName + "/" + className);
foundClockImpl = true;
} catch (NameNotFoundException e) {
debug(vendor + " does not exists");
}
}
if (foundClockImpl) {
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, alarmClockIntent, 0);
// add pending intent to your component
// ....
}
Таким образом, я могу запустить менеджер часов по умолчанию.
Чтобы следовать ответу Майры, класс android.provider.AlarmClock
имеет надлежащий Intent
для этого, но он доступен только на уровне API 9 и выше. (По крайней мере, кто-то в Google слушает подобные запросы!)
Чтобы запустить приложение часов из вашего виджета, работает следующий код:
Intent openClockIntent = new Intent(AlarmClock.ACTION_SET_ALARM);
openClockIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(openClockIntent);
Вам также необходимо это разрешение:<uses-permission android:name="com.android.alarm.permission.SET_ALARM"/>
На уровне API 19 вы можете использовать это для отображения списка будильников в приложении часов по умолчанию:
Intent mClockIntent = new Intent(AlarmClock.ACTION_SHOW_ALARMS);
mClockIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(mClockIntent);
Правильный способ начать действие вне вашего приложения - это использовать неявное намерение. С неявным намерением вы не предоставляете определенный класс для запуска, вместо этого вы указываете действие, которое другие приложения могут выбрать для выполнения.
Это сделано для предотвращения поломок в вашем приложении, когда создатель другого приложения решает переименовать свой класс или что-то подобное. Кроме того, он позволяет нескольким приложениям реагировать на одно и то же действие.
Посмотрите намерения и фильтры намерений для более подробной информации о неявных намерениях.
К сожалению, для того, чтобы это работало, вам нужно, чтобы разработчики приложений согласились выполнить все конкретные действия. Если в приложениях с часами этого нет, то нет хорошего способа выполнить то, что вы хотите.
Я бы посоветовал не пытаться создать такое огромное утверждение, как у вас, поскольку приложение может отличаться не только в разных версиях SDK, но и в разных телефонах, поскольку производители телефонов могут заменить приложения. Таким образом, ваше приложение будет постоянно ломаться на новых телефонах, если вы полагаетесь на возможность открывать приложение часов.
Код:
Intent i = new Intent(AlarmClock.ACTION_SET_ALARM);
i.putExtra(AlarmClock.EXTRA_MESSAGE, "Alarm Title");
ArrayList<Integer> alarmDays = new ArrayList<>();
alarmDays.add(Calendar.SATURDAY);
alarmDays.add(Calendar.SUNDAY);
alarmDays.add(Calendar.MONDAY);
alarmDays.add(Calendar.TUESDAY);
alarmDays.add(Calendar.WEDNESDAY);
alarmDays.add(Calendar.THURSDAY);
alarmDays.add(Calendar.FRIDAY);
i.putExtra(AlarmClock.EXTRA_DAYS, alarmDays);
i.putExtra(AlarmClock.EXTRA_VIBRATE, true);
i.putExtra(AlarmClock.EXTRA_HOUR, 10);
i.putExtra(AlarmClock.EXTRA_MINUTES, 21);
startActivity(i);
Разрешение:
<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
@ Майра права. Это путь. Однако собственное приложение часов не имеет зарегистрированного намерения и не использует фильтр намерений. Я не думаю, что есть собственное приложение, кроме системных настроек, которое открывает его.
Кроме того, приложение родных часов недоступно в одной и той же форме или вообще не доступно на разных телефонах. Это даже за пределами версий SDK. Так что на самом деле нет (хорошего) способа включить вас.
Ваш лучший выход - отправить патч на source.android.com, который дает приложению часов фильтр намерений, а затем зарегистрировать намерение на http://www.openintents.org/en/intentstable. По крайней мере, тогда ваше приложение работает на подмножестве устройств, а на других не работает (говоря, что не может быть найдено такое приложение для обработки намерений).
Небольшое дополнение для ответа. Чтобы запустить Будильник на телефонах Google Galaxy Nexus:
{"Standar Alarm Clock2", "com.google.android.deskclock", "com.android.deskclock.AlarmClock"},
в остальных случаях будет запущено приложение Clock вместо Alarm Clock
Можете добавить
{ "Sony Ericsson Xperia Z", "com.sonyericsson.organizer", "com.sonyericsson.organizer.Organizer_WorldClock" }
чтобы ответить на вопрос о поддержке новых телефонов Xperia.