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.
2Q1/ui/NotesPreferenceActivity.java

520 lines
31 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.ui;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.ActionBar;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceActivity;
import android.preference.PreferenceCategory;
import android.text.TextUtils;
import android.text.format.DateFormat;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
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;
// NotesPreferenceActivity类继承自PreferenceActivity用于展示和管理应用的偏好设置相关界面及功能
public class NotesPreferenceActivity extends PreferenceActivity {
// 定义偏好设置的名称常量用于在获取和操作SharedPreferences时作为标识
public static final String PREFERENCE_NAME = "notes_preferences";
// 定义用于存储同步账户名称的偏好设置键常量
public static final String PREFERENCE_SYNC_ACCOUNT_NAME = "pref_key_account_name";
// 定义用于存储上次同步时间的偏好设置键常量
public static final String PREFERENCE_LAST_SYNC_TIME = "pref_last_sync_time";
// 定义用于设置背景颜色相关功能的偏好设置键常量(可能是控制背景颜色随机显示等功能,具体需看业务逻辑)
public static final String PREFERENCE_SET_BG_COLOR_KEY = "pref_key_bg_random_appear";
// 定义与同步账户相关的偏好设置键常量,可能用于在偏好设置界面中定位或操作相关的账户设置项
private static final String PREFERENCE_SYNC_ACCOUNT_KEY = "pref_sync_account_key";
// 定义用于过滤广播的权限相关键常量(具体用途需结合广播相关逻辑进一步确定)
private static final String AUTHORITIES_FILTER_KEY = "authorities";
// 用于在偏好设置界面中对账户相关的偏好设置项进行分类管理的PreferenceCategory对象
private PreferenceCategory mAccountCategory;
// 自定义的广播接收器对象,用于接收特定的广播消息(这里可能与同步服务相关的广播有关)
private GTaskReceiver mReceiver;
// 用于保存原始的账户列表信息,可能用于对比账户变化情况等操作
private Account[] mOriAccounts;
// 用于标记是否添加了新账户的布尔变量初始值为false
private boolean mHasAddedAccount;
// onCreate方法在Activity创建时被调用用于进行初始化相关的操作
@Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
// 设置ActionBar的显示属性使得应用图标可以用于导航通常点击图标可返回上一级界面
getActionBar().setDisplayHomeAsUpEnabled(true);
// 从指定的XML资源文件R.xml.preferences中加载偏好设置界面的布局和配置信息构建出偏好设置界面的初始显示内容
addPreferencesFromResource(R.xml.preferences);
// 通过键PREFERENCE_SYNC_ACCOUNT_KEY从已加载的偏好设置中找到对应的PreferenceCategory对象用于后续对账户相关设置项的操作
mAccountCategory = (PreferenceCategory) findPreference(PREFERENCE_SYNC_ACCOUNT_KEY);
// 创建一个GTaskReceiver实例用于接收相关广播消息
mReceiver = new GTaskReceiver();
// 创建一个IntentFilter对象用于指定要接收的广播动作这里只关注GTaskSyncService.GTASK_SERVICE_BROADCAST_NAME对应的广播
IntentFilter filter = new IntentFilter();
filter.addAction(GTaskSyncService.GTASK_SERVICE_BROADCAST_NAME);
// 注册广播接收器使得该Activity能够接收到符合过滤条件的广播消息
registerReceiver(mReceiver, filter);
// 初始化原始账户列表为null后续可能会获取并赋值实际的账户信息
mOriAccounts = null;
// 通过LayoutInflater从当前上下文获取布局Inflater并加载指定的布局资源R.layout.settings_header作为头部视图添加到当前Activity的列表视图中第三个参数设置为true表示该头部视图在列表滚动时固定显示
View header = LayoutInflater.from(this).inflate(R.layout.settings_header, null);
getListView().addHeaderView(header, null, true);
}
// onResume方法在Activity重新回到前台可见状态时被调用常用于恢复或更新界面相关的操作以及处理一些业务逻辑
@Override
protected void onResume() {
super.onResume();
// 如果已经添加了新账户mHasAddedAccount为true
if (mHasAddedAccount) {
// 获取当前的谷歌账户列表
Account[] accounts = getGoogleAccounts();
// 如果原始账户列表不为null且新获取的账户数量大于原始账户数量说明可能添加了新账户
if (mOriAccounts!= null && accounts.length > mOriAccounts.length) {
// 遍历新获取的账户列表
for (Account accountNew : accounts) {
// 标记是否找到匹配的原始账户初始化为false
boolean found = false;
// 遍历原始账户列表,对比账户名称是否相同
for (Account accountOld : mOriAccounts) {
if (TextUtils.equals(accountOld.name, accountNew.name)) {
found = true;
break;
}
}
// 如果在原始账户列表中未找到匹配的账户,说明是新添加的账户
if (!found) {
// 设置同步账户为新添加的这个账户的名称,并跳出循环(只设置一个新账户作为同步账户即可,具体业务逻辑可能如此)
setSyncAccount(accountNew.name);
break;
}
}
}
}
// 调用refreshUI方法更新界面显示内容具体更新逻辑在该方法中实现代码中未完整展示该方法内容
refreshUI();
}
// 当Activity被销毁时调用的方法用于释放相关资源和进行一些清理操作
@Override
protected void onDestroy() {
// 如果广播接收器mReceiver不为空就注销该广播接收器避免内存泄漏等问题
if (mReceiver!= null) {
unregisterReceiver(mReceiver);
}
// 调用父类的onDestroy方法执行父类中定义的销毁相关的默认操作
super.onDestroy();
}
// 用于加载账户偏好设置相关内容的方法,例如在偏好设置界面中添加账户相关的设置项及设置其显示和点击等行为逻辑
private void loadAccountPreference() {
// 先移除账户偏好设置分类mAccountCategory下的所有已有偏好设置项确保后续添加的是最新的内容
mAccountCategory.removeAll();
// 创建一个新的Preference实例用于表示账户相关的偏好设置项
Preference accountPref = new Preference(this);
// 获取当前的默认同步账户名称通过调用getSyncAccountName方法
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) {
// 如果同步服务GTaskSyncService当前没有正在进行同步操作
if (!GTaskSyncService.isSyncing()) {
// 如果默认账户名称为空字符串,说明是第一次设置账户
if (TextUtils.isEmpty(defaultAccount)) {
// 弹出选择账户的警告对话框用于让用户选择要设置的账户具体逻辑在showSelectAccountAlertDialog方法中
showSelectAccountAlertDialog();
} else {
// 如果已经设置过账户了弹出确认更改账户的警告对话框提示用户更改账户可能存在的风险具体逻辑在showChangeAccountConfirmAlertDialog方法中
showChangeAccountConfirmAlertDialog();
}
} else {
// 如果同步服务正在同步通过Toast提示用户当前不能更改账户
Toast.makeText(NotesPreferenceActivity.this,
R.string.preferences_toast_cannot_change_account, Toast.LENGTH_SHORT)
.show();
}
// 返回true表示已处理该点击事件
return true;
}
});
// 将创建并设置好的账户偏好设置项添加到账户偏好设置分类中
mAccountCategory.addPreference(accountPref);
}
// 用于加载同步按钮相关设置的方法,包括设置按钮的文本、点击事件以及同步状态相关的显示文本等内容
private void loadSyncButton() {
// 通过findViewById方法找到布局中的同步按钮Button实例
Button syncButton = (Button) findViewById(R.id.preference_sync_button);
// 通过findViewById方法找到布局中的用于显示上次同步时间的TextView实例
TextView lastSyncTimeView = (TextView) findViewById(R.id.prefenerece_sync_status_textview);
// 根据同步服务GTaskSyncService是否正在同步来设置同步按钮的文本和点击事件逻辑
// 如果正在同步
if (GTaskSyncService.isSyncing()) {
// 设置按钮文本为取消同步的文本内容(通过资源字符串获取)
syncButton.setText(getString(R.string.preferences_button_sync_cancel));
// 为按钮设置点击监听器点击时调用GTaskSyncService的cancelSync方法来取消同步操作传入当前的NotesPreferenceActivity实例作为上下文
syncButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
GTaskSyncService.cancelSync(NotesPreferenceActivity.this);
}
});
} else {
// 如果没有正在同步
syncButton.setText(getString(R.string.preferences_button_sync_immediately));
// 为按钮设置点击监听器点击时调用GTaskSyncService的startSync方法来立即启动同步操作传入当前的NotesPreferenceActivity实例作为上下文
syncButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
GTaskSyncService.startSync(NotesPreferenceActivity.this);
}
});
}
// 根据是否设置了同步账户来决定同步按钮是否可用,只有设置了同步账户(同步账户名称不为空字符串)时,按钮才可用
syncButton.setEnabled(!TextUtils.isEmpty(getSyncAccountName(this)));
// 根据同步服务的状态来设置上次同步时间显示文本及可见性
// 如果正在同步
if (GTaskSyncService.isSyncing()) {
// 设置显示文本为同步服务的进度字符串通过GTaskSyncService的getProgressString方法获取并将该TextView设置为可见
lastSyncTimeView.setText(GTaskSyncService.getProgressString());
lastSyncTimeView.setVisibility(View.VISIBLE);
} else {
// 如果没有正在同步获取上次同步的时间戳通过调用getLastSyncTime方法
long lastSyncTime = getLastSyncTime(this);
// 如果上次同步时间戳不为0说明有上次同步记录
if (lastSyncTime!= 0) {
// 设置显示文本通过格式化字符串的方式将时间戳格式化为指定格式的日期时间字符串先通过资源字符串获取日期时间格式再进行格式化并将该TextView设置为可见
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 {
// 如果没有上次同步记录将该TextView设置为不可见
lastSyncTimeView.setVisibility(View.GONE);
}
}
}
// 用于刷新整个偏好设置界面的方法,通过调用加载账户偏好设置和加载同步按钮相关的方法来更新界面显示内容
private void refreshUI() {
loadAccountPreference();
loadSyncButton();
}
// 用于弹出选择账户的警告对话框的方法,在该对话框中展示可供选择的账户列表以及添加账户的入口等内容
private void showSelectAccountAlertDialog() {
// 创建一个AlertDialog.Builder实例用于构建警告对话框
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
// 通过LayoutInflater从当前上下文加载自定义的标题布局R.layout.account_dialog_title
View titleView = LayoutInflater.from(this).inflate(R.layout.account_dialog_title, null);
// 从加载的标题布局中找到对应的标题TextView实例
TextView titleTextView = (TextView) titleView.findViewById(R.id.account_dialog_title);
// 设置标题TextView的文本内容通过资源字符串获取对应的文本
titleTextView.setText(getString(R.string.preferences_dialog_select_account_title));
// 从加载的标题布局中找到对应的副标题TextView实例
TextView subtitleTextView = (TextView) titleView.findViewById(R.id.account_dialog_subtitle);
// 设置副标题TextView的文本内容通过资源字符串获取对应的文本
subtitleTextView.setText(getString(R.string.preferences_dialog_select_account_tips));
// 将自定义的标题视图设置为对话框的标题部分
dialogBuilder.setCustomTitle(titleView);
// 设置对话框的确认按钮正按钮这里先设置为null后续可能会根据具体逻辑再设置或者在某些情况下不需要点击操作
dialogBuilder.setPositiveButton(null, null);
// 获取当前的谷歌账户列表通过调用getGoogleAccounts方法
Account[] accounts = getGoogleAccounts();
// 获取当前的默认同步账户名称通过调用getSyncAccountName方法
String defAccount = getSyncAccountName(this);
// 将获取的账户列表保存到mOriAccounts变量中用于后续可能的对比等操作
mOriAccounts = accounts;
// 标记是否添加了新账户初始化为false
mHasAddedAccount = false;
// 如果获取到的账户列表长度大于0说明有可用的账户可供选择
if (accounts.length > 0) {
// 创建一个字符序列数组,长度与账户列表长度相同,用于存储账户名称,作为单选列表项展示给用户
CharSequence[] items = new CharSequence[accounts.length];
// 创建一个临时的字符序列数组用于在点击单选列表项时进行账户名称的映射操作这里其实和items数组内容基本一致只是为了方便后续代码逻辑理解和编写
final CharSequence[] itemMapping = items;
// 用于记录默认选中的账户在列表中的索引位置,初始化为 -1表示没有默认选中项
int checkedItem = -1;
// 索引变量用于遍历账户列表并填充items数组以及查找默认选中项的索引
int index = 0;
// 遍历账户列表
for (Account account : accounts) {
// 如果当前账户名称与默认同步账户名称相等,说明该账户是当前默认选中的账户,记录其索引位置
if (TextUtils.equals(account.name, defAccount)) {
checkedItem = index;
}
// 将账户名称添加到items数组中作为单选列表项的显示内容
items[index++] = account.name;
}
// 设置对话框的单选列表项内容、默认选中项索引以及点击监听器当用户点击某个单选列表项时调用setSyncAccount方法设置选中的账户作为同步账户然后关闭对话框并刷新界面通过调用refreshUI方法
dialogBuilder.setSingleChoiceItems(items, checkedItem,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
setSyncAccount(itemMapping[which].toString());
dialog.dismiss();
refreshUI();
}
});
}
// 通过LayoutInflater从当前上下文加载添加账户相关的布局R.layout.add_account_text用于在对话框中展示添加账户的入口视图
View addAccountView = LayoutInflater.from(this).inflate(R.layout.add_account_text, null);
// 将添加账户的入口视图添加到对话框中
dialogBuilder.setView(addAccountView);
// 显示构建好的警告对话框,并获取对话框实例
final AlertDialog dialog = dialogBuilder.show();
// 为添加账户的入口视图设置点击监听器当用户点击时标记已添加新账户mHasAddedAccount设置为true然后启动添加账户的系统设置页面通过意图指定相关动作和参数最后关闭当前对话框
addAccountView.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();
}
});
}
// 用于弹出更改账户确认警告对话框的方法,在对话框中展示相关提示信息以及操作选项供用户选择
private void showChangeAccountConfirmAlertDialog() {
// 创建一个AlertDialog.Builder实例用于构建警告对话框
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
// 通过LayoutInflater从当前上下文加载自定义的标题布局R.layout.account_dialog_title
View titleView = LayoutInflater.from(this).inflate(R.layout.account_dialog_title, null);
// 从加载的标题布局中找到对应的标题TextView实例
TextView titleTextView = (TextView) titleView.findViewById(R.id.account_dialog_title);
// 设置标题TextView的文本内容通过资源字符串获取对应的格式化文本其中格式化参数为当前的同步账户名称通过调用getSyncAccountName方法获取
titleTextView.setText(getString(R.string.preferences_dialog_change_account_title,
getSyncAccountName(this)));
// 从加载的标题布局中找到对应的副标题TextView实例
TextView subtitleTextView = (TextView) titleView.findViewById(R.id.account_dialog_subtitle);
// 设置副标题TextView的文本内容通过资源字符串获取对应的警告提示文本
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) {
// 如果用户点击的是“更改账户”菜单项索引为0
if (which == 0) {
// 弹出选择账户的警告对话框通过调用showSelectAccountAlertDialog方法让用户重新选择账户
showSelectAccountAlertDialog();
} else if (which == 1) {
// 如果用户点击的是“移除账户”菜单项索引为1则调用removeSyncAccount方法移除当前的同步账户并刷新界面通过调用refreshUI方法
removeSyncAccount();
refreshUI();
}
}
});
// 显示构建好的警告对话框
dialogBuilder.show();
}
// 用于获取当前设备上的谷歌账户列表的方法通过AccountManager来获取指定类型"com.google")的账户信息
private Account[] getGoogleAccounts() {
// 获取AccountManager实例传入当前上下文
AccountManager accountManager = AccountManager.get(this);
// 调用AccountManager的getAccountsByType方法获取类型为"com.google"的账户数组并返回
return accountManager.getAccountsByType("com.google");
}
// 用于设置同步账户的方法,根据传入的账户名称来更新偏好设置中的同步账户相关信息,并进行一些相关的数据清理和提示操作
private void setSyncAccount(String account) {
// 如果传入的账户与当前获取的同步账户名称不一致(说明要进行账户更改操作)
if (!getSyncAccountName(this).equals(account)) {
// 获取应用的SharedPreferences实例用于存储和读取偏好设置数据指定偏好设置名称PREFERENCE_NAME和私有访问模式Context.MODE_PRIVATE
SharedPreferences settings = getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
// 获取SharedPreferences的编辑器用于修改偏好设置中的数据
SharedPreferences.Editor editor = settings.edit();
// 如果传入的账户不为null将其存入偏好设置中对应的键PREFERENCE_SYNC_ACCOUNT_NAME
if (account!= null) {
editor.putString(PREFERENCE_SYNC_ACCOUNT_NAME, account);
} else {
// 如果传入的账户为null将同步账户名称设置为空字符串
editor.putString(PREFERENCE_SYNC_ACCOUNT_NAME, "");
}
// 提交对偏好设置的修改,使其生效
editor.commit();
// 调用setLastSyncTime方法将上次同步时间清理设置为0表示重新开始同步相关的计时等逻辑
setLastSyncTime(this, 0);
// 在一个新线程中执行清理本地与GTask相关信息的操作创建一个ContentValues实例用于存储要更新的数据
new Thread(new Runnable() {
public void run() {
ContentValues values = new ContentValues();
// 将笔记相关列NoteColumns.GTASK_ID的值设置为空字符串可能用于清除之前与该账户关联的同步任务相关标识
values.put(NoteColumns.GTASK_ID, "");
// 将同步相关列NoteColumns.SYNC_ID的值设置为0可能用于重置同步相关的状态标识
values.put(NoteColumns.SYNC_ID, 0);
// 通过内容解析器getContentResolver更新笔记相关的内容提供器Notes.CONTENT_NOTE_URI中的数据使用设置好的ContentValues进行更新这里更新条件为null可能是更新所有符合条件的数据具体需看内容提供器的实现逻辑
getContentResolver().update(Notes.CONTENT_NOTE_URI, values, null, null);
}
}).start();
// 通过Toast提示用户账户设置成功显示的文本通过资源字符串获取并传入设置的账户名称作为格式化参数
Toast.makeText(NotesPreferenceActivity.this,
getString(R.string.preferences_toast_success_set_accout, account),
Toast.LENGTH_SHORT).show();
}
}
// 用于移除同步账户的方法从偏好设置中移除同步账户相关的信息并清理本地与GTask相关的信息
private void removeSyncAccount() {
// 获取应用的SharedPreferences实例用于存储和读取偏好设置数据指定偏好设置名称PREFERENCE_NAME和私有访问模式Context.MODE_PRIVATE
SharedPreferences settings = getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
// 获取SharedPreferences的编辑器用于修改偏好设置中的数据
SharedPreferences.Editor editor = settings.edit();
// 如果偏好设置中包含同步账户名称相关的键PREFERENCE_SYNC_ACCOUNT_NAME则移除该键对应的值
if (settings.contains(PREFERENCE_SYNC_ACCOUNT_NAME)) {
editor.remove(PREFERENCE_SYNC_ACCOUNT_NAME);
}
// 如果偏好设置中包含上次同步时间相关的键PREFERENCE_LAST_SYNC_TIME则移除该键对应的值
if (settings.contains(PREFERENCE_LAST_SYNC_TIME)) {
editor.remove(PREFERENCE_LAST_SYNC_TIME);
}
// 提交对偏好设置的修改,使其生效
editor.commit();
// 在一个新线程中执行清理本地与GTask相关信息的操作创建一个ContentValues实例用于存储要更新的数据
new Thread(new Runnable() {
public void run() {
ContentValues values = new ContentValues();
// 将笔记相关列NoteColumns.GTASK_ID的值设置为空字符串可能用于清除之前与该账户关联的同步任务相关标识
values.put(NoteColumns.GTASK_ID, "");
// 将同步相关列NoteColumns.SYNC_ID的值设置为0可能用于重置同步相关的状态标识
values.put(NoteColumns.SYNC_ID, 0);
// 通过内容解析器getContentResolver更新笔记相关的内容提供器Notes.CONTENT_NOTE_URI中的数据使用设置好的ContentValues进行更新这里更新条件为null可能是更新所有符合条件的数据具体需看内容提供器的实现逻辑
getContentResolver().update(Notes.CONTENT_NOTE_URI, values, null, null);
}
}).start();
}
// 静态方法用于获取当前设置的同步账户名称从应用的SharedPreferences中读取对应键PREFERENCE_SYNC_ACCOUNT_NAME下存储的值如果不存在则返回空字符串
public static String getSyncAccountName(Context context) {
SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME,
Context.MODE_PRIVATE);
return settings.getString(PREFERENCE_SYNC_ACCOUNT_NAME, "");
}
// 静态方法用于设置上次同步时间将指定的时间戳time存入应用的SharedPreferences中对应的键PREFERENCE_LAST_SYNC_TIME
public static void setLastSyncTime(Context context, long time) {
SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME,
Context.MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
editor.putLong(PREFERENCE_LAST_SYNC_TIME, time);
editor.commit();
}
// 静态方法用于获取上次同步时间从应用的SharedPreferences中读取对应键PREFERENCE_LAST_SYNC_TIME下存储的时间戳如果不存在则返回0
public static long getLastSyncTime(Context context) {
SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME,
Context.MODE_PRIVATE);
return settings.getLong(PREFERENCE_LAST_SYNC_TIME, 0);
}
// 自定义的广播接收器类继承自BroadcastReceiver用于接收特定的广播消息并做出相应的响应
private class GTaskReceiver extends BroadcastReceiver {
// 当接收到广播消息时调用的方法,在这里进行界面刷新以及根据广播中的同步相关信息更新界面显示内容等操作
@Override
public void onReceive(Context context, Intent intent) {
// 调用refreshUI方法刷新整个偏好设置界面更新界面上的各种显示内容如账户信息、同步按钮状态等
refreshUI();
// 如果广播消息中携带的表示是否正在同步的额外数据通过GTaskSyncService.GTASK_SERVICE_BROADCAST_IS_SYNCING键获取为true说明正在同步
if (intent.getBooleanExtra(GTaskSyncService.GTASK_SERVICE_BROADCAST_IS_SYNCING, false)) {
// 通过findViewById方法找到用于显示同步状态的TextView实例
TextView syncStatus = (TextView) findViewById(R.id.prefenerece_sync_status_textview);
// 设置该TextView的文本内容为广播消息中携带的同步进度相关信息通过GTaskSyncService.GTASK_SERVICE_BROADCAST_PROGRESS_MSG键获取
syncStatus.setText(intent.getStringExtra(GTaskSyncService.GTASK_SERVICE_BROADCAST_PROGRESS_MSG));
}
}
}
// 用于处理选项菜单中菜单项被选中时的操作逻辑,例如处理返回按钮等菜单项的点击事件
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
// 如果点击的是Home按钮通常是左上角的返回箭头图标用于返回上一级界面等操作
case android.R.id.home:
// 创建一个意图Intent指定要启动的目标Activity为NotesListActivity.class即返回笔记列表界面
Intent intent = new Intent(this, NotesListActivity.class);
// 添加标志位使得启动的Activity会清除其上的所有其他Activity实现返回栈的清理回到笔记列表界面并将其置于栈顶
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
// 根据意图启动Activity
startActivity(intent);
// 返回true表示已处理该菜单项点击事件
return true;
default:
// 如果点击的是其他未处理的菜单项返回false表示未处理该事件
return false;
}
}
}