机器人:通过点击小工具打开闹钟或时钟应用 [英] android: open alarm or clock app by clicking widget

查看:207
本文介绍了机器人:通过点击小工具打开闹钟或时钟应用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

不同的手机和供应商有不同的时钟应用程序。 code可打开的应用设置一个有些手机。不同的答案给出不同的列表和策略,他们往往有工作的问题。


解决方案

可靠的方式来打开点击一个widget时钟的应用程序。

这code描述了如何报警或座钟的应用程序可以通过点击小工具打开。它解决了与其它解决方案的可靠性问题。它通过使用共享preferences增加了功率经济性。

在code,它认定为手机应用程序被放置在onEnabled。它发现应用程序,然后保存在共享preferences的信息,通过更新服务来调用。一旦第一个包被发现,将停止搜索。如果你要搜索的报警及座钟两者放在数组列表越高preferred选项。每个小部件被更新时,它不这样做搜索,节省电力。如果你的部件经常更新,这将使电池寿命的差异。

如果您觉得用户可能会改变他们的闹钟应用,可以放置onEnabled code在WidgetProvider类一个单独的方法。然后从onEnabled调用它,并调用它,当你发现在用户时钟包的变化。

WIDGET Provider类


  

公共类WidgetProvider扩展AppWidgetProvider {

 公共静态最后弦乐SHARED_ preFS =共享preFS
私人的PendingIntent的PendingIntent = NULL;@覆盖
公共无效的onUpdate(上下文的背景下,AppWidgetManager appWidgetManager,INT [] appWidgetIds){    每当的onUpdate被称为//启动UpdateService
    意图sIntent =新意图(背景下,UpdateService.class);
    sIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    context.startService(sIntent);
}@覆盖
公共无效onEnabled(上下文的背景下){
    super.onEnabled(上下文);
    Log.w(LOGWidgetProvider.onEnabled触发);    //找到当地报警服务    //这是报警+时钟服务不完整的数组,
    //在优先的任意顺序。
    //你可能需要改变,以满足您的要求
    串clockImpls [] [] = {
     {标准报警,com.android.alarmclock,com.android.alarmclock.AlarmClock},
     {索尼报警,com.sonyericsson.alarm,com.sonyericsson.alarm.Alarm},
     {索尼爱立信Xperia Z,com.sonyericsson.organizer,com.sonyericsson.organizer.Organizer_WorldClock},
     {华硕闹钟,com.asus.alarmclock,com.asus.alarmclock.AlarmClock},
     {华硕座钟,com.asus.deskclock,com.asus.deskclock.DeskClock},
     {HTC报警ClockDT,com.htc.android.worldclock,com.htc.android.worldclock.WorldClockTabControl},
     {标准报警ClockDT,com.android.deskclock,com.android.deskclock.AlarmClock},
     {升级Froyo的Nexus报警ClockDT,com.google.android.deskclock,com.android.deskclock.DeskClock},
     {MOTO BLUR报警ClockDT,com.motorola.blur.alarmclock,com.motorola.blur.alarmclock.AlarmClock},
     {三星Galaxy S,com.sec.android.app.clockpackage,com.sec.android.app.clockpackage.ClockPackage}
    };    软件包管理系统软件包管理系统= context.getPackageManager();
    意图alarmClockIntent =新意图(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_LAUNCHER);
    布尔foundClockImpl = FALSE;
    字符串VENDORNAME =;
    串的packageName =;
    字符串的className =;    的for(int i = 0; I< clockImpls.length;我++){
        VENDORNAME = clockImpls [I] [0]; //不需要的,仅用于调试
        的packageName = clockImpls [I] [1];
        的className = clockImpls [I] [2];
        尝试{
            组件名CN =新的组件名(的packageName,className)已过时;
            packageManager.getActivityInfo(CN,PackageManager.GET_META_DATA);
            alarmClockIntent.setComponent(CN);
            foundClockImpl = TRUE;
        }赶上(PackageManager.NameNotFoundException E){
            // Log.w(LOGAlarmService想不出检索活动信息);
        }
        如果(foundClockImpl){
            //当第一包被发现
            //发送alarmCLockIntent到共享preferences
            //,打破的循环
            共享preferences设置= context.getShared preferences(SHARED_ preFS,0);
            共享preferences.Editor编辑= settings.edit();
            editor.putString(VENDORNAME,VENDORNAME); //仅用于调试
            editor.putString(包名的packageName);
            editor.putString(类名的className);
            //提交的编辑!
            editor.commit();
            打破; //停止搜索,以避免设置不太适合选项
        }
    }
}


时钟应用的阵列是不完整的,它包含了一些常见的供应商。这里将是不要有任何这些应用程序的设备。你可以把其他厂商的应用程序的意见,我将它们编辑成阵。我用的应用程序系统调谐器找到我的设备包的信息。

在第一个窗口小部件放在包信息已经被保存在共享preferences。然后,UpdateService调用这些信息来创建挂起的意图每个小部件的更新时间。建议:更新所有悬而未决的意图和任何其他remoteviews更新,每次更新。这将美元重新启动或改变方向等发生p $ pvent的问题。

更新服务类


  

公共类UpdateService延伸服务{

 公共静态最后弦乐SHARED_ preFS =共享preFS
私人的PendingIntent的PendingIntent = NULL;@覆盖
公众诠释onStartCommand(意向意图,诠释标志诠释startId){    //从共享preferences数据
    共享preferences设置= getShared preferences(SHARED_ preFS,0);
    //检索每次你所有的preferences,更新一切
    INT背景= settings.getInt(背景,R.drawable.bg_box_light);
    //如果无法检索,设置默认为标准封装
    //如果不可用,窗口小部件点击会做什么。
    字符串的packageName = settings.getString(包名,com.android.alarmclock);
    串的className = settings.getString(类名,com.android.alarmclock.AlarmClock);    //获取所有小appwidgetmanager实例
    AppWidgetManager localAppWidgetManager = AppWidgetManager.getInstance(本);    //设置openAlarm PI
    软件包管理系统软件包管理系统= this.getPackageManager();
    意图alarmClockIntent =新意图(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_LAUNCHER);
    //从中检索包信息构建未决意图
    尝试{
        组件名CN =新的组件名(的packageName,className)已过时;
        packageManager.getActivityInfo(CN,PackageManager.GET_META_DATA);
        alarmClockIntent.setComponent(CN);
    }赶上(PackageManager.NameNotFoundException E){
        //日志或调试消息
    }
    的PendingIntent alarmPI = PendingIntent.getActivity(在此,0,alarmClockIntent,0);    //更新所有控件实例
    组件名thisWidget =新的组件名(getBaseContext(),WidgetProvider.class);
    INT [] = allWidgetIds localAppWidgetManager.getAppWidgetIds(thisWidget);
    对于(INT为widgetid:allWidgetIds){
        RemoteViews remoteViews =新的RemoteViews(getPackageName(),R.layout.widget_layout_name);
        //更新的一切,每一次。
        //无论是未更新可能会恢复到初始布局设置
        remoteViews.setImageViewResource(R.id.imageviewBG,背景);
        remoteViews.setOnClickPendingIntent(R.id.analogClock,alarmPI);
        localAppWidgetManager.updateAppWidget(为widgetid,remoteViews);
    }


如果你有一个以上的部件供应商,简单重复code从 //更新所有控件实例对每个供应商开始,并更改widget_layout_name。这code更新所有以同样的方式不同的部件布局。如果你想允许不同部件的布局有不同的preferences,您可以更改code来实现这一点 - 为每个插件布局创建唯一标识符,并有一组共享preferences每个布局。

Different phones and vendors have different clock apps. code is available that opens the app one some phones. Different answers give different lists and strategies, and they often have problems working.

解决方案

Reliable way to open clock apps on clicking a widget.

This code describes how the alarm or desk clock app can be opened by clicking the widget. It solves reliability problems with other solutions. It increases power economy by using Shared Preferences.

The code that finds the app for the phone is placed in onEnabled. It finds the app then saves the information in Shared Preferences, to be called by the Update Service. Once the first package is found, it stops searching. If you want to search for both the alarm and desk clock, place the preferred option higher in the array list. It doesnt do this search every time the widget is updated, conserving power. If your widget updates often, this will make a difference to battery life.

If you feel the user may change their alarm app, you could place the onEnabled code in a separate method in the WidgetProvider class. Then call it from onEnabled, and call it when you detect a change in the users clock package.

WIDGET PROVIDER CLASS

public class WidgetProvider extends AppWidgetProvider {

public static final String SHARED_PREFS = "SharedPrefs";
private PendingIntent pendingIntent = null;

@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {

    // start UpdateService whenever onUpdate is called
    Intent sIntent = new Intent(context, UpdateService.class);
    sIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    context.startService(sIntent);
}

@Override
public void onEnabled(Context context) {
    super.onEnabled(context);
    Log.w(LOG, "WidgetProvider.onEnabled triggered");

    // find the local alarm service

    // this is an incomplete array of alarm+clock services,
    // in an arbitrary order of priority.
    // you may need to change the order to suit your requirements
    String clockImpls[][] = {
     { "Standard Alarm", "com.android.alarmclock", "com.android.alarmclock.AlarmClock" },
     { "Sony Alarm", "com.sonyericsson.alarm", "com.sonyericsson.alarm.Alarm" },
     { "Sony Ericsson Xperia Z", "com.sonyericsson.organizer", "com.sonyericsson.organizer.Organizer_WorldClock" },
     { "ASUS Alarm Clock", "com.asus.alarmclock", "com.asus.alarmclock.AlarmClock" },
     { "ASUS Desk Clock", "com.asus.deskclock", "com.asus.deskclock.DeskClock" },
     { "HTC Alarm ClockDT", "com.htc.android.worldclock", "com.htc.android.worldclock.WorldClockTabControl" },
     { "Standard Alarm ClockDT", "com.android.deskclock", "com.android.deskclock.AlarmClock" },
     { "Froyo Nexus Alarm ClockDT", "com.google.android.deskclock", "com.android.deskclock.DeskClock" },
     { "Moto Blur Alarm ClockDT", "com.motorola.blur.alarmclock", "com.motorola.blur.alarmclock.AlarmClock" },
     { "Samsung Galaxy S", "com.sec.android.app.clockpackage", "com.sec.android.app.clockpackage.ClockPackage" }      
    };

    PackageManager packageManager = context.getPackageManager();
    Intent alarmClockIntent = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_LAUNCHER);
    boolean foundClockImpl = false;
    String vendorName = "";
    String packageName = "";
    String className = "";

    for(int i=0; i<clockImpls.length; i++) {
        vendorName = clockImpls[i][0]; // not needed, for debugging only
        packageName = clockImpls[i][1];
        className = clockImpls[i][2];
        try {
            ComponentName cn = new ComponentName(packageName, className);
            packageManager.getActivityInfo(cn, PackageManager.GET_META_DATA);
            alarmClockIntent.setComponent(cn);
            foundClockImpl = true;
        } catch (PackageManager.NameNotFoundException e) {
            // Log.w(LOG, "AlarmService couldnt retrieve activity info");
        }
        if (foundClockImpl) {
            // when the first package is found
            // send alarmCLockIntent to Shared Preferences
            // and break out of the for loop
            SharedPreferences settings = context.getSharedPreferences(SHARED_PREFS, 0);
            SharedPreferences.Editor editor = settings.edit();
            editor.putString("VendorName", vendorName); // only needed for debugging
            editor.putString("PackageName", packageName);
            editor.putString("ClassName", className);
            // Commit the edits!
            editor.commit();
            break;  // stop searching to avoid setting less suitable options
        }
    }
}

The array of clock apps is not complete, it includes a few common vendors. There will be devices that dont have any of these apps. You can put the apps of other vendors in the comments and i will edit them into the array. I used the app "System Tuner" to find the package info for my device.

The package info has been saved in Shared Preferences when the first widget is placed. Then, the UpdateService calls this information to create the pending intent each time the widget is updated. Recommendation: Update ALL the pending intents and any other remoteviews updates, EVERY TIME you update. This will prevent issues that occur on restart, or changing the orientation, etc.

UPDATE SERVICE CLASS

public class UpdateService extends Service {

public static final String SHARED_PREFS = "SharedPrefs";
private PendingIntent pendingIntent = null;

@Override
public int onStartCommand(Intent intent, int flags, int startId) {

    // retrieve data from shared preferences
    SharedPreferences settings = getSharedPreferences(SHARED_PREFS, 0);
    // retrieve all your preferences each time, update everything
    int background = settings.getInt("Background", R.drawable.bg_box_light);
    // if cannot retrieve, set default to standard package
    // if it is not available, widget click will do nothing.
    String packageName = settings.getString("PackageName", "com.android.alarmclock");
    String className = settings.getString("ClassName", "com.android.alarmclock.AlarmClock");

    // get appwidgetmanager instance for all widgets
    AppWidgetManager localAppWidgetManager = AppWidgetManager.getInstance(this);

    // set up openAlarm PI
    PackageManager packageManager = this.getPackageManager();
    Intent alarmClockIntent = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_LAUNCHER);
    // construct pending intent from retrieved package info
    try {
        ComponentName cn = new ComponentName(packageName, className);
        packageManager.getActivityInfo(cn, PackageManager.GET_META_DATA);
        alarmClockIntent.setComponent(cn);
    } catch (PackageManager.NameNotFoundException e) {
        // Log or debug message
    }
    PendingIntent alarmPI = PendingIntent.getActivity(this, 0, alarmClockIntent, 0);

    // update all widget instances
    ComponentName thisWidget = new ComponentName(getBaseContext(), WidgetProvider.class);
    int[] allWidgetIds = localAppWidgetManager.getAppWidgetIds(thisWidget);
    for (int widgetId : allWidgetIds) {
        RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.widget_layout_name);
        // update EVERYTHING, EVERY TIME.
        // whatever is not updated may revert to the initial layout settings
        remoteViews.setImageViewResource(R.id.imageviewBG, background);
        remoteViews.setOnClickPendingIntent(R.id.analogClock, alarmPI);
        localAppWidgetManager.updateAppWidget(widgetId, remoteViews);
    }

If you have more than one widget provider, simply duplicate the code starting from //update all widget instances for each provider, and change the widget_layout_name. This code updates all the different widget layouts in the same way. If you want to allow different widget layouts to have different preferences, you can change the code to achieve this - create unique identifiers for each widget layout, and have a set of shared preferences for each layout.

这篇关于机器人:通过点击小工具打开闹钟或时钟应用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆