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.
5MI/NoteWidgetProvider (2).java

164 lines
8.3 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)
* 以下是MiCode开源社区的版权声明表明该文件的版权所有者为MiCode开源社区并提供了网站链接。
*
* 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
* 该文件遵循Apache 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;
// 声明该文件属于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用于提供便签应用的小部件功能。
public abstract class NoteWidgetProvider extends AppWidgetProvider {
// 定义一个字符串数组,用于数据库查询时指定需要返回的列。
public static final String [] PROJECTION = new String [] {
NoteColumns.ID,
NoteColumns.BG_COLOR_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) {
ContentValues values = new ContentValues();
values.put(NoteColumns.WIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
for (int i = 0; i < appWidgetIds.length; i++) {
// 更新数据库将被删除小部件的WIDGET_ID设置为INVALID_APPWIDGET_ID。
context.getContentResolver().update(Notes.CONTENT_NOTE_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,
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);
}
// 更新小部件显示的私有方法,包含隐私模式参数。
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) {
// 获取默认背景ID。
int bgId = ResourceParser.getDefaultBgId(context);
// 初始化便签摘要字符串。
String snippet = "";
// 创建一个Intent用于启动NoteEditActivity。
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);
intent.putExtra(Intent.EXTRA_UID, c.getLong(COLUMN_ID));
intent.setAction(Intent.ACTION_VIEW);
} else {
// 如果没有查询到记录设置默认摘要文本并设置Intent动作为插入或编辑。
snippet = context.getResources().getString(R.string.widget_havenot_content);
intent.setAction(Intent.ACTION_INSERT_OR_EDIT);
}
// 关闭查询结果的Cursor。
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。
intent.putExtra(Notes.INTENT_EXTRA_BACKGROUND_ID, bgId);
/**
* Generate the pending intent to start host for the widget.
* 生成用于启动小部件宿主的PendingIntent。
*/
PendingIntent pendingIntent = null;
if (privacyMode) {
// 如果启用隐私模式设置小部件文本为隐私模式提示并创建PendingIntent以启动NotesListActivity。
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 {
// 如果不启用隐私模式设置小部件文本为便签摘要并创建PendingIntent以启动NoteEditActivity。
rv.setTextViewText(R.id.widget_text, snippet);
pendingIntent = PendingIntent.getActivity(context, appWidgetIds[i], intent,
PendingIntent.FLAG_UPDATE_CURRENT);
}
// 设置小部件文本视图的点击事件关联到PendingIntent。
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();
}