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

530 lines
22 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 是一个用于管理笔记应用设置的活动类。
* 它允许用户设置同步账户、执行同步操作,并显示最后一次同步的时间。
*/
public class NotesPreferenceActivity extends PreferenceActivity {
// 存储笔记设置的共享偏好名称
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";
// 同步账户偏好类别
private PreferenceCategory mAccountCategory;
// 用于接收 GTaskSyncService 广播的接收器
private GTaskReceiver mReceiver;
// 原始的 Google 账户数组
private Account[] mOriAccounts;
// 标记是否添加了新账户
private boolean mHasAddedAccount;
/**
* 活动创建时调用,进行初始化操作。
* @param icicle 保存的活动状态
*/
@Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
// 设置应用图标可用于导航返回
getActionBar().setDisplayHomeAsUpEnabled(true);
// 从 XML 文件中加载偏好设置
addPreferencesFromResource(R.xml.preferences);
// 查找同步账户偏好类别
mAccountCategory = (PreferenceCategory) findPreference(PREFERENCE_SYNC_ACCOUNT_KEY);
// 创建 GTask 广播接收器
mReceiver = new GTaskReceiver();
// 创建意图过滤器,监听 GTaskSyncService 的广播
IntentFilter filter = new IntentFilter();
filter.addAction(GTaskSyncService.GTASK_SERVICE_BROADCAST_NAME);
// 注册广播接收器
registerReceiver(mReceiver, filter);
// 初始化原始账户数组
mOriAccounts = null;
// 加载设置头部视图
View header = LayoutInflater.from(this).inflate(R.layout.settings_header, null);
// 将头部视图添加到列表视图中
getListView().addHeaderView(header, null, true);
}
/**
* 活动恢复时调用,检查是否添加了新账户并刷新 UI。
*/
@Override
protected void onResume() {
super.onResume();
// 如果添加了新账户,自动设置同步账户
if (mHasAddedAccount) {
Account[] accounts = getGoogleAccounts();
if (mOriAccounts != null && accounts.length > mOriAccounts.length) {
for (Account accountNew : accounts) {
boolean found = false;
for (Account accountOld : mOriAccounts) {
if (TextUtils.equals(accountOld.name, accountNew.name)) {
found = true;
break;
}
}
if (!found) {
setSyncAccount(accountNew.name);
break;
}
}
}
}
// 刷新 UI
refreshUI();
}
/**
* 活动销毁时调用,注销广播接收器。
*/
@Override
protected void onDestroy() {
if (mReceiver != null) {
unregisterReceiver(mReceiver);
}
super.onDestroy();
}
/**
* 加载同步账户偏好设置。
*/
private void loadAccountPreference() {
// 清空同步账户偏好类别中的所有偏好
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)) {
// 如果没有设置同步账户,显示选择账户的对话框
showSelectAccountAlertDialog();
} else {
// 如果已经设置了同步账户,显示更改账户的确认对话框
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);
// 根据同步状态设置按钮状态和文本
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);
}
});
} else {
syncButton.setText(getString(R.string.preferences_button_sync_immediately));
syncButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// 立即开始同步操作
GTaskSyncService.startSync(NotesPreferenceActivity.this);
}
});
}
// 只有在设置了同步账户时,同步按钮才可用
syncButton.setEnabled(!TextUtils.isEmpty(getSyncAccountName(this)));
// 根据同步状态设置最后一次同步时间的显示
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);
}
}
}
/**
* 刷新 UI包括同步账户偏好和同步按钮。
*/
private void refreshUI() {
loadAccountPreference();
loadSyncButton();
}
/**
* 显示选择账户的对话框。
*/
private void showSelectAccountAlertDialog() {
// 创建一个 AlertDialog 构建器
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);
// 获取所有 Google 账户
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();
// 刷新 UI
refreshUI();
}
});
}
// 加载添加账户的视图
View addAccountView = LayoutInflater.from(this).inflate(R.layout.add_account_text, null);
// 设置对话框的视图
dialogBuilder.setView(addAccountView);
// 显示对话框
final AlertDialog dialog = dialogBuilder.show();
// 设置添加账户视图的点击监听器
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 构建器
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) {
// 选择移除账户,移除同步账户并刷新 UI
removeSyncAccount();
refreshUI();
}
}
});
// 显示对话框
dialogBuilder.show();
}
/**
* 获取所有 Google 账户。
* @return Google 账户数组
*/
private Account[] getGoogleAccounts() {
// 获取账户管理器
AccountManager accountManager = AccountManager.get(this);
// 获取所有 Google 账户
return accountManager.getAccountsByType("com.google");
}
/**
* 设置同步账户。
* @param account 要设置的账户名称
*/
private void setSyncAccount(String account) {
if (!getSyncAccountName(this).equals(account)) {
// 获取共享偏好设置
SharedPreferences settings = getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
// 获取偏好编辑器
SharedPreferences.Editor editor = settings.edit();
if (account != null) {
// 保存同步账户名称
editor.putString(PREFERENCE_SYNC_ACCOUNT_NAME, account);
} else {
// 清空同步账户名称
editor.putString(PREFERENCE_SYNC_ACCOUNT_NAME, "");
}
// 提交更改
editor.commit();
// 清空最后一次同步时间
setLastSyncTime(this, 0);
// 清理本地与 GTask 相关的信息
new Thread(new Runnable() {
public void run() {
// 创建内容值对象
ContentValues values = new ContentValues();
// 清空 GTask ID
values.put(NoteColumns.GTASK_ID, "");
// 清空同步 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();
}
}
// 移除同步账户相关设置
private void removeSyncAccount() {
// 获取指定名称的 SharedPreferences 对象,使用私有模式,确保只有本应用可以访问这些设置
SharedPreferences settings = getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
// 获取 SharedPreferences 的编辑器,用于修改存储的设置
SharedPreferences.Editor editor = settings.edit();
// 检查 SharedPreferences 中是否包含同步账户名称的键
if (settings.contains(PREFERENCE_SYNC_ACCOUNT_NAME)) {
// 如果包含,则从编辑器中移除该键值对
editor.remove(PREFERENCE_SYNC_ACCOUNT_NAME);
}
// 检查 SharedPreferences 中是否包含最后同步时间的键
if (settings.contains(PREFERENCE_LAST_SYNC_TIME)) {
// 如果包含,则从编辑器中移除该键值对
editor.remove(PREFERENCE_LAST_SYNC_TIME);
}
// 提交编辑器中的修改,将更改保存到 SharedPreferences 中
editor.commit();
// 清理本地与 Google 任务GTask相关的信息由于数据库操作可能会阻塞主线程因此在新线程中执行
new Thread(new Runnable() {
public void run() {
// 创建一个 ContentValues 对象,用于存储要更新的数据
ContentValues values = new ContentValues();
// 将 GTask ID 字段设置为空字符串
values.put(NoteColumns.GTASK_ID, "");
// 将同步 ID 字段设置为 0
values.put(NoteColumns.SYNC_ID, 0);
// 使用 ContentResolver 更新 Notes 内容提供者中的笔记数据,将 GTask ID 和同步 ID 字段清空
getContentResolver().update(Notes.CONTENT_NOTE_URI, values, null, null);
}
}).start();
}
// 获取当前设置的同步账户名称
public static String getSyncAccountName(Context context) {
// 获取指定名称的 SharedPreferences 对象,使用私有模式
SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME,
Context.MODE_PRIVATE);
// 从 SharedPreferences 中获取同步账户名称,如果不存在则返回空字符串
return settings.getString(PREFERENCE_SYNC_ACCOUNT_NAME, "");
}
// 设置最后一次同步的时间
public static void setLastSyncTime(Context context, long time) {
// 获取指定名称的 SharedPreferences 对象,使用私有模式
SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME,
Context.MODE_PRIVATE);
// 获取 SharedPreferences 的编辑器,用于修改存储的设置
SharedPreferences.Editor editor = settings.edit();
// 将最后同步时间存储到编辑器中
editor.putLong(PREFERENCE_LAST_SYNC_TIME, time);
// 提交编辑器中的修改,将更改保存到 SharedPreferences 中
editor.commit();
}
// 获取最后一次同步的时间
public static long getLastSyncTime(Context context) {
// 获取指定名称的 SharedPreferences 对象,使用私有模式
SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME,
Context.MODE_PRIVATE);
// 从 SharedPreferences 中获取最后同步时间,如果不存在则返回 0
return settings.getLong(PREFERENCE_LAST_SYNC_TIME, 0);
}
// 自定义广播接收器,用于接收 GTask 同步服务的广播
private class GTaskReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// 刷新界面,更新账户设置和同步按钮状态等信息
refreshUI();
// 检查广播意图中是否包含正在同步的标志,并且标志为 true
if (intent.getBooleanExtra(GTaskSyncService.GTASK_SERVICE_BROADCAST_IS_SYNCING, false)) {
// 查找用于显示同步状态的 TextView 控件
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) {
// 根据点击的菜单项 ID 进行不同的处理
switch (item.getItemId()) {
// 如果点击的是应用图标(即返回按钮)
case android.R.id.home:
// 创建一个意图,用于启动 NotesListActivity
Intent intent = new Intent(this, NotesListActivity.class);
// 添加标志,确保启动的 NotesListActivity 位于任务栈的顶部,并清除之前的所有活动
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
// 启动 NotesListActivity
startActivity(intent);
// 返回 true 表示事件已处理
return true;
// 如果点击的是其他菜单项
default:
// 返回 false 表示事件未处理
return false;
}
}