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.
git-test/src/main/java/net/micode/notes/model/RecentlyDeletedManager.java

230 lines
7.7 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.model;
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.util.Log;
import net.micode.notes.data.Notes;
import net.micode.notes.data.Notes.NoteColumns;
import net.micode.notes.tool.DataUtils;
import java.util.HashSet;
/**
* 最近删除管理器,负责管理最近删除的便签和文件夹
* 采用单例模式设计,提供获取最近删除项、恢复项、永久删除项、清空回收站等功能
*/
public class RecentlyDeletedManager {
// 默认保留天数,超过此天数的已删除项将被自动清理
public static final int DEFAULT_RETENTION_DAYS = 30;
// 清理任务间隔(每天)
public static final long CLEANUP_INTERVAL = 24 * 60 * 60 * 1000;
private Context mContext;
private ContentResolver mContentResolver;
// 单例实例
private static RecentlyDeletedManager sInstance;
// 日志标签
private static final String TAG = "RecentlyDeletedManager";
/**
* 私有构造方法,防止外部实例化
* @param context 上下文对象
*/
private RecentlyDeletedManager(Context context) {
mContext = context.getApplicationContext();
mContentResolver = mContext.getContentResolver();
}
/**
* 获取单例实例
* @param context 上下文对象
* @return 最近删除管理器实例
*/
public static synchronized RecentlyDeletedManager getInstance(Context context) {
if (sInstance == null) {
sInstance = new RecentlyDeletedManager(context);
}
return sInstance;
}
/**
* 获取最近删除的项列表
* @return 最近删除项的游标,按删除时间倒序排列
*/
public Cursor getRecentlyDeletedItems() {
// 查询条件已删除DELETED_DATE > 0且位于回收站文件夹
String selection = NoteColumns.DELETED_DATE + " > 0 AND " + NoteColumns.PARENT_ID + "=" + Notes.ID_TRASH_FOLER;
// 按删除时间倒序排序
String sortOrder = NoteColumns.DELETED_DATE + " DESC";
try {
return mContentResolver.query(
Notes.CONTENT_NOTE_URI,
null, // 查询所有列
selection,
null,
sortOrder
);
} catch (Exception e) {
Log.e(TAG, "Failed to get recently deleted items", e);
return null;
}
}
/**
* 恢复指定项
* @param itemIds 要恢复的项ID数组
* @return 成功恢复的项数量
*/
public int restoreItems(long[] itemIds) {
if (itemIds == null || itemIds.length == 0) {
return 0;
}
int restoredCount = 0;
for (long itemId : itemIds) {
try {
// 获取原父文件夹ID
String[] projection = {NoteColumns.ORIGIN_PARENT_ID};
String selection = NoteColumns.ID + "=" + itemId;
Cursor cursor = mContentResolver.query(
Notes.CONTENT_NOTE_URI,
projection,
selection,
null,
null
);
if (cursor != null && cursor.moveToFirst()) {
long originParentId = cursor.getLong(0);
cursor.close();
// 如果原父文件夹不存在或已被删除,使用根文件夹
long targetParentId = originParentId != Notes.ID_TRASH_FOLER ? originParentId : Notes.ID_ROOT_FOLDER;
// 使用现有的batchMoveToFolder方法来恢复项目
HashSet<Long> ids = new HashSet<Long>();
ids.add(itemId);
if (DataUtils.batchMoveToFolder(mContentResolver, ids, targetParentId)) {
restoredCount++;
}
} else if (cursor != null) {
cursor.close();
}
} catch (Exception e) {
Log.e(TAG, "Failed to restore item: " + itemId, e);
}
}
return restoredCount;
}
/**
* 永久删除指定项
* @param itemIds 要永久删除的项ID数组
* @return 成功永久删除的项数量
*/
public int permanentlyDeleteItems(long[] itemIds) {
if (itemIds == null || itemIds.length == 0) {
return 0;
}
int deletedCount = 0;
for (long itemId : itemIds) {
try {
int rowsAffected = mContentResolver.delete(
Notes.CONTENT_NOTE_URI,
NoteColumns.ID + "=" + itemId,
null
);
if (rowsAffected > 0) {
deletedCount++;
}
} catch (Exception e) {
Log.e(TAG, "Failed to permanently delete item: " + itemId, e);
}
}
return deletedCount;
}
/**
* 清空回收站
* @return 成功清空的项数量
*/
public int emptyTrash() {
try {
// 删除所有已删除且位于回收站的项
String selection = NoteColumns.DELETED_DATE + " > 0 AND " + NoteColumns.PARENT_ID + "=" + Notes.ID_TRASH_FOLER;
return mContentResolver.delete(
Notes.CONTENT_NOTE_URI,
selection,
null
);
} catch (Exception e) {
Log.e(TAG, "Failed to empty trash", e);
return 0;
}
}
/**
* 清理超过保留天数的项
* @param retentionDays 保留天数
* @return 成功清理的项数量
*/
public int cleanupOldItems(int retentionDays) {
if (retentionDays < 0) {
retentionDays = DEFAULT_RETENTION_DAYS;
}
try {
// 计算清理阈值:当前时间减去保留天数(毫秒)
long cleanupThreshold = System.currentTimeMillis() - (retentionDays * 24 * 60 * 60 * 1000);
// 删除条件:已删除且删除时间小于清理阈值
String selection = NoteColumns.DELETED_DATE + " > 0 AND " + NoteColumns.DELETED_DATE + " < " + cleanupThreshold;
return mContentResolver.delete(
Notes.CONTENT_NOTE_URI,
selection,
null
);
} catch (Exception e) {
Log.e(TAG, "Failed to cleanup old items", e);
return 0;
}
}
/**
* 启动自动清理任务
* 注意此方法在当前实现中仅作为占位符实际自动清理逻辑由TrashCleanupWorker实现
*/
public void startAutoCleanup() {
// 自动清理任务由TrashCleanupWorker处理此处预留接口
Log.d(TAG, "Auto cleanup task is managed by TrashCleanupWorker");
}
}