From ee7f81870915006a0861664eba193e720e6ab706 Mon Sep 17 00:00:00 2001 From: gy <2293314358@qq.com> Date: Fri, 30 Jan 2026 20:33:36 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E4=BA=91=E5=90=8C=E6=AD=A5?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=EF=BC=8C=E6=94=AF=E6=8C=81=E4=BE=BF=E7=AD=BE?= =?UTF-8?q?=E5=9C=A8=E4=B8=8D=E5=90=8C=E8=AE=BE=E5=A4=87=E9=97=B4=E7=9A=84?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E5=90=8C=E6=AD=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../notes/data/NotesDatabaseHelper.java | 2 +- .../net/micode/notes/data/NotesProvider.java | 41 +++- .../micode/notes/ui/NotesListActivity.java | 35 +-- .../notes/ui/NotesPreferenceActivity.java | 212 ++++-------------- 4 files changed, 97 insertions(+), 193 deletions(-) diff --git a/src/Notes-master/src/net/micode/notes/data/NotesDatabaseHelper.java b/src/Notes-master/src/net/micode/notes/data/NotesDatabaseHelper.java index 4a6799a..aa05ee7 100644 --- a/src/Notes-master/src/net/micode/notes/data/NotesDatabaseHelper.java +++ b/src/Notes-master/src/net/micode/notes/data/NotesDatabaseHelper.java @@ -68,7 +68,7 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper { NoteColumns.IS_PRIVATE + " INTEGER NOT NULL DEFAULT 0," + NoteColumns.VIEW_MODE + " INTEGER NOT NULL DEFAULT 0," + NoteColumns.CUSTOM_BG_URI + " TEXT NOT NULL DEFAULT ''," + - NoteColumns.EXPAND_1 + " TEXT NOT NULL DEFAULT ''" + + NoteColumns.EXPAND_1 + " TEXT NOT NULL DEFAULT ''," + // [新增字段 v9] NoteColumns.SYNC_STATE + " INTEGER DEFAULT 1," + NoteColumns.SERVER_ID + " TEXT," + diff --git a/src/Notes-master/src/net/micode/notes/data/NotesProvider.java b/src/Notes-master/src/net/micode/notes/data/NotesProvider.java index 0db1b5b..e5cebcd 100644 --- a/src/Notes-master/src/net/micode/notes/data/NotesProvider.java +++ b/src/Notes-master/src/net/micode/notes/data/NotesProvider.java @@ -54,7 +54,7 @@ public class NotesProvider extends ContentProvider { static { mMatcher = new UriMatcher(UriMatcher.NO_MATCH); mMatcher.addURI(Notes.AUTHORITY, "note", URI_NOTE); - mMatcher.addURI(Notes.AUTHORITY, "note/#", URI_NOTE_ITEM); + mMatcher.addURI(Notes.AUTHORITY, "note/*", URI_NOTE_ITEM); mMatcher.addURI(Notes.AUTHORITY, "data", URI_DATA); mMatcher.addURI(Notes.AUTHORITY, "data/#", URI_DATA_ITEM); mMatcher.addURI(Notes.AUTHORITY, "search", URI_SEARCH); @@ -235,16 +235,32 @@ public class NotesProvider extends ContentProvider { @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { int count = 0; - String id = null; + String id = null; // <--- 注意:这是原有的定义,保持不动 SQLiteDatabase db = mHelper.getWritableDatabase(); boolean updateData = false; - switch (mMatcher.match(uri)) { + + // [新增手术位置 1]:定义一个标志,用来识别是否为系统受限项 + boolean skipSyncTag = false; + + int match = mMatcher.match(uri); + switch (match) { case URI_NOTE: increaseNoteVersion(-1, selection, selectionArgs); count = db.update(TABLE.NOTE, values, selection, selectionArgs); break; case URI_NOTE_ITEM: - id = uri.getPathSegments().get(1); + id = uri.getPathSegments().get(1); // <--- 原有的 id 赋值 + + // [新增手术位置 2]:利用解析出的 id 进行判断 + try { + long numericId = Long.parseLong(id); + if (numericId <= 0) { + skipSyncTag = true; // ID 为 -3, -2, -1, 0 的都是系统项,不打同步标 + } + } catch (NumberFormatException e) { + skipSyncTag = true; // 如果不是数字,也跳过标记 + } + increaseNoteVersion(Long.valueOf(id), selection, selectionArgs); count = db.update(TABLE.NOTE, values, NoteColumns.ID + "=" + id + parseSelection(selection), selectionArgs); @@ -252,17 +268,34 @@ public class NotesProvider extends ContentProvider { case URI_DATA: count = db.update(TABLE.DATA, values, selection, selectionArgs); updateData = true; + // 更新 DATA 表通常意味着正文改了,标记位应该打在对应的 Note 上 + // 这里的简化处理是不在此处加标记,而是让 note 表的更新触发 + skipSyncTag = true; break; case URI_DATA_ITEM: id = uri.getPathSegments().get(1); count = db.update(TABLE.DATA, values, DataColumns.ID + "=" + id + parseSelection(selection), selectionArgs); updateData = true; + skipSyncTag = true; break; default: throw new IllegalArgumentException("Unknown URI " + uri); } + // [核心手术位置 3]:统一处理同步标记 + // 如果不是系统项,且 values 里没有主动设置过同步状态,则强制设为 1 (待同步) + if (!skipSyncTag) { + if (!values.containsKey(NoteColumns.SYNC_STATE)) { + values.put(NoteColumns.SYNC_STATE, 1); + // 注意:因为上面已经执行过 db.update 了, + // 所以对于单条 Note 记录,我们需要补丁式地更新一下这个状态 + if (id != null && match == URI_NOTE_ITEM) { + db.execSQL("UPDATE " + TABLE.NOTE + " SET " + NoteColumns.SYNC_STATE + "=1 WHERE " + NoteColumns.ID + "=" + id); + } + } + } + if (count > 0) { if (updateData) { getContext().getContentResolver().notifyChange(Notes.CONTENT_NOTE_URI, null); diff --git a/src/Notes-master/src/net/micode/notes/ui/NotesListActivity.java b/src/Notes-master/src/net/micode/notes/ui/NotesListActivity.java index 2958c6a..80d00ee 100644 --- a/src/Notes-master/src/net/micode/notes/ui/NotesListActivity.java +++ b/src/Notes-master/src/net/micode/notes/ui/NotesListActivity.java @@ -73,7 +73,6 @@ import net.micode.notes.tool.DataUtils.AppWidgetAttribute; import net.micode.notes.R; import net.micode.notes.data.Notes; import net.micode.notes.data.Notes.NoteColumns; -import net.micode.notes.gtask.remote.GTaskSyncService; import net.micode.notes.model.WorkingNote; import net.micode.notes.tool.BackupUtils; import net.micode.notes.tool.DataUtils; @@ -328,6 +327,12 @@ public class NotesListActivity extends AppCompatActivity implements OnClickListe super.onResume(); applyCustomBackground(); updateViewMode(); + + // [新增] 触发一次性的异步同步任务 + androidx.work.OneTimeWorkRequest syncRequest = + new androidx.work.OneTimeWorkRequest.Builder(net.micode.notes.sync.SyncWorker.class) + .build(); + androidx.work.WorkManager.getInstance(this).enqueue(syncRequest); } private void applyCustomBackground() { @@ -1323,12 +1328,9 @@ public class NotesListActivity extends AppCompatActivity implements OnClickListe // 移除之前的 menu.clear(),因为这会清空 onCreate 加载的内容 // 仅保留原有的动态逻辑,例如同步按钮的状态切换 if (mState == ListEditState.NOTE_LIST) { - // getMenuInflater().inflate(R.menu.note_list, menu); // 已在 onCreate 中加载 - // set sync or sync_cancel MenuItem syncItem = menu.findItem(R.id.menu_sync); if (syncItem != null) { - syncItem.setTitle( - GTaskSyncService.isSyncing() ? R.string.menu_sync_cancel : R.string.menu_sync); + syncItem.setTitle(R.string.menu_sync); // 始终显示“同步” } } else if (mState == ListEditState.SUB_FOLDER) { menu.clear(); // 子文件夹模式下可能需要清除并重新加载 @@ -1353,18 +1355,19 @@ public class NotesListActivity extends AppCompatActivity implements OnClickListe exportNoteToText(); break; } - case R.id.menu_sync: { - if (isSyncMode()) { - if (TextUtils.equals(item.getTitle(), getString(R.string.menu_sync))) { - GTaskSyncService.startSync(this); - } else { - GTaskSyncService.cancelSync(this); - } - } else { - startPreferenceActivity(); - } + case R.id.menu_sync: + // [新增] 弹出提示,告知用户正在同步 + Toast.makeText(this, "正在同步云端便签...", Toast.LENGTH_SHORT).show(); + + // [核心] 触发 WorkManager 立即执行同步 + androidx.work.OneTimeWorkRequest syncRequest = + new androidx.work.OneTimeWorkRequest.Builder(net.micode.notes.sync.SyncWorker.class) + .build(); + androidx.work.WorkManager.getInstance(this).enqueue(syncRequest); + + // 刷新列表显示 + startAsyncNotesListQuery(); break; - } case R.id.menu_setting: { startPreferenceActivity(); break; diff --git a/src/Notes-master/src/net/micode/notes/ui/NotesPreferenceActivity.java b/src/Notes-master/src/net/micode/notes/ui/NotesPreferenceActivity.java index 287cddb..17ec481 100644 --- a/src/Notes-master/src/net/micode/notes/ui/NotesPreferenceActivity.java +++ b/src/Notes-master/src/net/micode/notes/ui/NotesPreferenceActivity.java @@ -49,7 +49,6 @@ import android.net.Uri; // [新增] 修复错误 1 & 2 import net.micode.notes.R; import net.micode.notes.data.Notes; import net.micode.notes.data.Notes.NoteColumns; -import net.micode.notes.gtask.remote.GTaskSyncService; public class NotesPreferenceActivity extends PreferenceActivity { @@ -69,8 +68,6 @@ public class NotesPreferenceActivity extends PreferenceActivity { private PreferenceCategory mAccountCategory; - private GTaskReceiver mReceiver; - private Account[] mOriAccounts; private boolean mHasAddedAccount; @@ -86,10 +83,6 @@ public class NotesPreferenceActivity extends PreferenceActivity { addPreferencesFromResource(R.xml.preferences); mAccountCategory = (PreferenceCategory) findPreference(PREFERENCE_SYNC_ACCOUNT_KEY); - mReceiver = new GTaskReceiver(); - IntentFilter filter = new IntentFilter(); - filter.addAction(GTaskSyncService.GTASK_SERVICE_BROADCAST_NAME); - registerReceiver(mReceiver, filter, Context.RECEIVER_EXPORTED); mOriAccounts = null; View header = LayoutInflater.from(this).inflate(R.layout.settings_header, null); @@ -150,9 +143,6 @@ public class NotesPreferenceActivity extends PreferenceActivity { @Override protected void onDestroy() { - if (mReceiver != null) { - unregisterReceiver(mReceiver); - } super.onDestroy(); } @@ -187,159 +177,61 @@ public class NotesPreferenceActivity extends PreferenceActivity { mAccountCategory.removeAll(); Preference accountPref = new Preference(this); - final String defaultAccount = getSyncAccountName(this); - accountPref.setTitle(getString(R.string.preferences_account_title)); - accountPref.setSummary(getString(R.string.preferences_account_summary)); - accountPref.setOnPreferenceClickListener(new OnPreferenceClickListener() { - public boolean onPreferenceClick(Preference preference) { - if (!GTaskSyncService.isSyncing()) { - if (TextUtils.isEmpty(defaultAccount)) { - // the first time to set account - showSelectAccountAlertDialog(); - } else { - // if the account has already been set, we need to promp - // user about the risk - showChangeAccountConfirmAlertDialog(); - } - } else { - Toast.makeText(NotesPreferenceActivity.this, - R.string.preferences_toast_cannot_change_account, Toast.LENGTH_SHORT) - .show(); - } - return true; - } - }); - - mAccountCategory.addPreference(accountPref); - } - - private void loadSyncButton() { - Button syncButton = (Button) findViewById(R.id.preference_sync_button); - TextView lastSyncTimeView = (TextView) findViewById(R.id.prefenerece_sync_status_textview); - - // set button state - if (GTaskSyncService.isSyncing()) { - syncButton.setText(getString(R.string.preferences_button_sync_cancel)); - syncButton.setOnClickListener(new View.OnClickListener() { - public void onClick(View v) { - GTaskSyncService.cancelSync(NotesPreferenceActivity.this); + // [核心修改] 使用 Firebase 获取当前用户信息,不再使用 getSyncAccountName + com.google.firebase.auth.FirebaseUser user = com.google.firebase.auth.FirebaseAuth.getInstance().getCurrentUser(); + + if (user != null) { + // 已登录状态 + accountPref.setTitle("当前登录账号"); + accountPref.setSummary(user.getEmail()); + accountPref.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + public boolean onPreferenceClick(Preference preference) { + // 点击后弹出简单的信息确认,或者不做操作(注销已在主页菜单实现) + android.widget.Toast.makeText(NotesPreferenceActivity.this, + "账号已通过 Firebase 认证", android.widget.Toast.LENGTH_SHORT).show(); + return true; } }); } else { - syncButton.setText(getString(R.string.preferences_button_sync_immediately)); - syncButton.setOnClickListener(new View.OnClickListener() { - public void onClick(View v) { - GTaskSyncService.startSync(NotesPreferenceActivity.this); + // 未登录状态 + accountPref.setTitle("账号未登录"); + accountPref.setSummary("点击跳转至登录页面"); + accountPref.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + public boolean onPreferenceClick(Preference preference) { + Intent intent = new Intent(NotesPreferenceActivity.this, LoginActivity.class); + startActivity(intent); + return true; } }); } - syncButton.setEnabled(!TextUtils.isEmpty(getSyncAccountName(this))); - - // set last sync time - if (GTaskSyncService.isSyncing()) { - lastSyncTimeView.setText(GTaskSyncService.getProgressString()); - lastSyncTimeView.setVisibility(View.VISIBLE); - } else { - long lastSyncTime = getLastSyncTime(this); - if (lastSyncTime != 0) { - lastSyncTimeView.setText(getString(R.string.preferences_last_sync_time, - DateFormat.format(getString(R.string.preferences_last_sync_time_format), - lastSyncTime))); - lastSyncTimeView.setVisibility(View.VISIBLE); - } else { - lastSyncTimeView.setVisibility(View.GONE); - } - } - } - private void refreshUI() { - loadAccountPreference(); - loadSyncButton(); + mAccountCategory.addPreference(accountPref); } - private void showSelectAccountAlertDialog() { - AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this); - - View titleView = LayoutInflater.from(this).inflate(R.layout.account_dialog_title, null); - TextView titleTextView = (TextView) titleView.findViewById(R.id.account_dialog_title); - titleTextView.setText(getString(R.string.preferences_dialog_select_account_title)); - TextView subtitleTextView = (TextView) titleView.findViewById(R.id.account_dialog_subtitle); - subtitleTextView.setText(getString(R.string.preferences_dialog_select_account_tips)); - - dialogBuilder.setCustomTitle(titleView); - dialogBuilder.setPositiveButton(null, null); - - Account[] accounts = getGoogleAccounts(); - String defAccount = getSyncAccountName(this); - - mOriAccounts = accounts; - mHasAddedAccount = false; - - if (accounts.length > 0) { - CharSequence[] items = new CharSequence[accounts.length]; - final CharSequence[] itemMapping = items; - int checkedItem = -1; - int index = 0; - for (Account account : accounts) { - if (TextUtils.equals(account.name, defAccount)) { - checkedItem = index; - } - items[index++] = account.name; - } - dialogBuilder.setSingleChoiceItems(items, checkedItem, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - setSyncAccount(itemMapping[which].toString()); - dialog.dismiss(); - refreshUI(); - } - }); - } - - View addAccountView = LayoutInflater.from(this).inflate(R.layout.add_account_text, null); - dialogBuilder.setView(addAccountView); + private void loadSyncButton() { + Button syncButton = (Button) findViewById(R.id.preference_sync_button); + TextView lastSyncTimeView = (TextView) findViewById(R.id.prefenerece_sync_status_textview); - final AlertDialog dialog = dialogBuilder.show(); - addAccountView.setOnClickListener(new View.OnClickListener() { + // 始终显示“立即同步” + syncButton.setText(getString(R.string.preferences_button_sync_immediately)); + syncButton.setEnabled(true); + syncButton.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { - mHasAddedAccount = true; - Intent intent = new Intent("android.settings.ADD_ACCOUNT_SETTINGS"); - intent.putExtra(AUTHORITIES_FILTER_KEY, new String[] { - "gmail-ls" - }); - startActivityForResult(intent, -1); - dialog.dismiss(); + // 点击后执行我们的新同步 + androidx.work.OneTimeWorkRequest syncRequest = + new androidx.work.OneTimeWorkRequest.Builder(net.micode.notes.sync.SyncWorker.class).build(); + androidx.work.WorkManager.getInstance(NotesPreferenceActivity.this).enqueue(syncRequest); + Toast.makeText(NotesPreferenceActivity.this, "开始同步...", Toast.LENGTH_SHORT).show(); } }); + + // 暂时隐藏旧的状态文字 + lastSyncTimeView.setVisibility(View.GONE); } - private void showChangeAccountConfirmAlertDialog() { - AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this); - - View titleView = LayoutInflater.from(this).inflate(R.layout.account_dialog_title, null); - TextView titleTextView = (TextView) titleView.findViewById(R.id.account_dialog_title); - titleTextView.setText(getString(R.string.preferences_dialog_change_account_title, - getSyncAccountName(this))); - TextView subtitleTextView = (TextView) titleView.findViewById(R.id.account_dialog_subtitle); - subtitleTextView.setText(getString(R.string.preferences_dialog_change_account_warn_msg)); - dialogBuilder.setCustomTitle(titleView); - - CharSequence[] menuItemArray = new CharSequence[] { - getString(R.string.preferences_menu_change_account), - getString(R.string.preferences_menu_remove_account), - getString(R.string.preferences_menu_cancel) - }; - dialogBuilder.setItems(menuItemArray, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - if (which == 0) { - showSelectAccountAlertDialog(); - } else if (which == 1) { - removeSyncAccount(); - refreshUI(); - } - } - }); - dialogBuilder.show(); + private void refreshUI() { + loadAccountPreference(); + loadSyncButton(); } private Account[] getGoogleAccounts() { @@ -361,16 +253,6 @@ public class NotesPreferenceActivity extends PreferenceActivity { // clean up last sync time setLastSyncTime(this, 0); - // clean up local gtask related info - new Thread(new Runnable() { - public void run() { - ContentValues values = new ContentValues(); - values.put(NoteColumns.GTASK_ID, ""); - values.put(NoteColumns.SYNC_ID, 0); - getContentResolver().update(Notes.CONTENT_NOTE_URI, values, null, null); - } - }).start(); - Toast.makeText(NotesPreferenceActivity.this, getString(R.string.preferences_toast_success_set_accout, account), Toast.LENGTH_SHORT).show(); @@ -419,20 +301,6 @@ public class NotesPreferenceActivity extends PreferenceActivity { return settings.getLong(PREFERENCE_LAST_SYNC_TIME, 0); } - private class GTaskReceiver extends BroadcastReceiver { - - @Override - public void onReceive(Context context, Intent intent) { - refreshUI(); - if (intent.getBooleanExtra(GTaskSyncService.GTASK_SERVICE_BROADCAST_IS_SYNCING, false)) { - TextView syncStatus = (TextView) findViewById(R.id.prefenerece_sync_status_textview); - syncStatus.setText(intent - .getStringExtra(GTaskSyncService.GTASK_SERVICE_BROADCAST_PROGRESS_MSG)); - } - - } - } - public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: -- 2.34.1