0
点赞
收藏
分享

微信扫一扫

Pro Android学习笔记(一三七):Home Screen Widgets(3):配置Activity


作者@恺风Wei。

通过widget定义,我们在widget列表中看到了我们的TestWidget,当我们拖拽widget到主页时,如果在appwidet-provider中定义了android:configure的java类,在widget实例创建后会马上唤起配置activity。这个activity主要完成两个任务:1、配置初始化数据;2、将配置数据适配到widget实例中。

利用preference中存贮配置数据

widget数据可以保持在文件、Share preference,或者SQLite3中。widget作为小工具配置数据量小,通常可以方便地存贮在preference中。preference中数据存贮和读取使用BirthDayStoreData类来处理。我们在Pro Android学习笔记(六三):Preferences(7):代码控制首选项中的“利用preference保存状态”已经介绍过如何实现,在此,复习一下。

我们需要存贮的内容有widgetID,名字,生日,Preference是以键值对的方式保存,我们以name_widgetID作为key,生日作为value来进行信息存贮。

public class BirthDayStoreData { 
     private final static String BIRTHDAY_WIDGET_PROVIDER_NAME = "cn.wei.flowingflying.testwidget.provider"; 

     //保存配置数据:创建widget实例,通过configure activity进行配置时,保存相关配置数据 
     public static void storeData(Context context,int widgetId, String name,String value){
         String key = getKey(widgetId,name);            
        //第一个参数是preferences文件,如果不存在则创建之。具体为/data/data/cn.wei.flowingflying.testwidget/shared_prefs/cn.wei.flowingflying.testwidget.provider.xml,可以在DDMS中查看。
         Editor editor = context.getSharedPreferences(BIRTHDAY_WIDGET_PROVIDER_NAME, Context.MODE_PRIVATE).edit();
         editor.putString(key, value); 
         editor.commit();    
     } 

     //删除配置数据:删除widget实例的同时,需要删除该实例的相关数据
     public static void removeData(Context context, int widgetId){ 
         String key = getKeyById(context, widgetId); 
         if(key == null) 
             return; 
         Editor editor = context.getSharedPreferences(BIRTHDAY_WIDGET_PROVIDER_NAME, Context.MODE_PRIVATE).edit();
         editor.remove(key);         editor.commit(); 
     } 
     //清空全部的配置数据     public static void removeAllData(Context context){ 
         Editor editor = context.getSharedPreferences(BIRTHDAY_WIDGET_PROVIDER_NAME, Context.MODE_PRIVATE).edit();
         editor.clear(); 
         editor.commit();        
     }    

     //显示配置数据:用于我们在LogCat中进行跟踪,在此,我们也演示了如何通过轮询方式,显示全部的数据,通过类似的方式,我们可以同widgetId查得对应的名字和生日,通过类似的方法,可根据widgetId查询key,名字,生日,相关代码从略。
    public static void showData(Context context){ 
         SharedPreferences prefs = context.getSharedPreferences(BIRTHDAY_WIDGET_PROVIDER_NAME, Context.MODE_PRIVATE);
         Map<String,?> pairs = prefs.getAll();          Log.d("DATA","Total " + pairs.size() + " widgets:");
         for(String key:pairs.keySet()){ 
            String value = (String)pairs.get(key); 
             Log.d("DATA",key + " - " + value);
        } 
     }  
      
     public static String getNameById(Context context, int widgetId){ 
         … … 
     } 
     
     public static String getDateById(Context context ,int widgetId){ 
         … …   
     } 
     
     private static String getKey(int widgetId, String name){ 
         return name + "_" + widgetId; 
     }   
      
     private static String getKeyById(Context context,int widgetId){  
         … … 
     }  
     
 }

配置初始化数据

配置configure activity的代码如下:

public class ConfigBirthDayWidgetActivity extends Activity{ 
     private static String tag = "ConfigActivity"; 
     private int myWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID; 
     
     @Override //配置activity的操作和普通activity的一样,但在被AppWidgetManage唤起时,intent是携带widgetId的信息,我们在onCreate()中获取Widget ID。 
     protected void onCreate(Bundle savedInstanceState) { 
        … …  
         Intent intent = getIntent(); 
         Bundle b = intent.getExtras();         if(b != null){ 
             myWidgetId = b.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID,AppWidgetManager.INVALID_APPWIDGET_ID);           
         } 
         
         if(myWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID){  
             Toast.makeText(this, "Widget Error : 无有效widget ID", Toast.LENGTH_LONG).show();
             finish(); 
         }  

     } 
     
     .. ….  
      
    //点击配置button后调用的方法 
    private void getAndStoreConfigInfo(){  
         … …  String name为用户输入名字,String date为用户输入的有效日期
        //【1】在preference中保持数据,并显示所有数据         BirthDayStoreData.storeData(this, myWidgetId, name, date);
         BirthDayStoreData.showData(this); 
        //【2】将配置数据与具体的widget实例相关联,具体实现见后面
         BirthDayStoreData.updateAppWidget(this, myWidgetId,name, date); 
         
         //【3】将结果返回给AppWidget Manager,以通知它Configurator已经完成。作用如同startActivityForResult()给出返回值,通知AppWidgetManager某个widgetId已经完成配置,可以在主页上显示创建的widget实例 
         Intent resultIntent = new Intent(); 
         resultIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, myWidgetId);
         setResult(RESULT_OK, resultIntent); 
        //【4】关闭activity
         finish(); 
     }      
 }

配置数据适配到widget实例中

Widget实例的view要通过RemoteViews进行控制,小例子采用静态方法的方式,代码片段如下:

public class BirthDayStoreData {  
     ... ... 
       
     public static void updateAppWidget(Context context,int widgetId,String name, String date){
        //【1】设置Remote view的信息 
         // 1.1)、获得remote view对象
         RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.birday_widget);
         // 1.2)、对remote view进行setText()设置
        views.setTextViewText(R.id.bd_name, widgetId + ":" + name);
         views.setTextViewText(R.id.bd_date, date);  
         views.setTextViewText(R.id.bd_days, Long.toString(Utils.howFarInDays(Utils.getDate(date))));//Utils是处理日期的类
         // 1.3)、通过PendingIntent设置某个view的点击处理,采用intent方式,可以打开activity,service,receiver等等。本小例子将打开某个网页 
         Intent intent = new Intent(Intent.ACTION_VIEW,Uri.parse("http://www.taobao.com"));
         PendingIntent pi = PendingIntent.getActivity(context, 0, intent, 0); 
         views.setOnClickPendingIntent(R.id.bd_buy, pi); 
         
         //【2】通过AppWidgetManger,具体实施到widgetId实例上。
         AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
         appWidgetManager.updateAppWidget(widgetId,views); 
     } 
     
    public static void updateAppWidget(Context context,int widgetId){
         … …  
     } 
 }

小例子代码在:Pro Android学习:widget小例子


举报

相关推荐

0 条评论