类型: INTEGER
*/ public static final String DATA1 = "data1"; + + /** + * 隐私空间ID,用于标识便签所属的隐私空间 + *类型: TEXT
+ */ + public static final String PRIVACY_SPACE_ID = "privacy_space_id"; } /** diff --git a/src/main/java/net/micode/notes/data/NotesDatabaseHelper.java b/src/main/java/net/micode/notes/data/NotesDatabaseHelper.java index 39bf475..cb6e34e 100644 --- a/src/main/java/net/micode/notes/data/NotesDatabaseHelper.java +++ b/src/main/java/net/micode/notes/data/NotesDatabaseHelper.java @@ -36,7 +36,7 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper { private static final String DB_NAME = "note.db"; // 数据库版本号 - private static final int DB_VERSION = 10; + private static final int DB_VERSION = 11; // 数据库表名定义 public interface TABLE { @@ -96,7 +96,8 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper { NoteColumns.IS_LOCKED + " INTEGER NOT NULL DEFAULT 0," + NoteColumns.LOCK_PASSWORD + " TEXT NOT NULL DEFAULT ''," + NoteColumns.TAGS + " TEXT NOT NULL DEFAULT ''," + - NoteColumns.DATA1 + " INTEGER NOT NULL DEFAULT 0" + + NoteColumns.DATA1 + " INTEGER NOT NULL DEFAULT 0," + + NoteColumns.PRIVACY_SPACE_ID + " TEXT NOT NULL DEFAULT ''" + ")"; // 创建数据表的SQL语句 @@ -328,6 +329,12 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper { values.put(NoteColumns.ID, Notes.ID_TRASH_FOLER); values.put(NoteColumns.TYPE, Notes.TYPE_SYSTEM); db.insert(TABLE.NOTE, null, values); + + // 创建隐私空间根文件夹:用于存储隐私空间 + values.clear(); + values.put(NoteColumns.ID, Notes.ID_PRIVACY_SPACE_FOLDER); + values.put(NoteColumns.TYPE, Notes.TYPE_SYSTEM); + db.insert(TABLE.NOTE, null, values); } /** @@ -448,6 +455,11 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper { upgradeToV10(db); oldVersion++; } + + if (oldVersion == 10) { + upgradeToV11(db); + oldVersion++; + } if (reCreateTriggers) { reCreateNoteTableTriggers(db); @@ -580,4 +592,20 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper { db.execSQL("ALTER TABLE " + TABLE.NOTE + " ADD COLUMN " + NoteColumns.DATA1 + " INTEGER NOT NULL DEFAULT 0"); } + + /** + * 将数据库从v10升级到v11 + * 此版本升级添加了PRIVACY_SPACE_ID字段,用于存储便签所属的隐私空间ID + * @param db SQLite数据库实例 + */ + private void upgradeToV11(SQLiteDatabase db) { + // 为笔记表添加PRIVACY_SPACE_ID字段 + db.execSQL("ALTER TABLE " + TABLE.NOTE + " ADD COLUMN " + NoteColumns.PRIVACY_SPACE_ID + + " TEXT NOT NULL DEFAULT ''"); + // 添加隐私空间根文件夹 + ContentValues values = new ContentValues(); + values.put(NoteColumns.ID, Notes.ID_PRIVACY_SPACE_FOLDER); + values.put(NoteColumns.TYPE, Notes.TYPE_SYSTEM); + db.insert(TABLE.NOTE, null, values); + } } diff --git a/src/main/java/net/micode/notes/model/WorkingNote.java b/src/main/java/net/micode/notes/model/WorkingNote.java index 40bab6a..9eefdaa 100644 --- a/src/main/java/net/micode/notes/model/WorkingNote.java +++ b/src/main/java/net/micode/notes/model/WorkingNote.java @@ -132,6 +132,11 @@ public class WorkingNote { * 标题,便签的标题 */ private String mTitle; + + /** + * 隐私空间ID,用于标识便签所属的隐私空间 + */ + private String mPrivacySpaceId; /** * 数据投影数组,用于从数据库中查询便签数据 @@ -160,7 +165,8 @@ public class WorkingNote { NoteColumns.LOCK_PASSWORD, // 锁定密码 NoteColumns.PASSWORD_TYPE, // 密码类型 NoteColumns.NUMERIC_PASSWORD, // 数字密码 - NoteColumns.TITLE // 标题 + NoteColumns.TITLE, // 标题 + NoteColumns.PRIVACY_SPACE_ID // 隐私空间ID }; /** @@ -184,6 +190,7 @@ public class WorkingNote { private static final int NOTE_PASSWORD_TYPE_COLUMN = 8; // 密码类型列索引 private static final int NOTE_NUMERIC_PASSWORD_COLUMN = 9; // 数字密码列索引 private static final int NOTE_TITLE_COLUMN = 10; // 标题列索引 + private static final int NOTE_PRIVACY_SPACE_ID_COLUMN = 11; // 隐私空间ID列索引 /** * 构造方法,创建一个新的便签 @@ -198,6 +205,7 @@ public class WorkingNote { mNote = new Note(); // 创建便签对象 mNoteId = 0; // 新便签ID为0 mIsDeleted = false; // 初始化为未删除 + mPrivacySpaceId = ""; // 初始化为空 mMode = 0; // 初始化为普通模式 mWidgetType = Notes.TYPE_WIDGET_INVALIDE; // 初始化为无效小部件类型 } @@ -241,6 +249,10 @@ public class WorkingNote { mPasswordType = cursor.getString(NOTE_PASSWORD_TYPE_COLUMN); mNumericPassword = cursor.getString(NOTE_NUMERIC_PASSWORD_COLUMN); mTitle = cursor.getString(NOTE_TITLE_COLUMN); + mPrivacySpaceId = cursor.getString(NOTE_PRIVACY_SPACE_ID_COLUMN); + if (mPrivacySpaceId == null) { + mPrivacySpaceId = ""; + } } cursor.close(); } else { @@ -576,6 +588,25 @@ public class WorkingNote { return mWidgetType; } + /** + * 设置隐私空间ID + * @param privacySpaceId 隐私空间ID + */ + public void setPrivacySpaceId(String privacySpaceId) { + if (!TextUtils.equals(mPrivacySpaceId, privacySpaceId)) { + mPrivacySpaceId = privacySpaceId; + mNote.setNoteValue(NoteColumns.PRIVACY_SPACE_ID, privacySpaceId); + } + } + + /** + * 获取隐私空间ID + * @return 隐私空间ID + */ + public String getPrivacySpaceId() { + return mPrivacySpaceId; + } + /** * 设置便签锁定状态 * @param locked 是否锁定 diff --git a/src/main/java/net/micode/notes/ui/NoteEditActivity.java b/src/main/java/net/micode/notes/ui/NoteEditActivity.java index 97fa85e..013726d 100644 --- a/src/main/java/net/micode/notes/ui/NoteEditActivity.java +++ b/src/main/java/net/micode/notes/ui/NoteEditActivity.java @@ -300,15 +300,16 @@ public class NoteEditActivity extends Activity implements OnClickListener, | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); } // 处理创建或编辑便签操作 - else if(TextUtils.equals(Intent.ACTION_INSERT_OR_EDIT, intent.getAction())) { - // 获取参数 - long folderId = intent.getLongExtra(Notes.INTENT_EXTRA_FOLDER_ID, 0); - int widgetId = intent.getIntExtra(Notes.INTENT_EXTRA_WIDGET_ID, - AppWidgetManager.INVALID_APPWIDGET_ID); - int widgetType = intent.getIntExtra(Notes.INTENT_EXTRA_WIDGET_TYPE, - Notes.TYPE_WIDGET_INVALIDE); - int bgResId = intent.getIntExtra(Notes.INTENT_EXTRA_BACKGROUND_ID, - ResourceParser.getDefaultBgId(this)); + else if(TextUtils.equals(Intent.ACTION_INSERT_OR_EDIT, intent.getAction())) { + // 获取参数 + long folderId = intent.getLongExtra(Notes.INTENT_EXTRA_FOLDER_ID, 0); + int widgetId = intent.getIntExtra(Notes.INTENT_EXTRA_WIDGET_ID, + AppWidgetManager.INVALID_APPWIDGET_ID); + int widgetType = intent.getIntExtra(Notes.INTENT_EXTRA_WIDGET_TYPE, + Notes.TYPE_WIDGET_INVALIDE); + int bgResId = intent.getIntExtra(Notes.INTENT_EXTRA_BACKGROUND_ID, + ResourceParser.getDefaultBgId(this)); + String privacySpaceId = intent.getStringExtra("privacy_space_id"); // 处理通话记录便签 String phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER); @@ -332,11 +333,19 @@ public class NoteEditActivity extends Activity implements OnClickListener, mWorkingNote = WorkingNote.createEmptyNote(this, folderId, widgetId, widgetType, bgResId); mWorkingNote.convertToCallNote(phoneNumber, callDate); + // 设置隐私空间ID + if (!TextUtils.isEmpty(privacySpaceId)) { + mWorkingNote.setPrivacySpaceId(privacySpaceId); + } } } else { // 创建普通新便签 mWorkingNote = WorkingNote.createEmptyNote(this, folderId, widgetId, widgetType, bgResId); + // 设置隐私空间ID + if (!TextUtils.isEmpty(privacySpaceId)) { + mWorkingNote.setPrivacySpaceId(privacySpaceId); + } } // 设置软键盘模式为可见状态 diff --git a/src/main/java/net/micode/notes/ui/NotesListActivity.java b/src/main/java/net/micode/notes/ui/NotesListActivity.java index 35f8bfb..64dfc2f 100644 --- a/src/main/java/net/micode/notes/ui/NotesListActivity.java +++ b/src/main/java/net/micode/notes/ui/NotesListActivity.java @@ -50,6 +50,7 @@ import android.view.View.OnClickListener; import android.view.View.OnCreateContextMenuListener; import android.view.View.OnTouchListener; import android.view.KeyEvent; +import android.view.ViewGroup; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodManager; import android.widget.AdapterView; @@ -62,8 +63,12 @@ import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.PopupMenu; +import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; +import android.widget.GridView; +import android.widget.BaseAdapter; +import android.view.ViewGroup; import net.micode.notes.R; import net.micode.notes.data.Notes; @@ -96,11 +101,23 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt private static final int MENU_FOLDER_CHANGE_NAME = 2; private static final String PREFERENCE_ADD_INTRODUCTION = "net.micode.notes.introduction"; + private static final String PREFERENCE_BACKGROUND = "net.micode.notes.background"; + private static final String BACKGROUND_TYPE_DEFAULT = "default"; + private static final String BACKGROUND_TYPE_ALBUM = "album"; + private static final int REQUEST_CODE_PICK_IMAGE = 105; private enum ListEditState { NOTE_LIST, SUB_FOLDER, CALL_RECORD_FOLDER }; + // 背景选项 + private static final String[] BACKGROUND_OPTIONS = { + "高山流水", "风中树叶", "长河落日" + }; + private static final int[] BACKGROUND_RESOURCES = { + R.drawable.background_mountain, R.drawable.background_leaves, R.drawable.background_sunset + }; + private ListEditState mState; private BackgroundQueryHandler mBackgroundQueryHandler; @@ -110,6 +127,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt private ListView mNotesListView; private Button mAddNewNote; + private Button mPrivacyBackButton; private boolean mDispatch; @@ -135,6 +153,10 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt private static final String ROOT_FOLDER_SELECTION = "(" + NoteColumns.TYPE + "<>" + Notes.TYPE_SYSTEM + " AND " + NoteColumns.TYPE + "<>" + Notes.TYPE_TODO + " AND " + NoteColumns.PARENT_ID + "=?) OR (" + NoteColumns.ID + "=" + Notes.ID_CALL_RECORD_FOLDER + " AND " + NoteColumns.NOTES_COUNT + ">0)"; + // 隐私空间相关常量 + private static final int REQUEST_CODE_PRIVACY_SPACE = 104; + private String mCurrentPrivacySpaceId = ""; + private final static int REQUEST_CODE_OPEN_NODE = 102; private final static int REQUEST_CODE_NEW_NODE = 103; @@ -146,11 +168,30 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt private String mSearchQuery; private boolean mIsSearching; + // 背景相关变量 + private View mRootView; + private RelativeLayout mBackgroundContainer; + private LinearLayout mMainContent; + private String mCurrentBackgroundType = BACKGROUND_TYPE_DEFAULT; + private int mCurrentBackgroundResource = R.drawable.list_background; + private String mCurrentBackgroundPath = ""; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.note_list); + + // 获取隐私空间ID + Intent intent = getIntent(); + if (intent != null) { + mCurrentPrivacySpaceId = intent.getStringExtra("privacy_space_id"); + if (mCurrentPrivacySpaceId == null) { + mCurrentPrivacySpaceId = ""; + } + } + initResources(); + initBackground(); /** * Insert an introduction when user firstly use this application @@ -160,9 +201,36 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { - if (resultCode == RESULT_OK - && (requestCode == REQUEST_CODE_OPEN_NODE || requestCode == REQUEST_CODE_NEW_NODE)) { - mNotesListAdapter.changeCursor(null); + if (resultCode == RESULT_OK) { + if (requestCode == REQUEST_CODE_OPEN_NODE || requestCode == REQUEST_CODE_NEW_NODE) { + mNotesListAdapter.changeCursor(null); + } else if (requestCode == REQUEST_CODE_PRIVACY_SPACE) { + // 处理从隐私空间返回的结果 + if (data != null) { + String privacySpaceId = data.getStringExtra("privacy_space_id"); + if (!TextUtils.isEmpty(privacySpaceId)) { + mCurrentPrivacySpaceId = privacySpaceId; + updatePrivacySpaceUI(); + startAsyncNotesListQuery(); + } + } + } else if (requestCode == REQUEST_CODE_PICK_IMAGE) { + // 处理从相册选择图片的结果 + if (data != null && data.getData() != null) { + try { + // 保存图片路径 + mCurrentBackgroundType = BACKGROUND_TYPE_ALBUM; + mCurrentBackgroundPath = data.getData().toString(); + // 更新背景 + updateBackground(); + // 保存设置 + saveBackgroundSetting(); + } catch (Exception e) { + e.printStackTrace(); + Toast.makeText(this, "图片加载失败", Toast.LENGTH_SHORT).show(); + } + } + } } else { super.onActivityResult(requestCode, resultCode, data); } @@ -290,13 +358,46 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt mAddNewNote = (Button) findViewById(R.id.btn_add_note); mAddNewNote.setOnClickListener(this); mAddNewNote.setOnTouchListener(new NewNoteOnTouchListener()); + mPrivacyBackButton = (Button) findViewById(R.id.btn_privacy_back); + mPrivacyBackButton.setOnClickListener(this); mDispatch = false; mDispatchY = 0; mOriginY = 0; mTitleBar = (TextView) findViewById(R.id.tv_title_bar); + mMainContent = (LinearLayout) findViewById(R.id.main_content); + // 获取根视图作为背景容器 + mBackgroundContainer = (RelativeLayout) findViewById(R.id.note_list_root); + if (mBackgroundContainer == null) { + // 如果找不到,使用content view + View contentView = getWindow().getDecorView().findViewById(android.R.id.content); + if (contentView instanceof ViewGroup) { + ViewGroup contentViewGroup = (ViewGroup) contentView; + if (contentViewGroup.getChildCount() > 0) { + View childView = contentViewGroup.getChildAt(0); + if (childView instanceof RelativeLayout) { + mBackgroundContainer = (RelativeLayout) childView; + } + } + } + } + // 最后的备用方案 + if (mBackgroundContainer == null) { + // 如果还是找不到,使用整个窗口的装饰视图作为背景容器 + mBackgroundContainer = new RelativeLayout(this); + ViewGroup decorView = (ViewGroup) getWindow().getDecorView(); + View contentView = decorView.findViewById(android.R.id.content); + if (contentView != null) { + decorView.removeView(contentView); + mBackgroundContainer.addView(contentView); + decorView.addView(mBackgroundContainer); + } + } mState = ListEditState.NOTE_LIST; mModeCallBack = new ModeCallback(); + // 检查是否处于隐私空间中 + updatePrivacySpaceUI(); + // 初始化界面切换栏 mNotesTab = (TextView) findViewById(R.id.notes_tab); mTodoTab = (TextView) findViewById(R.id.todo_tab); @@ -711,6 +812,57 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt } } + // 添加隐私空间筛选条件 + if (!TextUtils.isEmpty(mCurrentPrivacySpaceId)) { + // 在隐私空间中,只显示该隐私空间的便签 + String privacyCondition = NoteColumns.PRIVACY_SPACE_ID + "=?"; + if (mCurrentFolderId == Notes.ID_ROOT_FOLDER) { + // 根文件夹需要特殊处理 + if (!TextUtils.isEmpty(mSearchQuery) || !TextUtils.isEmpty(mSelectedTag)) { + // 有搜索关键词或标签的情况 + baseSelection = "(" + baseSelection + ") AND " + privacyCondition; + } else { + // 没有搜索关键词和标签的情况 + baseSelection = "(" + NoteColumns.TYPE + "<>" + Notes.TYPE_SYSTEM + " AND " + NoteColumns.PARENT_ID + "=? AND " + privacyCondition + ")"; + // 重新构建参数列表 + argsList.clear(); + argsList.add(String.valueOf(mCurrentFolderId)); + argsList.add(mCurrentPrivacySpaceId); + } + } else { + // 普通文件夹 + if (!TextUtils.isEmpty(mSearchQuery) || !TextUtils.isEmpty(mSelectedTag)) { + // 有搜索关键词或标签的情况 + baseSelection = "(" + baseSelection + ") AND " + privacyCondition; + } else { + // 没有搜索关键词和标签的情况 + baseSelection = NoteColumns.PARENT_ID + "=? AND " + NoteColumns.TYPE + "<>" + Notes.TYPE_TODO + " AND " + privacyCondition; + // 重新构建参数列表 + argsList.clear(); + argsList.add(String.valueOf(mCurrentFolderId)); + argsList.add(mCurrentPrivacySpaceId); + } + } + if (!TextUtils.isEmpty(mSearchQuery) || !TextUtils.isEmpty(mSelectedTag)) { + // 有搜索关键词或标签的情况,需要添加隐私空间ID参数 + argsList.add(mCurrentPrivacySpaceId); + } + } else { + // 不在隐私空间中,只显示非隐私空间的便签 + String privacyCondition = "(" + NoteColumns.PRIVACY_SPACE_ID + "='' OR " + NoteColumns.PRIVACY_SPACE_ID + " IS NULL)"; + if (mCurrentFolderId == Notes.ID_ROOT_FOLDER) { + // 根文件夹需要特殊处理 + baseSelection = "(" + baseSelection + ") AND " + privacyCondition; + } else { + // 普通文件夹 + if (baseSelection.contains("AND")) { + baseSelection += " AND " + privacyCondition; + } else { + baseSelection += " WHERE " + privacyCondition; + } + } + } + selection = baseSelection; selectionArgs = argsList.toArray(new String[argsList.size()]); @@ -769,6 +921,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt Intent intent = new Intent(this, NoteEditActivity.class); intent.setAction(Intent.ACTION_INSERT_OR_EDIT); intent.putExtra(Notes.INTENT_EXTRA_FOLDER_ID, mCurrentFolderId); + intent.putExtra("privacy_space_id", mCurrentPrivacySpaceId); this.startActivityForResult(intent, REQUEST_CODE_NEW_NODE); } @@ -856,6 +1009,29 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt public void onClick(View v) { if (v.getId() == R.id.btn_add_note) { createNewNote(); + } else if (v.getId() == R.id.btn_privacy_back) { + // 从隐私空间返回普通空间 + mCurrentPrivacySpaceId = ""; + updatePrivacySpaceUI(); + startAsyncNotesListQuery(); + } + } + + /** + * 更新隐私空间相关的UI元素 + */ + private void updatePrivacySpaceUI() { + if (!TextUtils.isEmpty(mCurrentPrivacySpaceId)) { + // 在隐私空间中,显示隐私空间名称 + mTitleBar.setText("隐私空间"); + mTitleBar.setVisibility(View.VISIBLE); + // 显示隐私空间返回按钮 + mPrivacyBackButton.setVisibility(View.VISIBLE); + } else { + // 不在隐私空间中,隐藏标题栏或显示默认标题 + mTitleBar.setVisibility(View.GONE); + // 隐藏隐私空间返回按钮 + mPrivacyBackButton.setVisibility(View.GONE); } } @@ -1060,6 +1236,8 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt // set sync or sync_cancel menu.findItem(R.id.menu_sync).setTitle( GTaskSyncService.isSyncing() ? R.string.menu_sync_cancel : R.string.menu_sync); + // 添加背景设置选项 + addBackgroundMenuItems(menu); } else if (mState == ListEditState.SUB_FOLDER) { getMenuInflater().inflate(R.menu.sub_folder, menu); } else if (mState == ListEditState.CALL_RECORD_FOLDER) { @@ -1094,6 +1272,19 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt onSearchRequested(); } else if (item.getItemId() == R.id.menu_trash) { startTrashActivity(); + } else if (item.getItemId() == R.id.menu_privacy_space) { + if (!TextUtils.isEmpty(mCurrentPrivacySpaceId)) { + // 从隐私空间返回普通空间 + Intent intent = new Intent(this, NotesListActivity.class); + intent.putExtra("privacy_space_id", ""); + intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(intent); + finish(); + } else { + // 打开隐私空间 + Intent intent = new Intent(this, PrivacySpaceActivity.class); + startActivityForResult(intent, REQUEST_CODE_PRIVACY_SPACE); + } } return true; } @@ -1413,4 +1604,150 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt builder.show(); } + + /** + * 初始化背景 + */ + private void initBackground() { + // 加载保存的背景设置 + SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this); + mCurrentBackgroundType = sp.getString(PREFERENCE_BACKGROUND + "_type", BACKGROUND_TYPE_DEFAULT); + mCurrentBackgroundPath = sp.getString(PREFERENCE_BACKGROUND + "_path", ""); + + if (BACKGROUND_TYPE_DEFAULT.equals(mCurrentBackgroundType)) { + int backgroundIndex = sp.getInt(PREFERENCE_BACKGROUND + "_index", 0); + if (backgroundIndex >= 0 && backgroundIndex < BACKGROUND_RESOURCES.length) { + mCurrentBackgroundResource = BACKGROUND_RESOURCES[backgroundIndex]; + } + } + + // 更新背景 + updateBackground(); + } + + /** + * 更新背景 + */ + private void updateBackground() { + if (mBackgroundContainer == null) { + return; + } + + try { + if (BACKGROUND_TYPE_DEFAULT.equals(mCurrentBackgroundType)) { + // 使用默认背景 + mBackgroundContainer.setBackgroundResource(mCurrentBackgroundResource); + } else if (BACKGROUND_TYPE_ALBUM.equals(mCurrentBackgroundType) && !TextUtils.isEmpty(mCurrentBackgroundPath)) { + // 使用相册图片作为背景 + try { + android.graphics.Bitmap bitmap = android.graphics.BitmapFactory.decodeStream( + getContentResolver().openInputStream(android.net.Uri.parse(mCurrentBackgroundPath))); + if (bitmap != null) { + // 计算屏幕尺寸 + android.util.DisplayMetrics displayMetrics = new android.util.DisplayMetrics(); + getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); + int screenWidth = displayMetrics.widthPixels; + int screenHeight = displayMetrics.heightPixels; + + // 缩放图片以适配屏幕 + android.graphics.Bitmap scaledBitmap = android.graphics.Bitmap.createScaledBitmap( + bitmap, screenWidth, screenHeight, true); + + android.graphics.drawable.BitmapDrawable drawable = new android.graphics.drawable.BitmapDrawable(getResources(), scaledBitmap); + // 设置背景图片的缩放方式 + drawable.setTileModeXY(android.graphics.Shader.TileMode.CLAMP, android.graphics.Shader.TileMode.CLAMP); + mBackgroundContainer.setBackground(drawable); + + // 释放原始 bitmap + if (bitmap != scaledBitmap) { + bitmap.recycle(); + } + } + } catch (Exception e) { + e.printStackTrace(); + Toast.makeText(this, "图片加载失败", Toast.LENGTH_SHORT).show(); + // 加载失败时使用默认背景 + mBackgroundContainer.setBackgroundResource(R.drawable.list_background); + } + } + } catch (Exception e) { + e.printStackTrace(); + // 加载失败时使用默认背景 + mBackgroundContainer.setBackgroundResource(R.drawable.list_background); + } + } + + /** + * 保存背景设置 + */ + private void saveBackgroundSetting() { + SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this); + SharedPreferences.Editor editor = sp.edit(); + editor.putString(PREFERENCE_BACKGROUND + "_type", mCurrentBackgroundType); + editor.putString(PREFERENCE_BACKGROUND + "_path", mCurrentBackgroundPath); + + if (BACKGROUND_TYPE_DEFAULT.equals(mCurrentBackgroundType)) { + // 找到当前背景资源的索引 + int index = 0; + for (int i = 0; i < BACKGROUND_RESOURCES.length; i++) { + if (BACKGROUND_RESOURCES[i] == mCurrentBackgroundResource) { + index = i; + break; + } + } + editor.putInt(PREFERENCE_BACKGROUND + "_index", index); + } + + editor.apply(); + } + + /** + * 显示背景选择对话框 + */ + private void showBackgroundSelectorDialog() { + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle("选择背景"); + + // 创建背景选项数组,添加从相册选择的选项 + String[] options = new String[BACKGROUND_OPTIONS.length + 1]; + System.arraycopy(BACKGROUND_OPTIONS, 0, options, 0, BACKGROUND_OPTIONS.length); + options[BACKGROUND_OPTIONS.length] = "从相册选择"; + + builder.setItems(options, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + if (which < BACKGROUND_OPTIONS.length) { + // 选择预设背景 + mCurrentBackgroundType = BACKGROUND_TYPE_DEFAULT; + mCurrentBackgroundResource = BACKGROUND_RESOURCES[which]; + mCurrentBackgroundPath = ""; + updateBackground(); + saveBackgroundSetting(); + Toast.makeText(NotesListActivity.this, "背景已更新", Toast.LENGTH_SHORT).show(); + } else { + // 从相册选择 + Intent intent = new Intent(Intent.ACTION_GET_CONTENT); + intent.setType("image/*"); + intent.addCategory(Intent.CATEGORY_OPENABLE); + startActivityForResult(intent, REQUEST_CODE_PICK_IMAGE); + } + } + }); + + builder.show(); + } + + /** + * 在菜单中添加背景设置选项 + */ + private void addBackgroundMenuItems(Menu menu) { + MenuItem backgroundMenu = menu.add(0, 100, 0, "背景设置"); + backgroundMenu.setOnMenuItemClickListener(new OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem item) { + showBackgroundSelectorDialog(); + return true; + } + }); + } } diff --git a/src/main/java/net/micode/notes/ui/PrivacySpaceActivity.java b/src/main/java/net/micode/notes/ui/PrivacySpaceActivity.java new file mode 100644 index 0000000..f1829c8 --- /dev/null +++ b/src/main/java/net/micode/notes/ui/PrivacySpaceActivity.java @@ -0,0 +1,339 @@ +package net.micode.notes.ui; + +import android.app.Activity; +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.preference.PreferenceManager; +import android.text.Editable; +import android.text.TextUtils; +import android.text.TextWatcher; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.Button; +import android.widget.EditText; +import android.widget.LinearLayout; +import android.widget.TextView; +import android.widget.Toast; + +import net.micode.notes.R; +import net.micode.notes.tool.LockPasswordUtils; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +public class PrivacySpaceActivity extends Activity implements OnClickListener { + private static final String TAG = "PrivacySpaceActivity"; + + private static final String PREF_PRIVACY_SPACES = "privacy_spaces"; + private static final String PREF_CURRENT_SPACE = "current_privacy_space"; + + private LinearLayout mSpacesContainer; + private Button mAddSpaceButton; + private Button mBackButton; + + private ArrayList