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.
XiaoMiNotes/src/net/micode/notes/ui/NotesPreferenceActivity.java

432 lines
19 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.

/*
* 版权所有 (c) 2010-2011The MiCode 开源社区 (www.micode.net)
*
* 根据 Apache 许可证 2.0 版本("许可证")授权;
* 除非遵守许可证,否则不得使用此文件。
* 您可以在以下网址获取许可证副本:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 除非适用法律要求或书面同意,否则按"原样"分发软件,
* 没有任何明示或暗示的担保或条件。
* 有关许可证下权限和限制的具体语言,请参阅许可证。
*/
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;
/**
* 笔记应用设置页面Activity
* 继承自PreferenceActivity用于管理应用的偏好设置
* 主要功能:同步账户设置、同步状态显示、同步操作等
*/
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; // 账户设置分类
private GTaskReceiver mReceiver; // 同步服务广播接收器
private Account[] mOriAccounts; // 原始账户列表
private boolean mHasAddedAccount; // 是否添加了新账户的标志
@Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
/* 使用应用图标进行导航 */
getActionBar().setDisplayHomeAsUpEnabled(true); // 显示返回主页按钮
addPreferencesFromResource(R.xml.preferences); // 从XML资源加载偏好设置
mAccountCategory = (PreferenceCategory) findPreference(PREFERENCE_SYNC_ACCOUNT_KEY); // 查找账户设置分类
mReceiver = new GTaskReceiver(); // 创建广播接收器
IntentFilter filter = new IntentFilter(); // 创建Intent过滤器
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); // 将头部添加到列表视图
}
@Override
protected void onResume() {
super.onResume();
// 如果用户添加了新账户,需要自动设置同步账户
if (mHasAddedAccount) {
Account[] accounts = getGoogleAccounts(); // 获取当前所有Google账户
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;
}
}
}
}
refreshUI(); // 刷新UI
}
@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.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(); // 获取所有Google账户
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(); // 刷新UI
}
});
}
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); // 启动添加账户Activity
dialog.dismiss(); // 关闭对话框
}
});
}
/**
* 显示更改账户确认对话框
*/
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(); // 刷新UI
}
// 选项2为取消不执行任何操作
}
});
dialogBuilder.show(); // 显示对话框
}
/**
* 获取所有Google账户
* @return Google账户数组
*/
private Account[] getGoogleAccounts() {
AccountManager accountManager = AccountManager.get(this); // 获取账户管理器
return accountManager.getAccountsByType("com.google"); // 返回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();
values.put(NoteColumns.GTASK_ID, ""); // 清空GTask ID
values.put(NoteColumns.SYNC_ID, 0); // 清空同步ID
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 settings = getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE); // 获取偏好设置
SharedPreferences.Editor editor = settings.edit(); // 获取编辑器
if (settings.contains(PREFERENCE_SYNC_ACCOUNT_NAME)) {
editor.remove(PREFERENCE_SYNC_ACCOUNT_NAME); // 移除同步账户名称
}
if (settings.contains(PREFERENCE_LAST_SYNC_TIME)) {
editor.remove(PREFERENCE_LAST_SYNC_TIME); // 移除上次同步时间
}
editor.commit(); // 提交更改
// 清除本地GTask相关信息
new Thread(new Runnable() {
public void run() {
ContentValues values = new ContentValues();
values.put(NoteColumns.GTASK_ID, ""); // 清空GTask ID
values.put(NoteColumns.SYNC_ID, 0); // 清空同步ID
getContentResolver().update(Notes.CONTENT_NOTE_URI, values, null, null); // 更新数据库
}
}).start();
}
/**
* 获取同步账户名称
* @param context 上下文
* @return 同步账户名称,如果没有则为空字符串
*/
public static String getSyncAccountName(Context context) {
SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME,
Context.MODE_PRIVATE); // 获取偏好设置
return settings.getString(PREFERENCE_SYNC_ACCOUNT_NAME, ""); // 返回账户名称
}
/**
* 设置上次同步时间
* @param context 上下文
* @param 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(); // 提交更改
}
/**
* 获取上次同步时间
* @param context 上下文
* @return 上次同步时间如果没有则为0
*/
public static long getLastSyncTime(Context context) {
SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME,
Context.MODE_PRIVATE); // 获取偏好设置
return settings.getLong(PREFERENCE_LAST_SYNC_TIME, 0); // 返回同步时间
}
/**
* GTask同步服务广播接收器
* 用于接收同步状态更新并刷新UI
*/
private class GTaskReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
refreshUI(); // 刷新UI
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)); // 更新进度消息
}
}
}
/**
* 处理选项菜单项选择
* @param item 被选中的菜单项
* @return 是否处理了该菜单项
*/
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home: // 返回主页按钮
Intent intent = new Intent(this, NotesListActivity.class); // 跳转到笔记列表Activity
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); // 清除Activity栈
startActivity(intent);
return true;
default:
return false;
}
}
}