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

177 lines
7.1 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
*
* 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;
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用于管理便签小部件的生命周期和更新逻辑。
*/
public abstract class NoteWidgetProvider extends AppWidgetProvider {
// 数据库查询所需字段
public static final String[] PROJECTION = new String[]{
NoteColumns.ID,
NoteColumns.BG_COLOR_ID,
NoteColumns.SNIPPET
};
// PROJECTION 的索引
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";
/**
* 当某个小部件被删除时调用。
* 删除小部件对应的数据库信息,将 WIDGET_ID 设置为无效值。
*/
@Override
public void onDeleted(Context context, int[] appWidgetIds) {
ContentValues values = new ContentValues();
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])});
}
}
/**
* 从数据库中获取指定小部件 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);
}
/**
* 更新指定小部件的显示内容(调用重载方法)。
*/
protected void update(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
update(context, appWidgetManager, appWidgetIds, false); // 默认非隐私模式
}
/**
* 更新小部件内容。
*
* @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 = ""; // 便签内容
// 创建启动 NoteEditActivity 的 Intent
Intent intent = new Intent(context, NoteEditActivity.class);
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; // 如果有多个便签对应同一小部件 ID返回错误
}
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)); // 设置背景图像
intent.putExtra(Notes.INTENT_EXTRA_BACKGROUND_ID, bgId);
// 根据隐私模式设置小部件显示和点击动作
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由子类实现
*/
protected abstract int getBgResourceId(int bgId);
/**
* 获取布局 ID由子类实现
*/
protected abstract int getLayoutId();
/**
* 获取小部件类型(由子类实现)。
*/
protected abstract int getWidgetType();
}