SetupWizard: Initial commit

This commit is contained in:
cretin45
2015-01-15 16:04:44 -08:00
commit 0328b87bf6
113 changed files with 7259 additions and 0 deletions

View File

@@ -0,0 +1,58 @@
/*
* Copyright (C) 2013 The CyanogenMod 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.cyanogenmod.setupwizard;
import android.app.Application;
import android.app.StatusBarManager;
import android.content.Context;
public class SetupWizardApp extends Application {
public static final String TAG = SetupWizardApp.class.getSimpleName();
// Leave this off for release
public static final boolean DEBUG = false;
public static final String ACCOUNT_TYPE_CYANOGEN = "com.cyanogen";
public static final String ACCOUNT_TYPE_GMS = "com.google";
public static final String ACTION_SETUP_WIFI = "com.android.net.wifi.SETUP_WIFI_NETWORK";
public static final String EXTRA_FIRST_RUN = "firstRun";
public static final String EXTRA_ALLOW_SKIP = "allowSkip";
public static final String EXTRA_AUTO_FINISH = "wifi_auto_finish_on_connect";
public static final int REQUEST_CODE_SETUP_WIFI = 0;
private StatusBarManager mStatusBarManager;
@Override
public void onCreate() {
super.onCreate();
mStatusBarManager = (StatusBarManager)getSystemService(Context.STATUS_BAR_SERVICE);
}
public void disableStatusBar() {
mStatusBarManager.disable(StatusBarManager.DISABLE_EXPAND | StatusBarManager.DISABLE_NOTIFICATION_ALERTS
| StatusBarManager.DISABLE_NOTIFICATION_TICKER | StatusBarManager.DISABLE_RECENT | StatusBarManager.DISABLE_HOME
| StatusBarManager.DISABLE_SEARCH);
}
public void enableStatusBar() {
mStatusBarManager.disable(StatusBarManager.DISABLE_NONE);
}
}

View File

@@ -0,0 +1,155 @@
/*
* Copyright (C) 2013 The CyanogenMod 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.cyanogenmod.setupwizard.setup;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import java.util.ArrayList;
public abstract class AbstractSetupData implements SetupDataCallbacks {
private static final String TAG = AbstractSetupData.class.getSimpleName();
protected Context mContext;
private ArrayList<SetupDataCallbacks> mListeners = new ArrayList<SetupDataCallbacks>();
private PageList mPageList;
private int mCurrentPageIndex = 0;
public AbstractSetupData(Context context) {
mContext = context;
mPageList = onNewPageList();
}
protected abstract PageList onNewPageList();
@Override
public void onPageLoaded(Page page) {
for (int i = 0; i < mListeners.size(); i++) {
mListeners.get(i).onPageLoaded(page);
}
}
@Override
public void onPageTreeChanged() {
for (int i = 0; i < mListeners.size(); i++) {
mListeners.get(i).onPageTreeChanged();
}
}
@Override
public void onFinish() {
for (int i = 0; i < mListeners.size(); i++) {
mListeners.get(i).onFinish();
}
}
@Override
public Page getPage(String key) {
return mPageList.getPage(key);
}
@Override
public Page getPage(int index) {
return mPageList.getPage(index);
}
public Page getCurrentPage() {
return mPageList.getPage(mCurrentPageIndex);
}
public boolean isFirstPage() {
return mCurrentPageIndex == 0;
}
public boolean isLastPage() {
return mCurrentPageIndex == mPageList.size() - 1;
}
@Override
public void onNextPage() {
if (getCurrentPage().doNextAction() == false) {
if (advanceToNextUncompleted()) {
for (int i = 0; i < mListeners.size(); i++) {
mListeners.get(i).onNextPage();
}
}
}
}
@Override
public void onPreviousPage() {
if (getCurrentPage().doPreviousAction() == false) {
if (advanceToPreviousUncompleted()) {
for (int i = 0; i < mListeners.size(); i++) {
mListeners.get(i).onPreviousPage();
}
}
}
}
@Override
public void onPageViewCreated(LayoutInflater inflater, Bundle savedInstanceState,
int layoutResource) {}
private boolean advanceToNextUncompleted() {
while (mCurrentPageIndex < mPageList.size()) {
mCurrentPageIndex++;
if (!getCurrentPage().isCompleted()) {
return true;
}
}
return false;
}
private boolean advanceToPreviousUncompleted() {
while (mCurrentPageIndex > 0) {
mCurrentPageIndex--;
if (!getCurrentPage().isCompleted()) {
return true;
}
}
return false;
}
public void load(Bundle savedValues) {
for (String key : savedValues.keySet()) {
Page page = mPageList.getPage(key);
if (page != null) {
page.resetData(savedValues.getBundle(key));
}
}
}
public Bundle save() {
Bundle bundle = new Bundle();
for (Page page : mPageList.values()) {
bundle.putBundle(page.getKey(), page.getData());
}
return bundle;
}
public void registerListener(SetupDataCallbacks listener) {
mListeners.add(listener);
}
public void unregisterListener(SetupDataCallbacks listener) {
mListeners.remove(listener);
}
}

View File

@@ -0,0 +1,59 @@
/*
* Copyright (C) 2013 The CyanogenMod 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.cyanogenmod.setupwizard.setup;
import com.cyanogenmod.setupwizard.util.SetupWizardUtils;
import android.content.Context;
import android.telephony.SubscriptionManager;
import java.util.ArrayList;
public class CMSetupWizardData extends AbstractSetupData {
public CMSetupWizardData(Context context) {
super(context);
}
@Override
protected PageList onNewPageList() {
ArrayList<SetupPage> pages = new ArrayList<SetupPage>();
pages.add(new WelcomePage(mContext, this));
pages.add(new WifiSetupPage(mContext, this));
if (SetupWizardUtils.isGSMPhone(mContext) && SetupWizardUtils.isSimMissing(mContext)) {
pages.add(new SimCardMissingPage(mContext, this));
}
if (SetupWizardUtils.isMultiSimDevice(mContext)
&& SubscriptionManager.getActiveSubInfoCount() > 1) {
pages.add(new ChooseDataSimPage(mContext, this));
}
if (SetupWizardUtils.hasTelephony(mContext) &&
!SetupWizardUtils.isMobileDataEnabled(mContext)) {
pages.add(new MobileDataPage(mContext, this));
}
if (SetupWizardUtils.hasGMS(mContext)) {
pages.add(new GmsAccountPage(mContext, this));
}
pages.add(new CyanogenAccountPage(mContext, this));
pages.add(new LocationSettingsPage(mContext, this));
pages.add(new DateTimePage(mContext, this));
pages.add(new FinishPage(mContext, this));
return new PageList(pages.toArray(new SetupPage[pages.size()]));
}
}

View File

@@ -0,0 +1,267 @@
/*
* Copyright (C) 2014 The CyanogenMod 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.cyanogenmod.setupwizard.setup;
import android.app.Fragment;
import android.content.Context;
import android.os.Bundle;
import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
import android.telephony.SubInfoRecord;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.TextView;
import com.cyanogenmod.setupwizard.R;
import com.cyanogenmod.setupwizard.ui.SetupPageFragment;
import java.util.List;
public class ChooseDataSimPage extends SetupPage {
public static final String TAG = "ChooseDataSimPage";
public ChooseDataSimPage(Context context, SetupDataCallbacks callbacks) {
super(context, callbacks);
}
@Override
public Fragment getFragment() {
Bundle args = new Bundle();
args.putString(SetupPage.KEY_PAGE_ARGUMENT, getKey());
ChooseDataSimFragment fragment = new ChooseDataSimFragment();
fragment.setArguments(args);
return fragment;
}
@Override
public String getKey() {
return TAG;
}
@Override
public int getTitleResId() {
return R.string.setup_choose_data_sim;
}
@Override
public int getNextButtonTitleResId() {
return R.string.skip;
}
public static class ChooseDataSimFragment extends SetupPageFragment {
private ViewGroup mPageView;
private SparseArray<TextView> mNameViews;
private SparseArray<ImageView> mSignalViews;
private SparseArray<CheckBox> mCheckBoxes;
private TelephonyManager mPhone;
private List<SubInfoRecord> mSubInfoRecords;
private SparseArray<SignalStrength> mSignalStrengths;
private SparseArray<ServiceState> mServiceStates;
private SparseArray<PhoneStateListener> mPhoneStateListeners;
private View.OnClickListener mSetDataSimClickListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
SubInfoRecord subInfoRecord = (SubInfoRecord)view.getTag();
if (subInfoRecord != null) {
SubscriptionManager.setDefaultDataSubId(subInfoRecord.subId);
setDataSubChecked(subInfoRecord);
}
}
};
@Override
protected void initializePage() {
mPageView = (ViewGroup)mRootView.findViewById(R.id.page_view);
mSubInfoRecords = SubscriptionManager.getActiveSubInfoList();
int simCount = mSubInfoRecords.size();
mNameViews = new SparseArray<TextView>(simCount);
mSignalViews = new SparseArray<ImageView>(simCount);
mCheckBoxes = new SparseArray<CheckBox>(simCount);
mServiceStates = new SparseArray<ServiceState>(simCount);
mSignalStrengths = new SparseArray<SignalStrength>(simCount);
mPhoneStateListeners = new SparseArray<PhoneStateListener>(simCount);
LayoutInflater inflater = LayoutInflater.from(getActivity());
for (int i = 0; i < simCount; i++) {
View simRow = inflater.inflate(R.layout.data_sim_row, null);
mPageView.addView(simRow);
SubInfoRecord subInfoRecord = mSubInfoRecords.get(i);
simRow.setTag(subInfoRecord);
simRow.setOnClickListener(mSetDataSimClickListener);
mNameViews.put(i, (TextView) simRow.findViewById(R.id.sim_title));
mSignalViews.put(i, (ImageView) simRow.findViewById(R.id.signal));
mCheckBoxes.put(i, (CheckBox) simRow.findViewById(R.id.enable_check));
mPhoneStateListeners.put(i, createPhoneStateListener(subInfoRecord));
mPageView.addView(inflater.inflate(R.layout.divider, null));
}
mPhone = (TelephonyManager)getActivity().getSystemService(Context.TELEPHONY_SERVICE);
for (int i = 0; i < mPhoneStateListeners.size(); i++) {
mPhone.listen(mPhoneStateListeners.get(i),
PhoneStateListener.LISTEN_SERVICE_STATE
| PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
}
updateSignalStrengths();
updateCurrentDataSub();
}
@Override
protected int getLayoutResource() {
return R.layout.choose_data_sim_page;
}
@Override
public void onResume() {
super.onResume();
updateSignalStrengths();
updateCurrentDataSub();
}
@Override
public void onDetach() {
super.onDetach();
for (int i = 0; i < mPhoneStateListeners.size(); i++) {
mPhone.listen(mPhoneStateListeners.get(i), PhoneStateListener.LISTEN_NONE);
}
}
private PhoneStateListener createPhoneStateListener(final SubInfoRecord subInfoRecord) {
return new PhoneStateListener(subInfoRecord.subId) {
@Override
public void onSignalStrengthsChanged(SignalStrength signalStrength) {
mSignalStrengths.put(subInfoRecord.slotId, signalStrength);
updateSignalStrength(subInfoRecord);
}
@Override
public void onServiceStateChanged(ServiceState state) {
mServiceStates.put(subInfoRecord.slotId, state);
updateSignalStrength(subInfoRecord);
}
};
}
private void updateSignalStrengths() {
for (int i = 0; i < mSubInfoRecords.size(); i++) {
updateSignalStrength(mSubInfoRecords.get(i));
}
}
private void setDataSubChecked(SubInfoRecord subInfoRecord) {
for (int i = 0; i < mCheckBoxes.size(); i++) {
mCheckBoxes.get(i).setChecked(subInfoRecord.slotId == i);
}
}
private void updateCurrentDataSub() {
for (int i = 0; i < mSubInfoRecords.size(); i++) {
SubInfoRecord subInfoRecord = mSubInfoRecords.get(i);
mCheckBoxes.get(i).setChecked(SubscriptionManager.getDefaultDataSubId()
== subInfoRecord.subId);
}
}
private void updateCarrierText(SubInfoRecord subInfoRecord) {
String name = mPhone.getNetworkOperatorName(subInfoRecord.subId);
ServiceState serviceState = mServiceStates.get(subInfoRecord.slotId);
if (TextUtils.isEmpty(name)) {
if (serviceState != null && serviceState.isEmergencyOnly()) {
name = getString(R.string.setup_mobile_data_emergency_only);
} else {
name = getString(R.string.setup_mobile_data_no_service);
}
}
String formattedName =
getString(R.string.data_sim_name, subInfoRecord.slotId + 1, name);
mNameViews.get(subInfoRecord.slotId).setText(formattedName);
}
private void updateSignalStrength(SubInfoRecord subInfoRecord) {
ImageView signalView = mSignalViews.get(subInfoRecord.slotId);
SignalStrength signalStrength = mSignalStrengths.get(subInfoRecord.slotId);
if (!hasService(subInfoRecord)) {
signalView.setImageResource(R.drawable.ic_signal_no_signal);
} else {
if (signalStrength != null) {
int resId;
switch (signalStrength.getLevel()) {
case 4:
resId = R.drawable.ic_signal_4;
break;
case 3:
resId = R.drawable.ic_signal_3;
break;
case 2:
resId = R.drawable.ic_signal_2;
break;
case 1:
resId = R.drawable.ic_signal_1;
break;
default:
resId = R.drawable.ic_signal_0;
break;
}
signalView.setImageResource(resId);
}
}
updateCarrierText(subInfoRecord);
}
private boolean hasService(SubInfoRecord subInfoRecord) {
boolean retVal;
ServiceState serviceState = mServiceStates.get(subInfoRecord.slotId);
if (serviceState != null) {
// Consider the device to be in service if either voice or data service is available.
// Some SIM cards are marketed as data-only and do not support voice service, and on
// these SIM cards, we want to show signal bars for data service as well as the "no
// service" or "emergency calls only" text that indicates that voice is not available.
switch(serviceState.getVoiceRegState()) {
case ServiceState.STATE_POWER_OFF:
retVal = false;
break;
case ServiceState.STATE_OUT_OF_SERVICE:
case ServiceState.STATE_EMERGENCY_ONLY:
retVal = serviceState.getDataRegState() == ServiceState.STATE_IN_SERVICE;
break;
default:
retVal = true;
}
} else {
retVal = false;
}
Log.d(TAG, "hasService: mServiceState=" + serviceState + " retVal=" + retVal);
return retVal;
}
}
}

View File

@@ -0,0 +1,83 @@
/*
* Copyright (C) 2013 The CyanogenMod 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.cyanogenmod.setupwizard.setup;
import com.cyanogenmod.setupwizard.SetupWizardApp;
import com.cyanogenmod.setupwizard.R;
import android.accounts.AccountManager;
import android.accounts.AccountManagerCallback;
import android.accounts.AccountManagerFuture;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
public class CyanogenAccountPage extends SetupPage {
public static final String TAG = "CyanogenAccountPage";
public CyanogenAccountPage(Context context, SetupDataCallbacks callbacks) {
super(context, callbacks);
}
@Override
public int getNextButtonTitleResId() {
return R.string.skip;
}
@Override
public String getKey() {
return TAG;
}
@Override
public int getTitleResId() {
return -1;
}
@Override
public void doLoadAction(Activity context, int action) {
launchCyanogenAccountSetup(context, action);
}
public void launchCyanogenAccountSetup(final Activity activity, final int action) {
Bundle bundle = new Bundle();
bundle.putBoolean(SetupWizardApp.EXTRA_FIRST_RUN, true);
AccountManager
.get(activity).addAccount(SetupWizardApp.ACCOUNT_TYPE_CYANOGEN, null, null, bundle,
activity, new AccountManagerCallback<Bundle>() {
@Override
public void run(AccountManagerFuture<Bundle> bundleAccountManagerFuture) {
if (activity == null) return; //There is a chance this activity has been torn down.
if (accountExists(activity, SetupWizardApp.ACCOUNT_TYPE_CYANOGEN)) {
setCompleted(true);
getCallbacks().onNextPage();
} else {
if (action == Page.ACTION_NEXT) {
getCallbacks().onNextPage();
} else {
getCallbacks().onPreviousPage();
}
}
}
}, null);
}
private boolean accountExists(Activity activity, String accountType) {
return AccountManager.get(activity).getAccountsByType(accountType).length > 0;
}
}

View File

@@ -0,0 +1,464 @@
/*
* Copyright (C) 2013 The CyanogenMod 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.cyanogenmod.setupwizard.setup;
import com.cyanogenmod.setupwizard.R;
import com.cyanogenmod.setupwizard.ui.SetupPageFragment;
import org.xmlpull.v1.XmlPullParserException;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.DatePickerDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.app.Fragment;
import android.app.TimePickerDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.XmlResourceParser;
import android.os.Bundle;
import android.os.Handler;
import android.text.format.DateFormat;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.DatePicker;
import android.widget.SimpleAdapter;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.TimePicker;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
public class DateTimePage extends SetupPage {
public static final String TAG = "DateTimePage";
private static final String KEY_ID = "id"; // value: String
private static final String KEY_DISPLAYNAME = "name"; // value: String
private static final String KEY_GMT = "gmt"; // value: String
private static final String KEY_OFFSET = "offset"; // value: int (Integer)
private static final String XMLTAG_TIMEZONE = "timezone";
private static final int HOURS_1 = 60 * 60000;
public DateTimePage(Context context, SetupDataCallbacks callbacks) {
super(context, callbacks);
}
@Override
public Fragment getFragment() {
Bundle args = new Bundle();
args.putString(SetupPage.KEY_PAGE_ARGUMENT, getKey());
DateTimeFragment fragment = new DateTimeFragment();
fragment.setArguments(args);
return fragment;
}
@Override
public String getKey() {
return TAG;
}
@Override
public int getTitleResId() {
return R.string.setup_datetime;
}
public static class DateTimeFragment extends SetupPageFragment
implements TimePickerDialog.OnTimeSetListener, DatePickerDialog.OnDateSetListener {
private TimeZone mCurrentTimeZone;
private View mDateView;
private View mTimeView;
private TextView mDateTextView;
private TextView mTimeTextView;
private final Handler mHandler = new Handler();
@Override
public void onResume() {
super.onResume();
// Register for time ticks and other reasons for time change
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_TIME_TICK);
filter.addAction(Intent.ACTION_TIME_CHANGED);
filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
getActivity().registerReceiver(mIntentReceiver, filter, null, null);
updateTimeAndDateDisplay(getActivity());
}
@Override
public void onPause() {
super.onPause();
getActivity().unregisterReceiver(mIntentReceiver);
}
@Override
protected void initializePage() {
final Spinner spinner = (Spinner) mRootView.findViewById(R.id.timezone_list);
final SimpleAdapter adapter = constructTimezoneAdapter(getActivity(), false);
mCurrentTimeZone = TimeZone.getDefault();
mDateView = mRootView.findViewById(R.id.date_item);
mDateView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
showDatePicker();
}
});
mTimeView = mRootView.findViewById(R.id.time_item);
mTimeView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
showTimePicker();
}
});
mDateTextView = (TextView)mRootView.findViewById(R.id.date_text);
mTimeTextView = (TextView)mRootView.findViewById(R.id.time_text);
// Pre-select current/default timezone
mHandler.post(new Runnable() {
@Override
public void run() {
int tzIndex = getTimeZoneIndex(adapter, mCurrentTimeZone);
spinner.setAdapter(adapter);
if (tzIndex != -1) {
spinner.setSelection(tzIndex);
}
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int position, long id) {
final Map<?, ?> map = (Map<?, ?>) adapterView.getItemAtPosition(position);
final String tzId = (String) map.get(KEY_ID);
if (mCurrentTimeZone != null && !mCurrentTimeZone.getID().equals(tzId)) {
// Update the system timezone value
final Activity activity = getActivity();
final AlarmManager alarm = (AlarmManager) activity.getSystemService(Context.ALARM_SERVICE);
alarm.setTimeZone(tzId);
mCurrentTimeZone = TimeZone.getTimeZone(tzId);
}
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
}
});
}
private void showDatePicker() {
DatePickerFragment datePickerFragment = DatePickerFragment.newInstance();
datePickerFragment.setOnDateSetListener(this);
datePickerFragment.show(getFragmentManager(), DatePickerFragment.TAG);
}
private void showTimePicker() {
TimePickerFragment timePickerFragment = TimePickerFragment.newInstance();
timePickerFragment.setOnTimeSetListener(this);
timePickerFragment.show(getFragmentManager(), TimePickerFragment.TAG);
}
public void updateTimeAndDateDisplay(Context context) {
java.text.DateFormat shortDateFormat = DateFormat.getDateFormat(context);
final Calendar now = Calendar.getInstance();
mTimeTextView.setText(DateFormat.getTimeFormat(getActivity()).format(now.getTime()));
mDateTextView.setText(shortDateFormat.format(now.getTime()));
}
@Override
protected int getLayoutResource() {
return R.layout.setup_datetime_page;
}
@Override
public void onDateSet(DatePicker view, int year, int month, int day) {
final Activity activity = getActivity();
if (activity != null) {
setDate(activity, year, month, day);
updateTimeAndDateDisplay(activity);
}
}
@Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
final Activity activity = getActivity();
if (activity != null) {
setTime(activity, hourOfDay, minute);
updateTimeAndDateDisplay(activity);
}
}
private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
final Activity activity = getActivity();
if (activity != null) {
updateTimeAndDateDisplay(activity);
}
}
};
}
private static SimpleAdapter constructTimezoneAdapter(Context context,
boolean sortedByName) {
final String[] from = new String[] {KEY_DISPLAYNAME, KEY_GMT};
final int[] to = new int[] {android.R.id.text1, android.R.id.text2};
final String sortKey = (sortedByName ? KEY_DISPLAYNAME : KEY_OFFSET);
final TimeZoneComparator comparator = new TimeZoneComparator(sortKey);
final List<HashMap<String, Object>> sortedList = getZones(context);
Collections.sort(sortedList, comparator);
final SimpleAdapter adapter = new SimpleAdapter(context,
sortedList,
R.layout.date_time_setup_custom_list_item_2,
from,
to);
return adapter;
}
private static List<HashMap<String, Object>> getZones(Context context) {
final List<HashMap<String, Object>> myData = new ArrayList<HashMap<String, Object>>();
final long date = Calendar.getInstance().getTimeInMillis();
try {
XmlResourceParser xrp = context.getResources().getXml(R.xml.timezones);
while (xrp.next() != XmlResourceParser.START_TAG)
continue;
xrp.next();
while (xrp.getEventType() != XmlResourceParser.END_TAG) {
while (xrp.getEventType() != XmlResourceParser.START_TAG) {
if (xrp.getEventType() == XmlResourceParser.END_DOCUMENT) {
return myData;
}
xrp.next();
}
if (xrp.getName().equals(XMLTAG_TIMEZONE)) {
String id = xrp.getAttributeValue(0);
String displayName = xrp.nextText();
addItem(myData, id, displayName, date);
}
while (xrp.getEventType() != XmlResourceParser.END_TAG) {
xrp.next();
}
xrp.next();
}
xrp.close();
} catch (XmlPullParserException xppe) {
Log.e(TAG, "Ill-formatted timezones.xml file");
} catch (java.io.IOException ioe) {
Log.e(TAG, "Unable to read timezones.xml file");
}
return myData;
}
private static void addItem(
List<HashMap<String, Object>> myData, String id, String displayName, long date) {
final HashMap<String, Object> map = new HashMap<String, Object>();
map.put(KEY_ID, id);
map.put(KEY_DISPLAYNAME, displayName);
final TimeZone tz = TimeZone.getTimeZone(id);
final int offset = tz.getOffset(date);
final int p = Math.abs(offset);
final StringBuilder name = new StringBuilder();
name.append("GMT");
if (offset < 0) {
name.append('-');
} else {
name.append('+');
}
name.append(p / (HOURS_1));
name.append(':');
int min = p / 60000;
min %= 60;
if (min < 10) {
name.append('0');
}
name.append(min);
map.put(KEY_GMT, name.toString());
map.put(KEY_OFFSET, offset);
myData.add(map);
}
private static int getTimeZoneIndex(SimpleAdapter adapter, TimeZone tz) {
final String defaultId = tz.getID();
final int listSize = adapter.getCount();
for (int i = 0; i < listSize; i++) {
// Using HashMap<String, Object> induces unnecessary warning.
final HashMap<?,?> map = (HashMap<?,?>)adapter.getItem(i);
final String id = (String)map.get(KEY_ID);
if (defaultId.equals(id)) {
// If current timezone is in this list, move focus to it
return i;
}
}
return -1;
}
private static void setDate(Context context, int year, int month, int day) {
Calendar c = Calendar.getInstance();
c.set(Calendar.YEAR, year);
c.set(Calendar.MONTH, month);
c.set(Calendar.DAY_OF_MONTH, day);
long when = c.getTimeInMillis();
if (when / 1000 < Integer.MAX_VALUE) {
((AlarmManager) context.getSystemService(Context.ALARM_SERVICE)).setTime(when);
}
}
private static void setTime(Context context, int hourOfDay, int minute) {
Calendar c = Calendar.getInstance();
c.set(Calendar.HOUR_OF_DAY, hourOfDay);
c.set(Calendar.MINUTE, minute);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
long when = c.getTimeInMillis();
if (when / 1000 < Integer.MAX_VALUE) {
((AlarmManager) context.getSystemService(Context.ALARM_SERVICE)).setTime(when);
}
}
private static class TimeZoneComparator implements Comparator<HashMap<?, ?>> {
private String mSortingKey;
public TimeZoneComparator(String sortingKey) {
mSortingKey = sortingKey;
}
public void setSortingKey(String sortingKey) {
mSortingKey = sortingKey;
}
public int compare(HashMap<?, ?> map1, HashMap<?, ?> map2) {
Object value1 = map1.get(mSortingKey);
Object value2 = map2.get(mSortingKey);
/*
* This should never happen, but just in-case, put non-comparable
* items at the end.
*/
if (!isComparable(value1)) {
return isComparable(value2) ? 1 : 0;
} else if (!isComparable(value2)) {
return -1;
}
return ((Comparable) value1).compareTo(value2);
}
private boolean isComparable(Object value) {
return (value != null) && (value instanceof Comparable);
}
}
private static class TimePickerFragment extends DialogFragment implements TimePickerDialog.OnTimeSetListener {
private static String TAG = TimePickerFragment.class.getSimpleName();
private TimePickerDialog.OnTimeSetListener mOnTimeSetListener;
public static TimePickerFragment newInstance() {
TimePickerFragment frag = new TimePickerFragment();
return frag;
}
private void setOnTimeSetListener(TimePickerDialog.OnTimeSetListener onTimeSetListener) {
mOnTimeSetListener = onTimeSetListener;
}
@Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
if (mOnTimeSetListener != null) {
mOnTimeSetListener.onTimeSet(view, hourOfDay, minute);
}
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final Calendar calendar = Calendar.getInstance();
return new TimePickerDialog(
getActivity(),
this,
calendar.get(Calendar.HOUR_OF_DAY),
calendar.get(Calendar.MINUTE),
DateFormat.is24HourFormat(getActivity()));
}
}
private static class DatePickerFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener {
private static String TAG = DatePickerFragment.class.getSimpleName();
private DatePickerDialog.OnDateSetListener mOnDateSetListener;
public static DatePickerFragment newInstance() {
DatePickerFragment frag = new DatePickerFragment();
return frag;
}
private void setOnDateSetListener(DatePickerDialog.OnDateSetListener onDateSetListener) {
mOnDateSetListener = onDateSetListener;
}
@Override
public void onDateSet(DatePicker view, int year, int month, int day) {
if (mOnDateSetListener != null) {
mOnDateSetListener.onDateSet(view, year, month, day);
}
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final Calendar calendar = Calendar.getInstance();
return new DatePickerDialog(
getActivity(),
this,
calendar.get(Calendar.YEAR),
calendar.get(Calendar.MONTH),
calendar.get(Calendar.DAY_OF_MONTH));
}
}
}

View File

@@ -0,0 +1,86 @@
/*
* Copyright (C) 2013 The CyanogenMod 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.cyanogenmod.setupwizard.setup;
import com.cyanogenmod.setupwizard.R;
import com.cyanogenmod.setupwizard.ui.SetupPageFragment;
import android.app.Fragment;
import android.content.Context;
import android.os.Bundle;
public class FinishPage extends SetupPage {
public static final String TAG = "FinishPage";
public FinishPage(Context context, SetupDataCallbacks callbacks) {
super(context, callbacks);
}
@Override
public Fragment getFragment() {
Bundle args = new Bundle();
args.putString(SetupPage.KEY_PAGE_ARGUMENT, getKey());
FinishFragment fragment = new FinishFragment();
fragment.setArguments(args);
return fragment;
}
@Override
public String getKey() {
return TAG;
}
@Override
public int getTitleResId() {
return R.string.setup_complete;
}
@Override
public boolean doNextAction() {
getCallbacks().onFinish();
return true;
}
@Override
public int getNextButtonTitleResId() {
return R.string.start;
}
@Override
public int getPrevButtonTitleResId() {
return -1;
}
public static class FinishFragment extends SetupPageFragment {
@Override
protected void initializePage() {}
@Override
protected int getLayoutResource() {
return R.layout.setup_finished_page;
}
@Override
protected int getHeaderLayoutResource() {
return -1;
}
}
}

View File

@@ -0,0 +1,90 @@
/*
* Copyright (C) 2013 The CyanogenMod 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.cyanogenmod.setupwizard.setup;
import android.accounts.AccountManager;
import android.accounts.AccountManagerCallback;
import android.accounts.AccountManagerFuture;
import android.accounts.AuthenticatorException;
import android.accounts.OperationCanceledException;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import com.cyanogenmod.setupwizard.R;
import com.cyanogenmod.setupwizard.SetupWizardApp;
import java.io.IOException;
public class GmsAccountPage extends SetupPage {
public static final String TAG = "GmsAccountPage";
public GmsAccountPage(Context context, SetupDataCallbacks callbacks) {
super(context, callbacks);
}
@Override
public String getKey() {
return TAG;
}
@Override
public int getTitleResId() {
return R.string.setup_gms_account;
}
@Override
public int getNextButtonTitleResId() {
return R.string.skip;
}
@Override
public void doLoadAction(Activity context, int action) {
launchGmsAccountSetup(context, action);
}
public void launchGmsAccountSetup(final Activity activity, final int action) {
Bundle bundle = new Bundle();
bundle.putBoolean(SetupWizardApp.EXTRA_FIRST_RUN, true);
bundle.putBoolean(SetupWizardApp.EXTRA_ALLOW_SKIP, true);
AccountManager
.get(activity).addAccount(SetupWizardApp.ACCOUNT_TYPE_GMS, null, null,
bundle, activity, new AccountManagerCallback<Bundle>() {
@Override
public void run(AccountManagerFuture<Bundle> bundleAccountManagerFuture) {
//There is a chance this activity has been torn down.
if (activity == null) return;
String token = null;
try {
token = bundleAccountManagerFuture.getResult().getString(AccountManager.KEY_AUTHTOKEN);
} catch (OperationCanceledException e) {
} catch (IOException e) {
} catch (AuthenticatorException e) {
}
if (token != null) {
setCompleted(true);
}
if (action == Page.ACTION_NEXT) {
getCallbacks().onNextPage();
} else {
getCallbacks().onPreviousPage();
}
}
}, null);
}
}

View File

@@ -0,0 +1,194 @@
/*
* Copyright (C) 2013 The CyanogenMod 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.cyanogenmod.setupwizard.setup;
import android.app.Fragment;
import android.content.ContentQueryMap;
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.location.LocationManager;
import android.os.Bundle;
import android.provider.Settings;
import android.view.View;
import android.widget.CheckBox;
import com.cyanogenmod.setupwizard.R;
import com.cyanogenmod.setupwizard.ui.SetupPageFragment;
import java.util.Observable;
import java.util.Observer;
public class LocationSettingsPage extends SetupPage {
private static final String TAG = "LocationSettingsPage";
public LocationSettingsPage(Context context, SetupDataCallbacks callbacks) {
super(context, callbacks);
}
@Override
public Fragment getFragment() {
Bundle args = new Bundle();
args.putString(Page.KEY_PAGE_ARGUMENT, getKey());
LocationSettingsFragment fragment = new LocationSettingsFragment();
fragment.setArguments(args);
return fragment;
}
@Override
public String getKey() {
return TAG;
}
@Override
public int getTitleResId() {
return R.string.setup_location;
}
public static class LocationSettingsFragment extends SetupPageFragment {
private View mLocationRow;
private View mGpsRow;
private View mNetworkRow;
private CheckBox mNetwork;
private CheckBox mGps;
private CheckBox mLocationAccess;
private ContentResolver mContentResolver;
// These provide support for receiving notification when Location Manager settings change.
// This is necessary because the Network Location Provider can change settings
// if the user does not confirm enabling the provider.
private ContentQueryMap mContentQueryMap;
private Observer mSettingsObserver;
private View.OnClickListener mLocationClickListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
onToggleLocationAccess(!mLocationAccess.isChecked());
}
};
private View.OnClickListener mGpsClickListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
Settings.Secure.setLocationProviderEnabled(mContentResolver,
LocationManager.GPS_PROVIDER, !mGps.isChecked());
}
};
private View.OnClickListener mNetworkClickListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
Settings.Secure.setLocationProviderEnabled(mContentResolver,
LocationManager.NETWORK_PROVIDER, !mNetwork.isChecked());
}
};
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mContentResolver = getActivity().getContentResolver();
getActivity().getWindow().setStatusBarColor(getResources().getColor(R.color.primary_dark));
}
@Override
protected void initializePage() {
mLocationRow = mRootView.findViewById(R.id.location);
mLocationRow.setOnClickListener(mLocationClickListener);
mLocationAccess = (CheckBox) mRootView.findViewById(R.id.location_checkbox);
mGpsRow = mRootView.findViewById(R.id.gps);
mGpsRow.setOnClickListener(mGpsClickListener);
mGps = (CheckBox) mRootView.findViewById(R.id.gps_checkbox);
mNetworkRow = mRootView.findViewById(R.id.network);
mNetworkRow.setOnClickListener(mNetworkClickListener);
mNetwork = (CheckBox) mRootView.findViewById(R.id.network_checkbox);
}
@Override
protected int getLayoutResource() {
return R.layout.location_settings;
}
@Override
protected int getHeaderLayoutResource() {
return R.layout.header_condensed;
}
@Override
public void onResume() {
super.onResume();
updateLocationToggles();
if (mSettingsObserver == null) {
mSettingsObserver = new Observer() {
public void update(Observable o, Object arg) {
updateLocationToggles();
}
};
}
mContentQueryMap.addObserver(mSettingsObserver);
}
@Override
public void onStart() {
super.onStart();
// listen for Location Manager settings changes
Cursor settingsCursor = getActivity().getContentResolver().query(Settings.Secure.CONTENT_URI, null,
"(" + Settings.System.NAME + "=?)",
new String[]{Settings.Secure.LOCATION_PROVIDERS_ALLOWED},
null);
mContentQueryMap = new ContentQueryMap(settingsCursor, Settings.System.NAME, true, null);
}
@Override
public void onStop() {
super.onStop();
if (mSettingsObserver != null) {
mContentQueryMap.deleteObserver(mSettingsObserver);
}
mContentQueryMap.close();
}
private void updateLocationToggles() {
boolean gpsEnabled = Settings.Secure.isLocationProviderEnabled(
mContentResolver, LocationManager.GPS_PROVIDER);
boolean networkEnabled = Settings.Secure.isLocationProviderEnabled(
mContentResolver, LocationManager.NETWORK_PROVIDER);
mGps.setChecked(gpsEnabled);
mNetwork.setChecked(networkEnabled);
mLocationAccess.setChecked(gpsEnabled || networkEnabled);
}
private void onToggleLocationAccess(boolean checked) {
Settings.Secure.setLocationProviderEnabled(mContentResolver,
LocationManager.GPS_PROVIDER, checked);
mGps.setEnabled(checked);
mGpsRow.setEnabled(checked);
Settings.Secure.setLocationProviderEnabled(mContentResolver,
LocationManager.NETWORK_PROVIDER, checked);
mNetwork.setEnabled(checked);
mNetworkRow.setEnabled(checked);
updateLocationToggles();
}
}
}

View File

@@ -0,0 +1,211 @@
/*
* Copyright (C) 2013 The CyanogenMod 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.cyanogenmod.setupwizard.setup;
import android.app.Activity;
import android.app.Fragment;
import android.content.Context;
import android.os.Bundle;
import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.view.View;
import android.widget.ImageView;
import android.widget.Switch;
import android.widget.TextView;
import com.cyanogenmod.setupwizard.R;
import com.cyanogenmod.setupwizard.ui.SetupPageFragment;
import com.cyanogenmod.setupwizard.util.SetupWizardUtils;
public class MobileDataPage extends SetupPage {
public static final String TAG = "MobileDataPage";
public MobileDataPage(Context context, SetupDataCallbacks callbacks) {
super(context, callbacks);
}
@Override
public Fragment getFragment() {
Bundle args = new Bundle();
args.putString(SetupPage.KEY_PAGE_ARGUMENT, getKey());
MobileDataFragment fragment = new MobileDataFragment();
fragment.setArguments(args);
return fragment;
}
@Override
public String getKey() {
return TAG;
}
@Override
public int getTitleResId() {
return R.string.setup_mobile_data;
}
public static class MobileDataFragment extends SetupPageFragment {
private View mEnableDataRow;
private Switch mEnableMobileData;
private ImageView mSignalView;
private TextView mNameView;
private TelephonyManager mPhone;
private SignalStrength mSignalStrength;
private ServiceState mServiceState;
private PhoneStateListener mPhoneStateListener =
new PhoneStateListener(SubscriptionManager.getDefaultDataSubId()) {
@Override
public void onSignalStrengthsChanged(SignalStrength signalStrength) {
mSignalStrength = signalStrength;
updateSignalStrength();
}
@Override
public void onServiceStateChanged(ServiceState state) {
mServiceState = state;
updateSignalStrength();
}
};
private View.OnClickListener mEnableDataClickListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
boolean checked = !mEnableMobileData.isChecked();
SetupWizardUtils.setMobileDataEnabled(getActivity(), checked);
mEnableMobileData.setChecked(checked);
}
};
@Override
protected void initializePage() {
mEnableDataRow = mRootView.findViewById(R.id.data);
mEnableDataRow.setOnClickListener(mEnableDataClickListener);
mEnableMobileData = (Switch) mRootView.findViewById(R.id.data_switch);
mSignalView = (ImageView) mRootView.findViewById(R.id.signal);
mNameView = (TextView) mRootView.findViewById(R.id.enable_data_title);
updateDataConnectionStatus();
updateSignalStrength();
}
@Override
protected int getLayoutResource() {
return R.layout.mobile_data_settings;
}
@Override
public void onResume() {
super.onResume();
updateDataConnectionStatus();
updateSignalStrength();
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mPhone = (TelephonyManager)getActivity().getSystemService(Context.TELEPHONY_SERVICE);
mPhone.listen(mPhoneStateListener,
PhoneStateListener.LISTEN_SERVICE_STATE
| PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
}
@Override
public void onDetach() {
super.onDetach();
mPhone.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
}
private void updateCarrierText() {
String name = mPhone.getNetworkOperatorName(SubscriptionManager.getDefaultDataSubId());
if (TextUtils.isEmpty(name)) {
if (mServiceState != null && mServiceState.isEmergencyOnly()) {
name = getString(R.string.setup_mobile_data_emergency_only);
} else {
name = getString(R.string.setup_mobile_data_no_service);
}
}
mNameView.setText(name);
}
private void updateSignalStrength() {
if (!hasService()) {
mSignalView.setImageResource(R.drawable.ic_signal_no_signal);
} else {
if (mSignalStrength != null) {
int resId;
switch (mSignalStrength.getLevel()) {
case 4:
resId = R.drawable.ic_signal_4;
break;
case 3:
resId = R.drawable.ic_signal_3;
break;
case 2:
resId = R.drawable.ic_signal_2;
break;
case 1:
resId = R.drawable.ic_signal_1;
break;
default:
resId = R.drawable.ic_signal_0;
break;
}
mSignalView.setImageResource(resId);
}
}
updateCarrierText();
}
private void updateDataConnectionStatus() {
mEnableMobileData.setChecked(SetupWizardUtils.isMobileDataEnabled(getActivity()));
}
private boolean hasService() {
boolean retVal;
if (mServiceState != null) {
// Consider the device to be in service if either voice or data service is available.
// Some SIM cards are marketed as data-only and do not support voice service, and on
// these SIM cards, we want to show signal bars for data service as well as the "no
// service" or "emergency calls only" text that indicates that voice is not available.
switch(mServiceState.getVoiceRegState()) {
case ServiceState.STATE_POWER_OFF:
retVal = false;
break;
case ServiceState.STATE_OUT_OF_SERVICE:
case ServiceState.STATE_EMERGENCY_ONLY:
retVal = mServiceState.getDataRegState() == ServiceState.STATE_IN_SERVICE;
break;
default:
retVal = true;
}
} else {
retVal = false;
}
return retVal;
}
}
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright (C) 2013 The CyanogenMod 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.cyanogenmod.setupwizard.setup;
import android.app.Activity;
import android.app.Fragment;
import android.content.Intent;
import android.os.Bundle;
public interface Page {
public static final String KEY_PAGE_ARGUMENT = "key_arg";
public static final int ACTION_NEXT = 1;
public static final int ACTION_PREVIOUS = 2;
public String getKey();
public int getTitleResId();
public int getPrevButtonTitleResId();
public int getNextButtonTitleResId();
public Fragment getFragment();
public Bundle getData();
public void resetData(Bundle data);
public boolean isRequired();
public Page setRequired(boolean required);
public boolean isCompleted();
public void setCompleted(boolean completed);
public boolean doPreviousAction();
public boolean doNextAction();
public void doLoadAction(Activity context, int action);
public abstract boolean onActivityResult(int requestCode, int resultCode, Intent data);
}

View File

@@ -0,0 +1,44 @@
/*
* Copyright (C) 2013 The CyanogenMod 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.cyanogenmod.setupwizard.setup;
import java.util.LinkedHashMap;
public class PageList extends LinkedHashMap<String, Page> {
public PageList(Page... pages) {
for (Page page : pages) {
put(page.getKey(), page);
}
}
public Page getPage(String key) {
return get(key);
}
public Page getPage(int index) {
int i=0;
for (Page page : values()) {
if (i == index) {
return page;
}
i++;
}
return null;
}
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright (C) 2013 The CyanogenMod 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.cyanogenmod.setupwizard.setup;
import android.os.Bundle;
import android.view.LayoutInflater;
public interface SetupDataCallbacks {
void onNextPage();
void onPreviousPage();
void onPageLoaded(Page page);
void onPageTreeChanged();
void onFinish();
Page getPage(String key);
Page getPage(int key);
void onPageViewCreated(LayoutInflater inflater, Bundle savedInstanceState, int layoutResource);
}

View File

@@ -0,0 +1,126 @@
/*
* Copyright (C) 2013 The CyanogenMod 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.cyanogenmod.setupwizard.setup;
import com.cyanogenmod.setupwizard.R;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
public abstract class SetupPage implements Page {
private final SetupDataCallbacks mCallbacks;
private Bundle mData = new Bundle();
private boolean mRequired = false;
private boolean mCompleted = false;
protected final Context mContext;
protected SetupPage(Context context, SetupDataCallbacks callbacks) {
mContext = context;
mCallbacks = callbacks;
}
@Override
public Fragment getFragment() {
return null;
}
@Override
public int getPrevButtonTitleResId() {
return -1;
}
@Override
public int getNextButtonTitleResId() {
return R.string.next;
}
@Override
public boolean doNextAction() {
return false;
}
@Override
public boolean doPreviousAction() {
return false;
}
@Override
public void doLoadAction(Activity context, int action) {
if (context == null || context.isFinishing()) { return; }
final FragmentManager fragmentManager = context.getFragmentManager();
if (action == Page.ACTION_NEXT) {
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.content, getFragment(), getKey());
transaction.commit();
} else {
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.content, getFragment(), getKey());
transaction.commit();
}
}
@Override
public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
return false;
}
@Override
public boolean isRequired() {
return mRequired;
}
@Override
public Page setRequired(boolean required) {
mRequired = required;
return this;
}
@Override
public boolean isCompleted() {
return mCompleted;
}
@Override
public void setCompleted(boolean completed) {
mCompleted = completed;
mCallbacks.onNextPage();
}
@Override
public Bundle getData() {
return mData;
}
@Override
public void resetData(Bundle data) {
mData = data;
mCallbacks.onPageLoaded(this);
}
protected SetupDataCallbacks getCallbacks() {
return mCallbacks;
}
}

View File

@@ -0,0 +1,72 @@
/*
* Copyright (C) 2014 The CyanogenMod 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.cyanogenmod.setupwizard.setup;
import android.app.Fragment;
import android.content.Context;
import android.os.Bundle;
import com.cyanogenmod.setupwizard.R;
import com.cyanogenmod.setupwizard.ui.SetupPageFragment;
public class SimCardMissingPage extends SetupPage {
public static final String TAG = "SimCardMissingPage";
public SimCardMissingPage(Context context, SetupDataCallbacks callbacks) {
super(context, callbacks);
}
@Override
public Fragment getFragment() {
Bundle args = new Bundle();
args.putString(SetupPage.KEY_PAGE_ARGUMENT, getKey());
FinishFragment fragment = new FinishFragment();
fragment.setArguments(args);
return fragment;
}
@Override
public String getKey() {
return TAG;
}
@Override
public int getTitleResId() {
return R.string.setup_sim_missing;
}
@Override
public int getNextButtonTitleResId() {
return R.string.skip;
}
public static class FinishFragment extends SetupPageFragment {
@Override
protected void initializePage() {}
@Override
protected int getLayoutResource() {
return R.layout.sim_missing_page;
}
}
}

View File

@@ -0,0 +1,148 @@
/*
* Copyright (C) 2013 The CyanogenMod 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.cyanogenmod.setupwizard.setup;
import android.app.Fragment;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Bundle;
import android.os.Handler;
import android.widget.ArrayAdapter;
import android.widget.NumberPicker;
import com.cyanogenmod.setupwizard.R;
import com.cyanogenmod.setupwizard.ui.LocalePicker;
import com.cyanogenmod.setupwizard.ui.SetupPageFragment;
import java.util.Locale;
public class WelcomePage extends SetupPage {
public static final String TAG = "WelcomePage";
public WelcomePage(Context context, SetupDataCallbacks callbacks) {
super(context, callbacks);
}
@Override
public Fragment getFragment() {
Bundle args = new Bundle();
args.putString(SetupPage.KEY_PAGE_ARGUMENT, getKey());
WelcomeFragment fragment = new WelcomeFragment();
fragment.setArguments(args);
return fragment;
}
@Override
public int getTitleResId() {
return R.string.setup_welcome;
}
@Override
public String getKey() {
return TAG;
}
@Override
public int getPrevButtonTitleResId() {
return R.string.emergency_call;
}
public static class WelcomeFragment extends SetupPageFragment {
private ArrayAdapter<com.android.internal.app.LocalePicker.LocaleInfo> mLocaleAdapter;
private Locale mInitialLocale;
private Locale mCurrentLocale;
private int[] mAdapterIndices;
private LocalePicker mLanguagePicker;
private final Handler mHandler = new Handler();
private final Runnable mUpdateLocale = new Runnable() {
public void run() {
if (mCurrentLocale != null) {
com.android.internal.app.LocalePicker.updateLocale(mCurrentLocale);
}
}
};
@Override
protected void initializePage() {
mLanguagePicker = (LocalePicker) mRootView.findViewById(R.id.locale_list);
loadLanguages();
}
private void loadLanguages() {
mLocaleAdapter = com.android.internal.app.LocalePicker.constructAdapter(getActivity(), R.layout.locale_picker_item, R.id.locale);
mInitialLocale = Locale.getDefault();
mCurrentLocale = mInitialLocale;
mAdapterIndices = new int[mLocaleAdapter.getCount()];
int currentLocaleIndex = 0;
String [] labels = new String[mLocaleAdapter.getCount()];
for (int i=0; i<mAdapterIndices.length; i++) {
com.android.internal.app.LocalePicker.LocaleInfo localLocaleInfo = mLocaleAdapter.getItem(i);
Locale localLocale = localLocaleInfo.getLocale();
if (localLocale.equals(mCurrentLocale)) {
currentLocaleIndex = i;
}
mAdapterIndices[i] = i;
labels[i] = localLocaleInfo.getLabel();
}
mLanguagePicker.setDisplayedValues(labels);
mLanguagePicker.setMaxValue(labels.length - 1);
mLanguagePicker.setValue(currentLocaleIndex);
mLanguagePicker.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);
mLanguagePicker.setOnValueChangedListener(new LocalePicker.OnValueChangeListener() {
public void onValueChange(LocalePicker picker, int oldVal, int newVal) {
setLocaleFromPicker();
}
});
}
private void setLocaleFromPicker() {
int i = mAdapterIndices[mLanguagePicker.getValue()];
final com.android.internal.app.LocalePicker.LocaleInfo localLocaleInfo = mLocaleAdapter.getItem(i);
onLocaleChanged(localLocaleInfo.getLocale());
}
private void onLocaleChanged(Locale paramLocale) {
Resources localResources = getActivity().getResources();
Configuration localConfiguration1 = localResources.getConfiguration();
Configuration localConfiguration2 = new Configuration();
localConfiguration2.locale = paramLocale;
localResources.updateConfiguration(localConfiguration2, null);
localResources.updateConfiguration(localConfiguration1, null);
mHandler.removeCallbacks(mUpdateLocale);
mCurrentLocale = paramLocale;
mHandler.postDelayed(mUpdateLocale, 1000);
}
@Override
protected int getLayoutResource() {
return R.layout.setup_welcome_page;
}
@Override
protected int getHeaderLayoutResource() {
return R.layout.logo_header;
}
}
}

View File

@@ -0,0 +1,65 @@
/*
* Copyright (C) 2013 The CyanogenMod 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.cyanogenmod.setupwizard.setup;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import com.cyanogenmod.setupwizard.R;
import com.cyanogenmod.setupwizard.SetupWizardApp;
import com.cyanogenmod.setupwizard.util.SetupWizardUtils;
public class WifiSetupPage extends SetupPage {
public static final String TAG = "WifiSetupPage";
public WifiSetupPage(Context context, SetupDataCallbacks callbacks) {
super(context, callbacks);
}
@Override
public int getNextButtonTitleResId() {
return R.string.skip;
}
@Override
public String getKey() {
return TAG;
}
@Override
public int getTitleResId() {
return R.string.existing;
}
@Override
public void doLoadAction(Activity context, int action) {
if (action == Page.ACTION_PREVIOUS) {
getCallbacks().onPreviousPage();
} else {
SetupWizardUtils.launchWifiSetup(context);
}
}
@Override
public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode != SetupWizardApp.REQUEST_CODE_SETUP_WIFI) return false;
getCallbacks().onNextPage();
return true;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,86 @@
/*
* Copyright (C) 2013 The CyanogenMod 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.cyanogenmod.setupwizard.ui;
import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.cyanogenmod.setupwizard.R;
import com.cyanogenmod.setupwizard.setup.Page;
import com.cyanogenmod.setupwizard.setup.SetupDataCallbacks;
public abstract class SetupPageFragment extends Fragment {
protected SetupDataCallbacks mCallbacks;
protected String mKey;
protected Page mPage;
protected View mRootView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle args = getArguments();
mKey = args.getString(Page.KEY_PAGE_ARGUMENT);
if (mKey == null) {
throw new IllegalArgumentException("No KEY_PAGE_ARGUMENT given");
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mRootView = inflater.inflate(getLayoutResource(), container, false);
mCallbacks.onPageViewCreated(inflater, savedInstanceState, getHeaderLayoutResource());
return mRootView;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mPage = mCallbacks.getPage(mKey);
initializePage();
mCallbacks.onPageLoaded(mPage);
getActivity().getWindow().setStatusBarColor(getResources().getColor(R.color.primary));
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (!(activity instanceof SetupDataCallbacks)) {
throw new ClassCastException("Activity implement SetupDataCallbacks");
}
mCallbacks = (SetupDataCallbacks) activity;
}
@Override
public void onDetach() {
super.onDetach();
mCallbacks = null;
}
protected int getHeaderLayoutResource() {
return R.layout.header;
}
protected abstract void initializePage();
protected abstract int getLayoutResource();
}

View File

@@ -0,0 +1,219 @@
/*
* Copyright (C) 2013 The CyanogenMod 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.cyanogenmod.setupwizard.ui;
import android.app.Activity;
import android.app.AppGlobals;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Bundle;
import android.provider.Settings;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import com.cyanogenmod.setupwizard.R;
import com.cyanogenmod.setupwizard.SetupWizardApp;
import com.cyanogenmod.setupwizard.setup.AbstractSetupData;
import com.cyanogenmod.setupwizard.setup.CMSetupWizardData;
import com.cyanogenmod.setupwizard.setup.Page;
import com.cyanogenmod.setupwizard.setup.SetupDataCallbacks;
import com.cyanogenmod.setupwizard.util.SetupWizardUtils;
public class SetupWizardActivity extends Activity implements SetupDataCallbacks {
private static final String TAG = SetupWizardActivity.class.getSimpleName();
private View mRootView;
private View mPageView;
private Button mNextButton;
private Button mPrevButton;
private TextView mTitleView;
private ViewGroup mHeaderView;
private AbstractSetupData mSetupData;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.setup_main);
mRootView = findViewById(R.id.root);
mPageView = findViewById(R.id.page);
((SetupWizardApp)getApplicationContext()).disableStatusBar();
mSetupData = (AbstractSetupData)getLastNonConfigurationInstance();
if (mSetupData == null) {
mSetupData = new CMSetupWizardData(this);
}
mHeaderView = (ViewGroup)findViewById(R.id.header);
mNextButton = (Button) findViewById(R.id.next_button);
mPrevButton = (Button) findViewById(R.id.prev_button);
mSetupData.registerListener(this);
mNextButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mSetupData.onNextPage();
}
});
mPrevButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mSetupData.onPreviousPage();
}
});
if (savedInstanceState == null) {
Page page = mSetupData.getCurrentPage();
page.doLoadAction(this, Page.ACTION_NEXT);
}
if (savedInstanceState != null && savedInstanceState.containsKey("data")) {
mSetupData.load(savedInstanceState.getBundle("data"));
}
}
@Override
protected void onResume() {
super.onResume();
onPageTreeChanged();
}
@Override
protected void onDestroy() {
super.onDestroy();
mSetupData.unregisterListener(this);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
mSetupData.getCurrentPage().onActivityResult(requestCode, resultCode, data);
}
@Override
public Object onRetainNonConfigurationInstance() {
return mSetupData;
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBundle("data", mSetupData.save());
}
@Override
public void onBackPressed() {
mSetupData.onPreviousPage();
}
@Override
public void onPageViewCreated(LayoutInflater inflater, Bundle savedInstanceState,
int layoutResource) {
if (layoutResource != -1) {
mHeaderView.setVisibility(View.VISIBLE);
mHeaderView.removeAllViews();
inflater.inflate(layoutResource, mHeaderView, true);
} else {
mHeaderView.setVisibility(View.GONE);
}
mTitleView = (TextView) findViewById(android.R.id.title);
if (mTitleView != null) {
Page page = mSetupData.getCurrentPage();
mTitleView.setText(page.getTitleResId());
}
}
@Override
public void onNextPage() {
Page page = mSetupData.getCurrentPage();
page.doLoadAction(this, Page.ACTION_NEXT);
}
@Override
public void onPreviousPage() {
Page page = mSetupData.getCurrentPage();
page.doLoadAction(this, Page.ACTION_PREVIOUS);
}
@Override
public void onPageLoaded(Page page) {
updateButtonBar();
}
@Override
public void onPageTreeChanged() {
updateButtonBar();
}
private void updateButtonBar() {
Page page = mSetupData.getCurrentPage();
mNextButton.setText(page.getNextButtonTitleResId());
if (page.getPrevButtonTitleResId() != -1) {
mPrevButton.setText(page.getPrevButtonTitleResId());
} else {
mPrevButton.setText("");
}
if (mSetupData.isFirstPage()) {
mPrevButton.setCompoundDrawables(null, null, null, null);
} else {
mPrevButton.setCompoundDrawablesWithIntrinsicBounds(
getDrawable(R.drawable.ic_chevron_left_dark),
null, null, null);
}
final Resources resources = getResources();
if (mSetupData.isLastPage()) {
mPrevButton.setVisibility(View.INVISIBLE);
mRootView.setBackgroundColor(resources.getColor(R.color.primary));
mPageView.setBackgroundColor(resources.getColor(R.color.primary));
mNextButton.setCompoundDrawablesWithIntrinsicBounds(null, null,
getDrawable(R.drawable.ic_chevron_right_wht), null);
mNextButton.setTextColor(resources.getColor(R.color.white));
} else {
mPrevButton.setVisibility(View.VISIBLE);
mPageView.setBackgroundColor(resources.getColor(R.color.page_background));
if (mSetupData.isFirstPage()) {
mRootView.setBackgroundColor(resources.getColor(R.color.page_background));
} else {
mRootView.setBackgroundColor(resources.getColor(R.color.window_background));
}
mNextButton.setCompoundDrawablesWithIntrinsicBounds(null, null,
getDrawable(R.drawable.ic_chevron_right_dark), null);
mNextButton.setTextColor(resources.getColor(R.color.primary_text));
}
}
@Override
public Page getPage(String key) {
return mSetupData.getPage(key);
}
@Override
public Page getPage(int key) {
return mSetupData.getPage(key);
}
@Override
public void onFinish() {
finishSetup();
}
private void finishSetup() {
Settings.Global.putInt(getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 1);
Settings.Secure.putInt(getContentResolver(), Settings.Secure.USER_SETUP_COMPLETE, 1);
((SetupWizardApp)AppGlobals.getInitialApplication()).enableStatusBar();
SetupWizardUtils.disableSetupWizards(this);
finish();
}
}

View File

@@ -0,0 +1,161 @@
/*
* Copyright (C) 2013 The CyanogenMod 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.cyanogenmod.setupwizard.util;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiManager;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import com.cyanogenmod.setupwizard.SetupWizardApp;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import java.util.List;
public class SetupWizardUtils {
private static final String TAG = SetupWizardUtils.class.getSimpleName();
private static final String GOOGLE_SETUPWIZARD_PACKAGE = "com.google.android.setupwizard";
private SetupWizardUtils(){}
public static void tryEnablingWifi(Context context) {
WifiManager wifiManager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE);
if (!wifiManager.isWifiEnabled()) {
wifiManager.setWifiEnabled(true);
}
}
public static void launchWifiSetup(Activity context) {
SetupWizardUtils.tryEnablingWifi(context);
Intent intent = new Intent(SetupWizardApp.ACTION_SETUP_WIFI);
intent.putExtra(SetupWizardApp.EXTRA_FIRST_RUN, true);
intent.putExtra(SetupWizardApp.EXTRA_ALLOW_SKIP, true);
intent.putExtra("theme", "material_light");
intent.putExtra(SetupWizardApp.EXTRA_AUTO_FINISH, true);
context.startActivityForResult(intent, SetupWizardApp.REQUEST_CODE_SETUP_WIFI);
}
public static boolean isNetworkConnected(Context context) {
ConnectivityManager connectivityManager =
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
return networkInfo != null && networkInfo.isConnected();
}
public static boolean isWifiConnected(Context context) {
ConnectivityManager connectivityManager =
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mWifi = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
return mWifi != null && mWifi.isConnected();
}
public static boolean isMobileDataEnabled(Context context) {
TelephonyManager tm =
(TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
if (tm.isMultiSimEnabled()) {
int subscription = SubscriptionManager.getDefaultDataPhoneId();
return android.provider.Settings.Global.getInt(context.getContentResolver(),
android.provider.Settings.Global.MOBILE_DATA + subscription, 0) != 0;
} else {
return android.provider.Settings.Global.getInt(context.getContentResolver(),
android.provider.Settings.Global.MOBILE_DATA, 0) != 0;
}
}
public static void setMobileDataEnabled(Context context, boolean enabled) {
TelephonyManager tm =
(TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
tm.setDataEnabled(enabled);
if (tm.isMultiSimEnabled()) {
int subscription = SubscriptionManager.getDefaultDataPhoneId();
android.provider.Settings.Global.putInt(context.getContentResolver(),
android.provider.Settings.Global.MOBILE_DATA + subscription, enabled ? 1 : 0);
} else {
android.provider.Settings.Global.putInt(context.getContentResolver(),
android.provider.Settings.Global.MOBILE_DATA, enabled ? 1 : 0);
}
}
public static boolean hasTelephony(Context context) {
PackageManager packageManager = context.getPackageManager();
return packageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
}
public static boolean isMultiSimDevice(Context context) {
TelephonyManager tm =
(TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
return tm.isMultiSimEnabled();
}
public static boolean isGSMPhone(Context context) {
TelephonyManager tm =
(TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
int phoneType = tm.getPhoneType();
return phoneType == TelephonyManager.PHONE_TYPE_GSM;
}
public static boolean isSimMissing(Context context) {
TelephonyManager tm =
(TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
int simCount = SubscriptionManager.getActiveSubInfoCount();
for (int i = 0; i < simCount; i++) {
int simState = tm.getSimState(i);
if (simState != TelephonyManager.SIM_STATE_ABSENT &&
simState != TelephonyManager.SIM_STATE_UNKNOWN) {
return false;
}
}
return true;
}
public static boolean hasGMS(Context context) {
return GooglePlayServicesUtil.isGooglePlayServicesAvailable(context) !=
ConnectionResult.SERVICE_MISSING;
}
public static void disableSetupWizards(Activity context) {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
final PackageManager pm = context.getPackageManager();
final List<ResolveInfo> resolveInfos =
pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
for (ResolveInfo info : resolveInfos) {
if (GOOGLE_SETUPWIZARD_PACKAGE.equals(info.activityInfo.packageName)) {
final ComponentName componentName =
new ComponentName(info.activityInfo.packageName, info.activityInfo.name);
pm.setComponentEnabledSetting(componentName,
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
}
}
pm.setComponentEnabledSetting(context.getComponentName(),
PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
context.startActivity(intent);
}
}