You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
MiNote/src/widget/NoteWidgetProvider.java

206 lines
9.0 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/*
* 版权所有 (c) 2010-2011MiCode 开源社区 (www.micode.net)
* 根据 Apache 许可证 2.0 版本("许可证")授权;
* 除非符合许可证的规定,否则不得使用本文件。
* 您可以从以下网址获取许可证副本:
* http://www.apache.org/licenses/LICENSE-2.0
* 除非适用法律要求或书面同意,本软件按"原样"分发,
* 没有任何明示或暗示的保证或条件。
* 详见许可证中规定的权限和限制。
* 这是一份标准的Apache许可证2.0版本的开源声明)
*/
// 定义包路径
package net.micode.notes.widget;
// 导入Android相关类
import android.app.PendingIntent; // 延时意图
import android.appwidget.AppWidgetManager; // 小部件管理器
import android.appwidget.AppWidgetProvider; // 小部件提供者基类
import android.content.ContentValues; // 内容值对象
import android.content.Context; // 上下文对象
import android.content.Intent; // 意图对象
import android.database.Cursor; // 数据库游标
import android.util.Log; // 日志工具
import android.widget.RemoteViews; // 远程视图用于小部件UI
// 导入项目资源
import net.micode.notes.R; // 项目资源文件
// 导入项目数据类
import net.micode.notes.data.Notes; // 笔记常量
import net.micode.notes.data.Notes.NoteColumns; // 笔记列定义
// 导入工具类
import net.micode.notes.tool.ResourceParser; // 资源解析工具
// 导入Activity类
import net.micode.notes.ui.NoteEditActivity; // 笔记编辑界面
import net.micode.notes.ui.NotesListActivity; // 笔记列表界面
/**
* 抽象笔记小部件提供者类
* 提供笔记小部件的基本功能,具体样式由子类实现
*/
public abstract class NoteWidgetProvider extends AppWidgetProvider {
// 笔记查询投影列定义
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; // 背景颜色列索引
public static final int COLUMN_SNIPPET = 2; // 摘要列索引
private static final String TAG = "NoteWidgetProvider"; // 日志标签
/**
* 当小部件被删除时调用
* @param context 上下文对象
* @param appWidgetIds 被删除的小部件ID数组
*/
@Override
public void onDeleted(Context context, int[] appWidgetIds) {
// 创建内容值对象,用于更新数据库
ContentValues values = new ContentValues();
// 将笔记的小部件ID设为无效值
values.put(NoteColumns.WIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
// 遍历所有被删除的小部件ID
for (int i = 0; i < appWidgetIds.length; i++) {
// 更新数据库,解除笔记与小部件的关联
context.getContentResolver().update(Notes.CONTENT_NOTE_URI,
values,
NoteColumns.WIDGET_ID + "=?", // 更新条件
new String[] { String.valueOf(appWidgetIds[i])}); // 参数值
}
}
/**
* 获取与小部件关联的笔记信息
* @param context 上下文对象
* @param widgetId 小部件ID
* @return 包含笔记信息的游标对象
*/
private Cursor getNoteWidgetInfo(Context context, int widgetId) {
// 查询数据库获取关联的笔记信息
return context.getContentResolver().query(Notes.CONTENT_NOTE_URI,
PROJECTION, // 查询列
// 查询条件匹配小部件ID且不在回收站中
NoteColumns.WIDGET_ID + "=? AND " + NoteColumns.PARENT_ID + "<>?",
new String[] { String.valueOf(widgetId), String.valueOf(Notes.ID_TRASH_FOLER) },
null); // 无排序
}
/**
* 更新小部件(公开方法)
* @param context 上下文对象
* @param appWidgetManager 小部件管理器
* @param appWidgetIds 需要更新的小部件ID数组
*/
protected void update(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
update(context, appWidgetManager, appWidgetIds, false); // 默认非隐私模式
}
/**
* 更新小部件(私有方法)
* @param context 上下文对象
* @param appWidgetManager 小部件管理器
* @param appWidgetIds 需要更新的小部件ID数组
* @param privacyMode 是否为隐私模式
*/
private void update(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds,
boolean privacyMode) {
// 遍历所有需要更新的小部件
for (int i = 0; i < appWidgetIds.length; i++) {
// 检查小部件ID是否有效
if (appWidgetIds[i] != AppWidgetManager.INVALID_APPWIDGET_ID) {
int bgId = ResourceParser.getDefaultBgId(context); // 获取默认背景ID
String snippet = ""; // 笔记摘要
// 创建编辑笔记的Intent
Intent intent = new Intent(context, NoteEditActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); // 设置启动模式
// 添加小部件ID到Intent
intent.putExtra(Notes.INTENT_EXTRA_WIDGET_ID, appWidgetIds[i]);
// 添加小部件类型到Intent
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); // 获取背景ID
intent.putExtra(Intent.EXTRA_UID, c.getLong(COLUMN_ID)); // 添加笔记ID
intent.setAction(Intent.ACTION_VIEW); // 设置操作为查看
} else {
// 如果没有关联的笔记,显示默认文本
snippet = context.getResources().getString(R.string.widget_havenot_content);
intent.setAction(Intent.ACTION_INSERT_OR_EDIT); // 设置操作为新建
}
// 关闭游标
if (c != null) {
c.close();
}
// 创建远程视图
RemoteViews rv = new RemoteViews(context.getPackageName(), getLayoutId());
// 设置背景图片
rv.setImageViewResource(R.id.widget_bg_image, getBgResourceId(bgId));
// 添加背景ID到Intent
intent.putExtra(Notes.INTENT_EXTRA_BACKGROUND_ID, bgId);
/**
* 生成启动宿主Activity的延时意图
*/
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(
context, NotesListActivity.class), PendingIntent.FLAG_UPDATE_CURRENT);
} else {
// 正常模式显示笔记摘要
rv.setTextViewText(R.id.widget_text, snippet);
// 点击跳转到笔记编辑界面
pendingIntent = PendingIntent.getActivity(context, appWidgetIds[i], intent,
PendingIntent.FLAG_UPDATE_CURRENT);
}
// 设置点击事件
rv.setOnClickPendingIntent(R.id.widget_text, pendingIntent);
// 更新小部件
appWidgetManager.updateAppWidget(appWidgetIds[i], rv);
}
}
}
/**
* 抽象方法获取背景资源ID
* @param bgId 背景颜色ID
* @return 对应的背景资源ID
*/
protected abstract int getBgResourceId(int bgId);
/**
* 抽象方法获取布局ID
* @return 小部件布局资源ID
*/
protected abstract int getLayoutId();
/**
* 抽象方法:获取小部件类型
* @return 小部件类型标识
*/
protected abstract int getWidgetType();
}