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.

446 lines
16 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.
*/
/**
* 文件: DataUtils.java
* 描述: 便签数据操作工具类,提供便签数据的批量处理和查询功能
* 作用: 封装对便签数据的各种操作,如批量删除、移动便签、查询便签信息等
*/
package net.micode.notes.tool;
import android.content.ContentProviderOperation;
import android.content.ContentProviderResult;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.OperationApplicationException;
import android.database.Cursor;
import android.os.RemoteException;
import android.util.Log;
import net.micode.notes.data.Notes;
import net.micode.notes.data.Notes.CallNote;
import net.micode.notes.data.Notes.NoteColumns;
import net.micode.notes.ui.NotesListAdapter.AppWidgetAttribute;
import java.util.ArrayList;
import java.util.HashSet;
/**
* 便签数据操作工具类
*
* 提供便签数据的批量操作和查询功能,包括批量删除、移动便签、查询便签信息等
* 所有方法都是静态的,可以直接通过类名调用
*/
public class DataUtils {
public static final String TAG = "DataUtils";
/**
* 批量删除便签
*
* @param resolver 内容解析器
* @param ids 要删除的便签ID集合
* @return 删除成功返回true失败返回false
*/
public static boolean batchDeleteNotes(ContentResolver resolver, HashSet<Long> ids) {
// 检查参数有效性
if (ids == null) {
Log.d(TAG, "the ids is null");
return true;
}
if (ids.size() == 0) {
Log.d(TAG, "no id is in the hashset");
return true;
}
// 创建批量操作列表
ArrayList<ContentProviderOperation> operationList = new ArrayList<ContentProviderOperation>();
for (long id : ids) {
// 不允许删除根文件夹
if(id == Notes.ID_ROOT_FOLDER) {
Log.e(TAG, "Don't delete system folder root");
continue;
}
// 为每个便签ID创建删除操作
ContentProviderOperation.Builder builder = ContentProviderOperation
.newDelete(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, id));
operationList.add(builder.build());
}
try {
// 执行批量操作
ContentProviderResult[] results = resolver.applyBatch(Notes.AUTHORITY, operationList);
// 检查操作结果
if (results == null || results.length == 0 || results[0] == null) {
Log.d(TAG, "delete notes failed, ids:" + ids.toString());
return false;
}
return true;
} catch (RemoteException e) {
// 远程异常处理
Log.e(TAG, String.format("%s: %s", e.toString(), e.getMessage()));
} catch (OperationApplicationException e) {
// 操作应用异常处理
Log.e(TAG, String.format("%s: %s", e.toString(), e.getMessage()));
}
return false;
}
/**
* 将便签移动到指定文件夹
*
* @param resolver 内容解析器
* @param id 便签ID
* @param srcFolderId 源文件夹ID
* @param desFolderId 目标文件夹ID
*/
public static void moveNoteToFoler(ContentResolver resolver, long id, long srcFolderId, long desFolderId) {
// 创建更新数据
ContentValues values = new ContentValues();
values.put(NoteColumns.PARENT_ID, desFolderId); // 设置新的父文件夹ID
values.put(NoteColumns.ORIGIN_PARENT_ID, srcFolderId); // 保存原始父文件夹ID
values.put(NoteColumns.LOCAL_MODIFIED, 1); // 标记为本地已修改
// 更新便签数据
resolver.update(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, id), values, null, null);
}
/**
* 批量将便签移动到指定文件夹
*
* @param resolver 内容解析器
* @param ids 要移动的便签ID集合
* @param folderId 目标文件夹ID
* @return 移动成功返回true失败返回false
*/
public static boolean batchMoveToFolder(ContentResolver resolver, HashSet<Long> ids,
long folderId) {
// 检查参数有效性
if (ids == null) {
Log.d(TAG, "the ids is null");
return true;
}
// 创建批量操作列表
ArrayList<ContentProviderOperation> operationList = new ArrayList<ContentProviderOperation>();
for (long id : ids) {
// 为每个便签ID创建更新操作
ContentProviderOperation.Builder builder = ContentProviderOperation
.newUpdate(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, id));
builder.withValue(NoteColumns.PARENT_ID, folderId); // 设置新的父文件夹ID
builder.withValue(NoteColumns.LOCAL_MODIFIED, 1); // 标记为本地已修改
operationList.add(builder.build());
}
try {
// 执行批量操作
ContentProviderResult[] results = resolver.applyBatch(Notes.AUTHORITY, operationList);
// 检查操作结果
if (results == null || results.length == 0 || results[0] == null) {
Log.d(TAG, "delete notes failed, ids:" + ids.toString());
return false;
}
return true;
} catch (RemoteException e) {
// 远程异常处理
Log.e(TAG, String.format("%s: %s", e.toString(), e.getMessage()));
} catch (OperationApplicationException e) {
// 操作应用异常处理
Log.e(TAG, String.format("%s: %s", e.toString(), e.getMessage()));
}
return false;
}
/**
* 获取用户文件夹数量(不包括系统文件夹)
*
* @param resolver 内容解析器
* @return 用户文件夹数量
*/
public static int getUserFolderCount(ContentResolver resolver) {
// 查询类型为文件夹且不在回收站中的记录数量
Cursor cursor = resolver.query(Notes.CONTENT_NOTE_URI,
new String[] { "COUNT(*)" },
NoteColumns.TYPE + "=? AND " + NoteColumns.PARENT_ID + "<>?",
new String[] { String.valueOf(Notes.TYPE_FOLDER), String.valueOf(Notes.ID_TRASH_FOLER)},
null);
int count = 0;
if(cursor != null) {
if(cursor.moveToFirst()) {
try {
// 获取查询结果中的计数值
count = cursor.getInt(0);
} catch (IndexOutOfBoundsException e) {
// 索引越界异常处理
Log.e(TAG, "get folder count failed:" + e.toString());
} finally {
// 确保关闭游标
cursor.close();
}
}
}
return count;
}
/**
* 检查指定ID和类型的便签是否可见不在回收站中
*
* @param resolver 内容解析器
* @param noteId 便签ID
* @param type 便签类型
* @return 如果便签可见返回true否则返回false
*/
public static boolean visibleInNoteDatabase(ContentResolver resolver, long noteId, int type) {
// 查询指定ID和类型的便签且不在回收站中
Cursor cursor = resolver.query(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, noteId),
null,
NoteColumns.TYPE + "=? AND " + NoteColumns.PARENT_ID + "<>" + Notes.ID_TRASH_FOLER,
new String [] {String.valueOf(type)},
null);
boolean exist = false;
if (cursor != null) {
// 如果查询结果不为空,则便签存在且可见
if (cursor.getCount() > 0) {
exist = true;
}
cursor.close();
}
return exist;
}
/**
* 检查指定ID的便签是否存在于数据库中
*
* @param resolver 内容解析器
* @param noteId 便签ID
* @return 如果便签存在返回true否则返回false
*/
public static boolean existInNoteDatabase(ContentResolver resolver, long noteId) {
// 查询指定ID的便签
Cursor cursor = resolver.query(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, noteId),
null, null, null, null);
boolean exist = false;
if (cursor != null) {
// 如果查询结果不为空,则便签存在
if (cursor.getCount() > 0) {
exist = true;
}
cursor.close();
}
return exist;
}
/**
* 检查指定ID的数据是否存在于数据库中
*
* @param resolver 内容解析器
* @param dataId 数据ID
* @return 如果数据存在返回true否则返回false
*/
public static boolean existInDataDatabase(ContentResolver resolver, long dataId) {
// 查询指定ID的数据
Cursor cursor = resolver.query(ContentUris.withAppendedId(Notes.CONTENT_DATA_URI, dataId),
null, null, null, null);
boolean exist = false;
if (cursor != null) {
// 如果查询结果不为空,则数据存在
if (cursor.getCount() > 0) {
exist = true;
}
cursor.close();
}
return exist;
}
/**
* 检查可见文件夹中是否存在指定名称的文件夹
*
* @param resolver 内容解析器
* @param name 文件夹名称
* @return 如果存在返回true否则返回false
*/
public static boolean checkVisibleFolderName(ContentResolver resolver, String name) {
// 查询类型为文件夹、不在回收站中且名称匹配的记录
Cursor cursor = resolver.query(Notes.CONTENT_NOTE_URI, null,
NoteColumns.TYPE + "=" + Notes.TYPE_FOLDER +
" AND " + NoteColumns.PARENT_ID + "<>" + Notes.ID_TRASH_FOLER +
" AND " + NoteColumns.SNIPPET + "=?",
new String[] { name }, null);
boolean exist = false;
if(cursor != null) {
// 如果查询结果不为空,则存在同名文件夹
if(cursor.getCount() > 0) {
exist = true;
}
cursor.close();
}
return exist;
}
/**
* 获取指定文件夹中的所有小部件属性
*
* @param resolver 内容解析器
* @param folderId 文件夹ID
* @return 小部件属性集合如果没有则返回null
*/
public static HashSet<AppWidgetAttribute> getFolderNoteWidget(ContentResolver resolver, long folderId) {
// 查询指定文件夹中便签的小部件ID和类型
Cursor c = resolver.query(Notes.CONTENT_NOTE_URI,
new String[] { NoteColumns.WIDGET_ID, NoteColumns.WIDGET_TYPE },
NoteColumns.PARENT_ID + "=?",
new String[] { String.valueOf(folderId) },
null);
HashSet<AppWidgetAttribute> set = null;
if (c != null) {
if (c.moveToFirst()) {
// 创建小部件属性集合
set = new HashSet<AppWidgetAttribute>();
do {
try {
// 提取小部件ID和类型
AppWidgetAttribute widget = new AppWidgetAttribute();
widget.widgetId = c.getInt(0);
widget.widgetType = c.getInt(1);
set.add(widget);
} catch (IndexOutOfBoundsException e) {
// 索引越界异常处理
Log.e(TAG, e.toString());
}
} while (c.moveToNext());
}
c.close();
}
return set;
}
/**
* 根据便签ID获取关联的电话号码
*
* @param resolver 内容解析器
* @param noteId 便签ID
* @return 电话号码字符串,如果没有则返回空字符串
*/
public static String getCallNumberByNoteId(ContentResolver resolver, long noteId) {
// 查询指定便签ID和MIME类型的通话记录数据
Cursor cursor = resolver.query(Notes.CONTENT_DATA_URI,
new String [] { CallNote.PHONE_NUMBER },
CallNote.NOTE_ID + "=? AND " + CallNote.MIME_TYPE + "=?",
new String [] { String.valueOf(noteId), CallNote.CONTENT_ITEM_TYPE },
null);
if (cursor != null && cursor.moveToFirst()) {
try {
// 返回电话号码
return cursor.getString(0);
} catch (IndexOutOfBoundsException e) {
// 索引越界异常处理
Log.e(TAG, "Get call number fails " + e.toString());
} finally {
// 确保关闭游标
cursor.close();
}
}
return "";
}
/**
* 根据电话号码和通话日期获取便签ID
*
* @param resolver 内容解析器
* @param phoneNumber 电话号码
* @param callDate 通话日期
* @return 便签ID如果没有找到则返回0
*/
public static long getNoteIdByPhoneNumberAndCallDate(ContentResolver resolver, String phoneNumber, long callDate) {
// 查询匹配电话号码和通话日期的便签ID
Cursor cursor = resolver.query(Notes.CONTENT_DATA_URI,
new String [] { CallNote.NOTE_ID },
CallNote.CALL_DATE + "=? AND " + CallNote.MIME_TYPE + "=? AND PHONE_NUMBERS_EQUAL("
+ CallNote.PHONE_NUMBER + ",?)",
new String [] { String.valueOf(callDate), CallNote.CONTENT_ITEM_TYPE, phoneNumber},
null);
if (cursor != null) {
if (cursor.moveToFirst()) {
try {
// 返回便签ID
return cursor.getLong(0);
} catch (IndexOutOfBoundsException e) {
Log.e(TAG, "Get note id by phone number and call date fails: " + e.toString());
} finally {
cursor.close();
}
} else {
cursor.close();
}
}
return 0;
}
/**
* 根据便签ID获取便签摘要
*
* @param resolver 内容解析器
* @param noteId 便签ID
* @return 便签摘要,如果没有则返回空字符串
*/
public static String getSnippetById(ContentResolver resolver, long noteId) {
// 查询指定便签ID的摘要
Cursor cursor = resolver.query(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, noteId),
new String[] { NoteColumns.SNIPPET },
null,
null,
null);
if (cursor != null) {
if (cursor.moveToFirst()) {
try {
// 返回便签摘要
return cursor.getString(0);
} catch (IndexOutOfBoundsException e) {
Log.e(TAG, "Get snippet fails: " + e.toString());
} finally {
cursor.close();
}
} else {
cursor.close();
}
}
return "";
}
/**
* 格式化便签摘要,处理特殊字符和长度
*
* @param snippet 原始摘要
* @return 格式化后的摘要
*/
public static String getFormattedSnippet(String snippet) {
if (snippet != null) {
// 替换换行符为空格
snippet = snippet.replace('\n', ' ');
}
return snippet;
}
}