Use Drawer in Settings app
- get rid of PreferenceActivity as much as we can and use fragments instead - add Drawer widget - add Dashboard high level entry into the Drawer (but this is work in progress and would be done in another CL) - add bypass of fragment's Header validation when launched from the Drawer but *force* validation if external call thru an Intent Be aware that WifiPickerActivity should remain for now a PreferenceActivity. It is used by SetupWizard and should not trigger running the SettingsActivity's header building code. SetupWizard is a Home during the provisionnig process and then deactivate itself as a Home but would make the Home header to appear in the Drawer (because momentarily we would have two Home). Also, verified that: - the WiFi settings still work when called from SetupWizard - when you have multiple Launchers, the Home header will appear in the list of Headers in the Drawer Change-Id: I407a5e0fdd843ad7615d3d511c416a44e3d97c90
This commit is contained in:
251
src/com/android/settings/accounts/ChooseAccountFragment.java
Normal file
251
src/com/android/settings/accounts/ChooseAccountFragment.java
Normal file
@@ -0,0 +1,251 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* 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 com.android.settings.accounts;
|
||||
|
||||
import android.accounts.AccountManager;
|
||||
import android.accounts.AuthenticatorDescription;
|
||||
import android.app.Activity;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SyncAdapterType;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.preference.Preference;
|
||||
import android.preference.PreferenceGroup;
|
||||
import android.preference.PreferenceScreen;
|
||||
import android.util.Log;
|
||||
import com.android.internal.util.CharSequences;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsPreferenceFragment;
|
||||
import com.google.android.collect.Maps;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Activity asking a user to select an account to be set up.
|
||||
*/
|
||||
public class ChooseAccountFragment extends SettingsPreferenceFragment {
|
||||
|
||||
private static final String TAG = "ChooseAccountFragment";
|
||||
private String[] mAuthorities;
|
||||
private PreferenceGroup mAddAccountGroup;
|
||||
private final ArrayList<ProviderEntry> mProviderList = new ArrayList<ProviderEntry>();
|
||||
public HashSet<String> mAccountTypesFilter;
|
||||
private AuthenticatorDescription[] mAuthDescs;
|
||||
private HashMap<String, ArrayList<String>> mAccountTypeToAuthorities = null;
|
||||
private Map<String, AuthenticatorDescription> mTypeToAuthDescription
|
||||
= new HashMap<String, AuthenticatorDescription>();
|
||||
|
||||
private static class ProviderEntry implements Comparable<ProviderEntry> {
|
||||
private final CharSequence name;
|
||||
private final String type;
|
||||
ProviderEntry(CharSequence providerName, String accountType) {
|
||||
name = providerName;
|
||||
type = accountType;
|
||||
}
|
||||
|
||||
public int compareTo(ProviderEntry another) {
|
||||
if (name == null) {
|
||||
return -1;
|
||||
}
|
||||
if (another.name == null) {
|
||||
return +1;
|
||||
}
|
||||
return CharSequences.compareToIgnoreCase(name, another.name);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle icicle) {
|
||||
super.onCreate(icicle);
|
||||
|
||||
addPreferencesFromResource(R.xml.add_account_settings);
|
||||
mAuthorities = getActivity().getIntent().getStringArrayExtra(
|
||||
AccountPreferenceBase.AUTHORITIES_FILTER_KEY);
|
||||
String[] accountTypesFilter = getActivity().getIntent().getStringArrayExtra(
|
||||
AccountPreferenceBase.ACCOUNT_TYPES_FILTER_KEY);
|
||||
if (accountTypesFilter != null) {
|
||||
mAccountTypesFilter = new HashSet<String>();
|
||||
for (String accountType : accountTypesFilter) {
|
||||
mAccountTypesFilter.add(accountType);
|
||||
}
|
||||
}
|
||||
mAddAccountGroup = getPreferenceScreen();
|
||||
updateAuthDescriptions();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates provider icons. Subclasses should call this in onCreate()
|
||||
* and update any UI that depends on AuthenticatorDescriptions in onAuthDescriptionsUpdated().
|
||||
*/
|
||||
private void updateAuthDescriptions() {
|
||||
mAuthDescs = AccountManager.get(getActivity()).getAuthenticatorTypes();
|
||||
for (int i = 0; i < mAuthDescs.length; i++) {
|
||||
mTypeToAuthDescription.put(mAuthDescs[i].type, mAuthDescs[i]);
|
||||
}
|
||||
onAuthDescriptionsUpdated();
|
||||
}
|
||||
|
||||
private void onAuthDescriptionsUpdated() {
|
||||
// Create list of providers to show on preference screen
|
||||
for (int i = 0; i < mAuthDescs.length; i++) {
|
||||
String accountType = mAuthDescs[i].type;
|
||||
CharSequence providerName = getLabelForType(accountType);
|
||||
|
||||
// Skip preferences for authorities not specified. If no authorities specified,
|
||||
// then include them all.
|
||||
ArrayList<String> accountAuths = getAuthoritiesForAccountType(accountType);
|
||||
boolean addAccountPref = true;
|
||||
if (mAuthorities != null && mAuthorities.length > 0 && accountAuths != null) {
|
||||
addAccountPref = false;
|
||||
for (int k = 0; k < mAuthorities.length; k++) {
|
||||
if (accountAuths.contains(mAuthorities[k])) {
|
||||
addAccountPref = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (addAccountPref && mAccountTypesFilter != null
|
||||
&& !mAccountTypesFilter.contains(accountType)) {
|
||||
addAccountPref = false;
|
||||
}
|
||||
if (addAccountPref) {
|
||||
mProviderList.add(new ProviderEntry(providerName, accountType));
|
||||
} else {
|
||||
if (Log.isLoggable(TAG, Log.VERBOSE)) {
|
||||
Log.v(TAG, "Skipped pref " + providerName + ": has no authority we need");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mProviderList.size() == 1) {
|
||||
// If there's only one provider that matches, just run it.
|
||||
finishWithAccountType(mProviderList.get(0).type);
|
||||
} else if (mProviderList.size() > 0) {
|
||||
Collections.sort(mProviderList);
|
||||
mAddAccountGroup.removeAll();
|
||||
for (ProviderEntry pref : mProviderList) {
|
||||
Drawable drawable = getDrawableForType(pref.type);
|
||||
ProviderPreference p =
|
||||
new ProviderPreference(getActivity(), pref.type, drawable, pref.name);
|
||||
mAddAccountGroup.addPreference(p);
|
||||
}
|
||||
} else {
|
||||
if (Log.isLoggable(TAG, Log.VERBOSE)) {
|
||||
final StringBuilder auths = new StringBuilder();
|
||||
for (String a : mAuthorities) {
|
||||
auths.append(a);
|
||||
auths.append(' ');
|
||||
}
|
||||
Log.v(TAG, "No providers found for authorities: " + auths);
|
||||
}
|
||||
getActivity().setResult(Activity.RESULT_CANCELED);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
public ArrayList<String> getAuthoritiesForAccountType(String type) {
|
||||
if (mAccountTypeToAuthorities == null) {
|
||||
mAccountTypeToAuthorities = Maps.newHashMap();
|
||||
SyncAdapterType[] syncAdapters = ContentResolver.getSyncAdapterTypes();
|
||||
for (int i = 0, n = syncAdapters.length; i < n; i++) {
|
||||
final SyncAdapterType sa = syncAdapters[i];
|
||||
ArrayList<String> authorities = mAccountTypeToAuthorities.get(sa.accountType);
|
||||
if (authorities == null) {
|
||||
authorities = new ArrayList<String>();
|
||||
mAccountTypeToAuthorities.put(sa.accountType, authorities);
|
||||
}
|
||||
if (Log.isLoggable(TAG, Log.VERBOSE)) {
|
||||
Log.d(TAG, "added authority " + sa.authority + " to accountType "
|
||||
+ sa.accountType);
|
||||
}
|
||||
authorities.add(sa.authority);
|
||||
}
|
||||
}
|
||||
return mAccountTypeToAuthorities.get(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an icon associated with a particular account type. If none found, return null.
|
||||
* @param accountType the type of account
|
||||
* @return a drawable for the icon or null if one cannot be found.
|
||||
*/
|
||||
protected Drawable getDrawableForType(final String accountType) {
|
||||
Drawable icon = null;
|
||||
if (mTypeToAuthDescription.containsKey(accountType)) {
|
||||
try {
|
||||
AuthenticatorDescription desc = mTypeToAuthDescription.get(accountType);
|
||||
Context authContext = getActivity().createPackageContext(desc.packageName, 0);
|
||||
icon = authContext.getResources().getDrawable(desc.iconId);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
// TODO: place holder icon for missing account icons?
|
||||
Log.w(TAG, "No icon name for account type " + accountType);
|
||||
} catch (Resources.NotFoundException e) {
|
||||
// TODO: place holder icon for missing account icons?
|
||||
Log.w(TAG, "No icon resource for account type " + accountType);
|
||||
}
|
||||
}
|
||||
return icon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the label associated with a particular account type. If none found, return null.
|
||||
* @param accountType the type of account
|
||||
* @return a CharSequence for the label or null if one cannot be found.
|
||||
*/
|
||||
protected CharSequence getLabelForType(final String accountType) {
|
||||
CharSequence label = null;
|
||||
if (mTypeToAuthDescription.containsKey(accountType)) {
|
||||
try {
|
||||
AuthenticatorDescription desc = mTypeToAuthDescription.get(accountType);
|
||||
Context authContext = getActivity().createPackageContext(desc.packageName, 0);
|
||||
label = authContext.getResources().getText(desc.labelId);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
Log.w(TAG, "No label name for account type " + accountType);
|
||||
} catch (Resources.NotFoundException e) {
|
||||
Log.w(TAG, "No label resource for account type " + accountType);
|
||||
}
|
||||
}
|
||||
return label;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceTreeClick(PreferenceScreen preferences, Preference preference) {
|
||||
if (preference instanceof ProviderPreference) {
|
||||
ProviderPreference pref = (ProviderPreference) preference;
|
||||
if (Log.isLoggable(TAG, Log.VERBOSE)) {
|
||||
Log.v(TAG, "Attempting to add account of type " + pref.getAccountType());
|
||||
}
|
||||
finishWithAccountType(pref.getAccountType());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void finishWithAccountType(String accountType) {
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra(AddAccountSettings.EXTRA_SELECTED_ACCOUNT, accountType);
|
||||
getActivity().setResult(Activity.RESULT_OK, intent);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user