Намерение запустить приложение часов на 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.

Другие вопросы по тегам