/* * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package net.micode.notes.widget; //隶属于widget这个包中 import android.app.PendingIntent; //在Android.app包中的,用于提供暂缓的服务,当某种条件达到时,就可以执行某些活动 import android.appwidget.AppWidgetManager; //继承object类,更新appwidget状态,和获取安装appwidget提供信息,以及其它相关状态信息。 import android.appwidget.AppWidgetProvider; //本质是广播作用,用来对widget进行更新 import android.content.ContentValues; //此类用于存储ContentResolver 可以处理的一组值,是一些基本类型的值 import android.content.Context; //可以理解为一个接口(抽象类),它提供了有关应用程序的全局信息。从它继承或者从它的直接或间接子类继承,那么继承的子类就可以拿到应用程序的全局信息。 import android.content.Intent; //联系各个Activity的关键对象。告诉android该做什么 import android.database.Cursor; //是数据库指针,用于查询并操作数据 import android.util.Log; //更新删改等的日志文件 import android.widget.RemoteViews; //它表示的是一个View结构,可以在其他进程中显示,小部件的旋转效果则是通过不断地更新RemoteViews来实现的 import net.micode.notes.R; import net.micode.notes.data.Notes; //引入其他包中类 import net.micode.notes.data.Notes.NoteColumns; //引入笔记换列的类 import net.micode.notes.tool.ResourceParser; //引入工具类 import net.micode.notes.ui.NoteEditActivity; //引入ui包中的编辑笔记类 import net.micode.notes.ui.NotesListActivity; //引入ui包中的列表活动类 public abstract class NoteWidgetProvider extends AppWidgetProvider { //继承AppWidgetProvider的抽象类NoteWidgetProvider,可以给子类提供接口 public static final String [] PROJECTION = new String [] { //最终静态字符串数组 NoteColumns.ID, //笔记框ID号 NoteColumns.BG_COLOR_ID, //笔记框颜色ID NoteColumns.SNIPPET //一小段笔记框 }; public static final int COLUMN_ID = 0; //最终静态笔记框ID号 public static final int COLUMN_BG_COLOR_ID = 1; //最终静态笔记框颜色ID public static final int COLUMN_SNIPPET = 2; //最终静态一小段笔记框 private static final String TAG = "NoteWidgetProvider"; //最终静态 TAG @Override //重写 public void onDeleted(Context context, int[] appWidgetIds) { //方法,删除部件 ContentValues values = new ContentValues(); //和Bundle类一样,键值对 values.put(NoteColumns.WIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID); //通过put来存放数据。大多是基础数据类型 for (int i = 0; i < appWidgetIds.length; i++) { context.getContentResolver().update(Notes.CONTENT_NOTE_URI, //根据长度批量修改数据,uri表名, 属性键值对,修改对象,修改内容 values, NoteColumns.WIDGET_ID + "=?", new String[] { String.valueOf(appWidgetIds[i])}); } } //操作数据库,查询操作 private Cursor getNoteWidgetInfo(Context context, int widgetId) { //得到一些部件的信息和全局消息,返回类型为游标 return context.getContentResolver().query(Notes.CONTENT_NOTE_URI, //查找数据,并返回含有数据信息的cursor对象。 PROJECTION, //参数为 uri 查询表名,查询列名,属性,属性域值,排序 NoteColumns.WIDGET_ID + "=? AND " + NoteColumns.PARENT_ID + "<>?", new String[] { String.valueOf(widgetId), String.valueOf(Notes.ID_TRASH_FOLER) }, null); } protected void update(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { //更新部件 update(context, appWidgetManager, appWidgetIds, false); } private void update(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds, //隐私模式下更新相关部件 boolean privacyMode) { for (int i = 0; i < appWidgetIds.length; i++) { if (appWidgetIds[i] != AppWidgetManager.INVALID_APPWIDGET_ID) { int bgId = ResourceParser.getDefaultBgId(context); String snippet = ""; Intent intent = new Intent(context, NoteEditActivity.class); //意图,从context到NoteEditActivity类的意图 intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); //设置标志,当栈顶为活动实例时,重用该实例,不用新建 intent.putExtra(Notes.INTENT_EXTRA_WIDGET_ID, appWidgetIds[i]); //传递参数 intent.putExtra(Notes.INTENT_EXTRA_WIDGET_TYPE, getWidgetType()); Cursor c = getNoteWidgetInfo(context, appWidgetIds[i]); //数据库光标,用于读取数据库 if (c != null && c.moveToFirst()) { if (c.getCount() > 1) { Log.e(TAG, "Multiple message with same widget id:" + appWidgetIds[i]); //日志信息,打印错误 c.close(); return; } snippet = c.getString(COLUMN_SNIPPET); bgId = c.getInt(COLUMN_BG_COLOR_ID); intent.putExtra(Intent.EXTRA_UID, c.getLong(COLUMN_ID)); //传递参数 intent.setAction(Intent.ACTION_VIEW); //隐式intent,设置意图,参数为向用户展示意图。 } else { snippet = context.getResources().getString(R.string.widget_havenot_content); intent.setAction(Intent.ACTION_INSERT_OR_EDIT); //隐式intent,设置联系人 } if (c != null) { //关闭 c.close(); } RemoteViews rv = new RemoteViews(context.getPackageName(), getLayoutId()); //布局文件layout的远程视图 rv.setImageViewResource(R.id.widget_bg_image, getBgResourceId(bgId)); //设置图像资源,从布局文件layout中找到ID intent.putExtra(Notes.INTENT_EXTRA_BACKGROUND_ID, bgId); //产生待定意图 /** * Generate the pending intent to start host for the widget */ PendingIntent pendingIntent = null; //待定意图,等待触发时机 if (privacyMode) { //隐私模式 rv.setTextViewText(R.id.widget_text, //设置视图文本 context.getString(R.string.widget_under_visit_mode)); pendingIntent = PendingIntent.getActivity(context, appWidgetIds[i], new Intent( //开始意图启动Activity context, NotesListActivity.class), PendingIntent.FLAG_UPDATE_CURRENT); //上下文,请求码,跳转对象, } else { //FLAG_UPDATE_CURRENT当前描述的PendingIntent如果已经存在,那么它们都会被更新,即它们的Intent中的Extras会被替换成最新的 rv.setTextViewText(R.id.widget_text, snippet); pendingIntent = PendingIntent.getActivity(context, appWidgetIds[i], intent, //先前的意图 PendingIntent.FLAG_UPDATE_CURRENT); } //FLAG_UPDATE_CURRENT当前描述的PendingIntent如果已经存在,那么它们都会被更新,即它们的Intent中的Extras会被替换成最新的 rv.setOnClickPendingIntent(R.id.widget_text, pendingIntent); //启动点击待定意图 appWidgetManager.updateAppWidget(appWidgetIds[i], rv); //更新部件 } } } protected abstract int getBgResourceId(int bgId); //抽象类获取Bg资源ID protected abstract int getLayoutId(); //抽象方法获取布局ID protected abstract int getWidgetType(); //获取部件的种类 }