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.
xiaomi/NoteWidgetProvider.java

175 lines
8.8 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.

/*
* Copyright (c) 2010 - 2011, The MiCode Open Source Community (www.micode.net)
*
* 遵循 Apache 许可证 2.0 版(“许可证”);
* 除非遵守许可证,否则不得使用此文件。
* 你可以在以下网址获取许可证副本:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 除非适用法律要求或书面同意,
* 根据许可证分发的软件按“原样”分发,
* 不令任何明示或暗示的保证或条件。
* 请参阅许可证,了解具体的权限和限制。
*/
package net.micode.notes.widget;
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;
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;
import net.micode.notes.ui.NotesListActivity;
// NoteWidgetProvider 是一个抽象类,继承自 AppWidgetProvider用于创建和管理便签小部件包括处理小部件的删除、更新等操作并提供了抽象方法供子类实现以获取小部件的资源 ID 和布局 ID 等信息
public abstract class NoteWidgetProvider extends AppWidgetProvider {
// 用于查询笔记小部件信息的投影数组
public static final String[] PROJECTION = new String[]{
NoteColumns.ID,
NoteColumns.BG_COLOR_ID,
NoteColumns.SNIPPET
};
// 投影数组中 ID 列的索引
public static final int COLUMN_ID = 0;
// 投影数组中 BG_COLOR_ID 列的索引
public static final int COLUMN_BG_COLOR_ID = 1;
// 投影数组中 SNIPPET 列的索引
public static final int COLUMN_SNIPPET = 2;
// 用于日志记录的标签,使用类的简单名称
private static final String TAG = "NoteWidgetProvider";
// 当小部件被删除时调用的方法
@Override
public void onDeleted(Context context, int[] appWidgetIds) {
// 创建一个 ContentValues 对象,用于更新笔记数据
ContentValues values = new ContentValues();
// 将笔记的小部件 ID 设置为无效值
values.put(NoteColumns.WIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
// 遍历被删除的小部件 ID 数组
for (int i = 0; i < appWidgetIds.length; i++) {
// 使用内容解析器更新与该小部件 ID 相关的笔记数据
context.getContentResolver().update(Notes.CONTENT_NOTE_URI,
values,
NoteColumns.WIDGET_ID + "=?",
new String[]{String.valueOf(appWidgetIds[i])});
}
}
// 获取指定小部件 ID 的笔记小部件信息的方法
private Cursor getNoteWidgetInfo(Context context, int widgetId) {
// 通过内容解析器查询符合条件的笔记小部件信息
return context.getContentResolver().query(Notes.CONTENT_NOTE_URI,
PROJECTION,
NoteColumns.WIDGET_ID + "=? AND " + NoteColumns.PARENT_ID + "<>?",
new String[]{String.valueOf(widgetId), String.valueOf(Notes.ID_TRASH_FOLER)},
null);
}
// 更新小部件的方法,调用了另一个带有隐私模式参数的更新方法,默认隐私模式为 false
protected void update(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
update(context, appWidgetManager, appWidgetIds, false);
}
// 实际的更新小部件的方法,根据小部件 ID 数组更新每个小部件的显示内容和点击事件
private void update(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds,
boolean privacyMode) {
// 遍历小部件 ID 数组
for (int i = 0; i < appWidgetIds.length; i++) {
// 如果小部件 ID 有效
if (appWidgetIds[i]!= AppWidgetManager.INVALID_APPWIDGET_ID) {
// 获取默认的背景颜色 ID
int bgId = ResourceParser.getDefaultBgId(context);
// 初始化笔记片段内容为空字符串
String snippet = "";
// 创建一个意图,用于启动 NoteEditActivity
Intent intent = new Intent(context, NoteEditActivity.class);
// 设置意图的标志,确保只有一个实例在栈顶
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
// 将小部件 ID 添加到意图的额外数据中
intent.putExtra(Notes.INTENT_EXTRA_WIDGET_ID, appWidgetIds[i]);
// 将小部件类型添加到意图的额外数据中,由子类实现具体类型
intent.putExtra(Notes.INTENT_EXTRA_WIDGET_TYPE, getWidgetType());
// 获取指定小部件 ID 的笔记小部件信息
Cursor c = getNoteWidgetInfo(context, appWidgetIds[i]);
// 如果查询结果不为空且游标可以移动到第一条记录
if (c!= null && c.moveToFirst()) {
// 如果查询结果数量大于 1表示存在多个相同小部件 ID 的笔记,记录错误日志并关闭游标,返回
if (c.getCount() > 1) {
Log.e(TAG, "Multiple message with same widget id:" + appWidgetIds[i]);
c.close();
return;
}
// 获取笔记片段内容
snippet = c.getString(COLUMN_SNIPPET);
// 获取背景颜色 ID
bgId = c.getInt(COLUMN_BG_COLOR_ID);
// 将笔记 ID 添加到意图的额外数据中
intent.putExtra(Intent.EXTRA_UID, c.getLong(COLUMN_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 对象,用于设置小部件的布局和内容
RemoteViews rv = new RemoteViews(context.getPackageName(), getLayoutId());
// 设置小部件的背景图片资源 ID
rv.setImageViewResource(R.id.widget_bg_image, getBgResourceId(bgId));
// 将背景颜色 ID 添加到意图的额外数据中
intent.putExtra(Notes.INTENT_EXTRA_BACKGROUND_ID, bgId);
/**
* 生成一个 PendingIntent用于在小部件被点击时启动相应的活动
*/
PendingIntent pendingIntent = null;
if (privacyMode) {
// 如果处于隐私模式,设置小部件的文本内容为隐私模式提示文本,并创建一个用于启动 NotesListActivity 的 PendingIntent
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 {
// 如果不处于隐私模式,设置小部件的文本内容为笔记片段内容,并创建一个用于启动 NoteEditActivity 的 PendingIntent
rv.setTextViewText(R.id.widget_text, snippet);
pendingIntent = PendingIntent.getActivity(context, appWidgetIds[i], intent,
PendingIntent.FLAG_UPDATE_CURENT);
}
// 设置小部件文本的点击事件为 PendingIntent
rv.setOnClickPendingIntent(R.id.widget_text, pendingIntent);
// 使用 AppWidgetManager 更新小部件的显示
appWidgetManager.updateAppWidget(appWidgetIds[i], rv);
}
}
}
// 抽象方法,用于获取小部件的背景资源 ID由子类实现
protected abstract int getBgResourceId(int bgId);
// 抽象方法,用于获取小部件的布局 ID由子类实现
protected abstract int getLayoutId();
// 抽象方法,用于获取小部件的类型,由子类实现
protected abstract int getWidgetType();
}