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/src/tool/DataUtils.java

404 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.

/*
* 版权所有 (c) 2010-2011MiCode 开源社区 (www.micode.net)
* 根据 Apache 许可证 2.0 版本("许可证")授权;
* 除非符合许可证的规定,否则不得使用本文件。
* 您可以从以下网址获取许可证副本:
* http://www.apache.org/licenses/LICENSE-2.0
* 除非适用法律要求或书面同意,本软件按"原样"分发,
* 没有任何明示或暗示的保证或条件。
* 详见许可证中规定的权限和限制。
* 这是一份标准的Apache许可证2.0版本的开源声明)
*/
// 定义数据工具类的包路径
package net.micode.notes.tool;
// 导入Android内容提供者相关类
import android.content.ContentProviderOperation; // 内容提供者操作
import android.content.ContentProviderResult; // 内容提供者操作结果
import android.content.ContentResolver; // 内容解析器
import android.content.ContentUris; // URI工具
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 是否删除成功
*/
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>();
// 遍历要删除的笔记ID
for (long id : ids) {
if(id == Notes.ID_ROOT_FOLDER) { // 防止删除系统根文件夹
Log.e(TAG, "Don't delete system folder root");
continue;
}
// 创建删除操作
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 是否移动成功
*/
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<>();
// 遍历要移动的笔记ID
for (long id : ids) {
// 创建更新操作
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;
}
/**
* 检查指定类型笔记是否在数据库中可见(不在回收站)
* @param resolver 内容解析器
* @param noteId 笔记ID
* @param type 笔记类型
* @return 是否可见
*/
public static boolean visibleInNoteDatabase(ContentResolver resolver, long noteId, int type) {
// 查询指定条件的笔记
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;
}
/**
* 检查笔记是否存在于笔记数据库中
* @param resolver 内容解析器
* @param noteId 笔记ID
* @return 是否存在
*/
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;
}
/**
* 检查数据项是否存在于数据数据库中
* @param resolver 内容解析器
* @param dataId 数据ID
* @return 是否存在
*/
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 是否存在
*/
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 小部件属性集合
*/
public static HashSet<AppWidgetAttribute> getFolderNoteWidget(ContentResolver resolver, long folderId) {
// 查询文件夹下笔记的小部件信息
Cursor c = resolver.query(Notes.CONTENT_NOTE_URI,
new String[] { NoteColumns.WIDGET_ID, NoteColumns.WIDGET_TYPE }, // 查询小部件ID和类型
NoteColumns.PARENT_ID + "=?", // 指定父文件夹
new String[] { String.valueOf(folderId) }, // 参数值
null); // 无排序
HashSet<AppWidgetAttribute> set = null;
if (c != null) {
if (c.moveToFirst()) {
set = new HashSet<>(); // 创建集合
do {
try {
// 创建小部件属性对象并添加到集合
AppWidgetAttribute widget = new AppWidgetAttribute();
widget.widgetId = c.getInt(0); // 小部件ID
widget.widgetType.set(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) {
// 查询指定笔记的通话数据
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 (cursor) {
return cursor.getString(0); // 返回电话号码
} catch (IndexOutOfBoundsException e) {
Log.e(TAG, "Get call number fails " + e.toString());
}
// 确保关闭游标
}
return ""; // 未找到返回空字符串
}
/**
* 根据电话号码和通话日期获取笔记ID
* @param resolver 内容解析器
* @param phoneNumber 电话号码
* @param callDate 通话日期
* @return 笔记ID
*/
public static long getNoteIdByPhoneNumberAndCallDate(ContentResolver resolver, String phoneNumber, long callDate) {
// 查询符合条件的数据项
Cursor cursor = resolver.query(Notes.CONTENT_DATA_URI,
new String [] { CallNote.NOTE_ID }, // 只查询笔记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 {
return cursor.getLong(0); // 返回笔记ID
} catch (IndexOutOfBoundsException e) {
Log.e(TAG, "Get call note id fails " + e.toString());
}
}
cursor.close(); // 关闭游标
}
return 0; // 未找到返回0
}
/**
* 根据笔记ID获取摘要内容
* @param resolver 内容解析器
* @param noteId 笔记ID
* @return 笔记摘要
*/
public static String getSnippetById(ContentResolver resolver, long noteId) {
// 查询指定笔记的摘要
Cursor cursor = resolver.query(Notes.CONTENT_NOTE_URI,
new String [] { NoteColumns.SNIPPET }, // 只查询摘要
NoteColumns.ID + "=?", // 条件
new String [] { String.valueOf(noteId)}, // 参数值
null); // 无排序
if (cursor != null) {
String snippet = "";
if (cursor.moveToFirst()) {
snippet = cursor.getString(0); // 获取摘要
}
cursor.close(); // 关闭游标
return snippet;
}
throw new IllegalArgumentException("Note is not found with id: " + noteId); // 未找到抛出异常
}
/**
* 格式化摘要内容(去除首尾空格和换行)
* @param snippet 原始摘要
* @return 格式化后的摘要
*/
public static String getFormattedSnippet(String snippet) {
if (snippet != null) {
snippet = snippet.trim(); // 去除首尾空格
int index = snippet.indexOf('\n'); // 查找第一个换行符
if (index != -1) {
snippet = snippet.substring(0, index); // 截取到第一个换行符前的内容
}
}
return snippet;
}
}