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.
triple6_practice/src/net/micode/notes/widget/NoteWidgetProvider.java

159 lines
6.6 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)
*
* 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
*
* 代码功能:小米便签桌面小部件提供者基类
* 主要负责:
* 1. 管理小部件的生命周期(创建/删除)
* 2. 更新小部件显示内容
* 3. 处理点击事件与便签的交互
*/
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;
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;
public static final int COLUMN_BG_COLOR_ID = 1;
public static final int COLUMN_SNIPPET = 2;
private static final String TAG = "NoteWidgetProvider"; // 日志标签
@Override
public void onDeleted(Context context, int[] appWidgetIds) {
// 当小部件被删除时清空关联的widget ID
ContentValues values = new ContentValues();
values.put(NoteColumns.WIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
for (int appWidgetId : appWidgetIds) {
// 更新数据库将对应widget ID设为无效
context.getContentResolver().update(
Notes.CONTENT_NOTE_URI,
values,
NoteColumns.WIDGET_ID + "=?",
new String[]{String.valueOf(appWidgetId)}
);
}
}
// 获取指定widget关联的便签信息
private Cursor getNoteWidgetInfo(Context context, int widgetId) {
return context.getContentResolver().query(
Notes.CONTENT_NOTE_URI,
PROJECTION,
// 查询条件匹配widget ID且不在回收站
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 appWidgetId : appWidgetIds) {
if (appWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) continue;
// 默认背景和内容
int bgId = ResourceParser.getDefaultBgId(context);
String snippet = "";
// 准备跳转到编辑页面的Intent
Intent intent = new Intent(context, NoteEditActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.putExtra(Notes.INTENT_EXTRA_WIDGET_ID, appWidgetId);
intent.putExtra(Notes.INTENT_EXTRA_WIDGET_TYPE, getWidgetType());
// 查询数据库获取便签信息
try (Cursor c = getNoteWidgetInfo(context, appWidgetId)) {
if (c != null && c.moveToFirst()) {
if (c.getCount() > 1) {
Log.e(TAG, "发现重复的widget ID关联多个便签: " + appWidgetId);
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); // 查看模式
} else {
// 无关联便签时的默认提示
snippet = context.getString(R.string.widget_havenot_content);
intent.setAction(Intent.ACTION_INSERT_OR_EDIT); // 新建模式
}
}
// 构建RemoteViews对象
RemoteViews rv = new RemoteViews(context.getPackageName(), getLayoutId());
// 设置背景资源
rv.setImageViewResource(R.id.widget_bg_image, getBgResourceId(bgId));
intent.putExtra(Notes.INTENT_EXTRA_BACKGROUND_ID, bgId);
// 构建PendingIntent
PendingIntent pendingIntent;
if (privacyMode) {
// 隐私模式:显示提示文字,点击进入列表页
rv.setTextViewText(R.id.widget_text, context.getString(R.string.widget_under_visit_mode));
pendingIntent = PendingIntent.getActivity(
context,
appWidgetId,
new Intent(context, NotesListActivity.class),
PendingIntent.FLAG_UPDATE_CURRENT
);
} else {
// 正常模式:显示便签内容,点击进入编辑页
rv.setTextViewText(R.id.widget_text, snippet);
pendingIntent = PendingIntent.getActivity(
context,
appWidgetId,
intent,
PendingIntent.FLAG_UPDATE_CURRENT
);
}
// 设置点击事件
rv.setOnClickPendingIntent(R.id.widget_text, pendingIntent);
// 更新小部件
appWidgetManager.updateAppWidget(appWidgetId, rv);
}
}
// 抽象方法(需要子类实现)
protected abstract int getBgResourceId(int bgId); // 获取实际背景资源ID
protected abstract int getLayoutId(); // 获取小部件布局ID
protected abstract int getWidgetType(); // 获取小部件类型标识
}