Detect radios in data usage, control them.
Teach data usage to inspect hardware radios to determine which tabs and options to display. Control "Mobile data enabled" state through ConnectivityManager. Persist "Show Wi-Fi" state. Bug: 4599714, 4645276, 4620024, 4599271, 4596812 Change-Id: I4479593d74a8ba744a056767422f1e03182a7a94
This commit is contained in:
63
res/layout/preference.xml
Normal file
63
res/layout/preference.xml
Normal file
@@ -0,0 +1,63 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2011 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.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="48dip"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingRight="?android:attr/scrollbarSize"
|
||||
android:background="?android:attr/selectableItemBackground">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="15dip"
|
||||
android:layout_marginRight="6dip"
|
||||
android:layout_marginTop="6dip"
|
||||
android:layout_marginBottom="6dip"
|
||||
android:layout_weight="1">
|
||||
|
||||
<TextView
|
||||
android:id="@+android:id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:ellipsize="marquee"
|
||||
android:fadingEdge="horizontal" />
|
||||
|
||||
<TextView
|
||||
android:id="@android:id/summary"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@android:id/title"
|
||||
android:layout_alignLeft="@android:id/title"
|
||||
android:visibility="gone"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:maxLines="4" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@android:id/widget_frame"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="vertical" />
|
||||
|
||||
</LinearLayout>
|
@@ -20,4 +20,5 @@
|
||||
<dimen name="vpn_connect_input_box_label_width">90sp</dimen>
|
||||
<dimen name="device_memory_usage_button_width">16dip</dimen>
|
||||
<dimen name="device_memory_usage_button_height">32dip</dimen>
|
||||
<dimen name="data_usage_chart_height">220dip</dimen>
|
||||
</resources>
|
||||
|
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.settings;
|
||||
|
||||
import static android.net.ConnectivityManager.TYPE_MOBILE;
|
||||
import static android.net.ConnectivityManager.TYPE_WIMAX;
|
||||
import static android.net.NetworkPolicy.LIMIT_DISABLED;
|
||||
import static android.net.NetworkPolicyManager.ACTION_DATA_USAGE_LIMIT;
|
||||
import static android.net.NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE;
|
||||
@@ -26,6 +28,7 @@ import static android.net.NetworkTemplate.MATCH_MOBILE_4G;
|
||||
import static android.net.NetworkTemplate.MATCH_MOBILE_ALL;
|
||||
import static android.net.NetworkTemplate.MATCH_WIFI;
|
||||
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
|
||||
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
@@ -34,10 +37,12 @@ import android.app.Fragment;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.INetworkPolicyManager;
|
||||
import android.net.INetworkStatsService;
|
||||
import android.net.NetworkPolicy;
|
||||
@@ -49,10 +54,8 @@ import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.preference.CheckBoxPreference;
|
||||
import android.preference.Preference;
|
||||
import android.preference.PreferenceActivity;
|
||||
import android.preference.SwitchPreference;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.text.TextUtils;
|
||||
import android.text.format.DateUtils;
|
||||
@@ -64,7 +67,6 @@ import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AbsListView;
|
||||
import android.widget.AdapterView;
|
||||
@@ -72,10 +74,14 @@ import android.widget.AdapterView.OnItemClickListener;
|
||||
import android.widget.AdapterView.OnItemSelectedListener;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.CompoundButton.OnCheckedChangeListener;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ListView;
|
||||
import android.widget.NumberPicker;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.Switch;
|
||||
import android.widget.TabHost;
|
||||
import android.widget.TabHost.OnTabChangeListener;
|
||||
import android.widget.TabHost.TabContentFactory;
|
||||
@@ -83,6 +89,7 @@ import android.widget.TabHost.TabSpec;
|
||||
import android.widget.TabWidget;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.internal.telephony.Phone;
|
||||
import com.android.settings.net.NetworkPolicyEditor;
|
||||
import com.android.settings.widget.DataUsageChartView;
|
||||
import com.android.settings.widget.DataUsageChartView.DataUsageChartListener;
|
||||
@@ -93,6 +100,10 @@ import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Panel show data usage history across various networks, including options to
|
||||
* inspect based on usage cycle and control through {@link NetworkPolicy}.
|
||||
*/
|
||||
public class DataUsageSummary extends Fragment {
|
||||
private static final String TAG = "DataUsage";
|
||||
private static final boolean LOGD = true;
|
||||
@@ -114,6 +125,12 @@ public class DataUsageSummary extends Fragment {
|
||||
|
||||
private INetworkStatsService mStatsService;
|
||||
private INetworkPolicyManager mPolicyService;
|
||||
private ConnectivityManager mConnService;
|
||||
|
||||
private static final String PREF_FILE = "data_usage";
|
||||
private static final String PREF_SHOW_WIFI = "show_wifi";
|
||||
|
||||
private SharedPreferences mPrefs;
|
||||
|
||||
private TabHost mTabHost;
|
||||
private TabWidget mTabWidget;
|
||||
@@ -123,8 +140,8 @@ public class DataUsageSummary extends Fragment {
|
||||
private View mHeader;
|
||||
private LinearLayout mSwitches;
|
||||
|
||||
private SwitchPreference mDataEnabled;
|
||||
private CheckBoxPreference mDisableAtLimit;
|
||||
private Switch mDataEnabled;
|
||||
private CheckBox mDisableAtLimit;
|
||||
private View mDataEnabledView;
|
||||
private View mDisableAtLimitView;
|
||||
|
||||
@@ -133,7 +150,6 @@ public class DataUsageSummary extends Fragment {
|
||||
private Spinner mCycleSpinner;
|
||||
private CycleAdapter mCycleAdapter;
|
||||
|
||||
// TODO: persist show wifi flag
|
||||
private boolean mShowWifi = false;
|
||||
|
||||
private NetworkTemplate mTemplate = null;
|
||||
@@ -143,6 +159,9 @@ public class DataUsageSummary extends Fragment {
|
||||
|
||||
private String mIntentTab = null;
|
||||
|
||||
/** Flag used to ignore listeners during binding. */
|
||||
private boolean mBinding;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
@@ -151,10 +170,15 @@ public class DataUsageSummary extends Fragment {
|
||||
ServiceManager.getService(Context.NETWORK_STATS_SERVICE));
|
||||
mPolicyService = INetworkPolicyManager.Stub.asInterface(
|
||||
ServiceManager.getService(Context.NETWORK_POLICY_SERVICE));
|
||||
mConnService = (ConnectivityManager) getActivity().getSystemService(
|
||||
Context.CONNECTIVITY_SERVICE);
|
||||
mPrefs = getActivity().getSharedPreferences(PREF_FILE, Context.MODE_PRIVATE);
|
||||
|
||||
mPolicyEditor = new NetworkPolicyEditor(mPolicyService);
|
||||
mPolicyEditor.read();
|
||||
|
||||
mShowWifi = mPrefs.getBoolean(PREF_SHOW_WIFI, false);
|
||||
|
||||
setHasOptionsMenu(true);
|
||||
}
|
||||
|
||||
@@ -175,17 +199,12 @@ public class DataUsageSummary extends Fragment {
|
||||
mHeader = inflater.inflate(R.layout.data_usage_header, mListView, false);
|
||||
mListView.addHeaderView(mHeader, null, false);
|
||||
|
||||
mDataEnabled = new SwitchPreference(context);
|
||||
mDisableAtLimit = new CheckBoxPreference(context);
|
||||
mDataEnabled = new Switch(inflater.getContext());
|
||||
mDataEnabledView = inflatePreference(inflater, mSwitches, mDataEnabled);
|
||||
mDataEnabled.setOnCheckedChangeListener(mDataEnabledListener);
|
||||
|
||||
// kick refresh once to force-create views
|
||||
refreshPreferenceViews();
|
||||
|
||||
// TODO: remove once thin preferences are supported (48dip)
|
||||
mDataEnabledView.setLayoutParams(new LinearLayout.LayoutParams(MATCH_PARENT, 72));
|
||||
mDisableAtLimitView.setLayoutParams(new LinearLayout.LayoutParams(MATCH_PARENT, 72));
|
||||
|
||||
mDataEnabledView.setOnClickListener(mDataEnabledListener);
|
||||
mDisableAtLimit = new CheckBox(inflater.getContext());
|
||||
mDisableAtLimitView = inflatePreference(inflater, mSwitches, mDisableAtLimit);
|
||||
mDisableAtLimitView.setOnClickListener(mDisableAtLimitListener);
|
||||
|
||||
mSwitches = (LinearLayout) mHeader.findViewById(R.id.switches);
|
||||
@@ -197,9 +216,11 @@ public class DataUsageSummary extends Fragment {
|
||||
mCycleSpinner.setAdapter(mCycleAdapter);
|
||||
mCycleSpinner.setOnItemSelectedListener(mCycleListener);
|
||||
|
||||
final int chartHeight = getResources().getDimensionPixelSize(
|
||||
R.dimen.data_usage_chart_height);
|
||||
mChart = new DataUsageChartView(context);
|
||||
mChart.setListener(mChartListener);
|
||||
mChart.setLayoutParams(new AbsListView.LayoutParams(MATCH_PARENT, 350));
|
||||
mChart.setLayoutParams(new AbsListView.LayoutParams(MATCH_PARENT, chartHeight));
|
||||
mListView.addHeaderView(mChart, null, false);
|
||||
|
||||
mAdapter = new DataUsageAdapter();
|
||||
@@ -235,8 +256,19 @@ public class DataUsageSummary extends Fragment {
|
||||
|
||||
@Override
|
||||
public void onPrepareOptionsMenu(Menu menu) {
|
||||
final Context context = getActivity();
|
||||
|
||||
final MenuItem split4g = menu.findItem(R.id.action_split_4g);
|
||||
split4g.setVisible(hasMobile4gRadio(context));
|
||||
split4g.setChecked(isMobilePolicySplit());
|
||||
|
||||
final MenuItem showWifi = menu.findItem(R.id.action_show_wifi);
|
||||
showWifi.setVisible(hasMobileRadio(context) && hasWifiRadio(context));
|
||||
showWifi.setChecked(mShowWifi);
|
||||
|
||||
final MenuItem settings = menu.findItem(R.id.action_settings);
|
||||
settings.setVisible(split4g.isVisible() || showWifi.isVisible());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -251,6 +283,7 @@ public class DataUsageSummary extends Fragment {
|
||||
}
|
||||
case R.id.action_show_wifi: {
|
||||
mShowWifi = !item.isChecked();
|
||||
mPrefs.edit().putBoolean(PREF_SHOW_WIFI, mShowWifi).apply();
|
||||
item.setChecked(mShowWifi);
|
||||
updateTabs();
|
||||
return true;
|
||||
@@ -273,24 +306,25 @@ public class DataUsageSummary extends Fragment {
|
||||
* first tab, and kicks off a full rebind of body contents.
|
||||
*/
|
||||
private void updateTabs() {
|
||||
final boolean mobileSplit = isMobilePolicySplit();
|
||||
final boolean tabsVisible = mobileSplit || mShowWifi;
|
||||
mTabWidget.setVisibility(tabsVisible ? View.VISIBLE : View.GONE);
|
||||
final Context context = getActivity();
|
||||
mTabHost.clearAllTabs();
|
||||
|
||||
if (mobileSplit) {
|
||||
final boolean mobileSplit = isMobilePolicySplit();
|
||||
if (mobileSplit && hasMobile4gRadio(context)) {
|
||||
mTabHost.addTab(buildTabSpec(TAB_3G, R.string.data_usage_tab_3g));
|
||||
mTabHost.addTab(buildTabSpec(TAB_4G, R.string.data_usage_tab_4g));
|
||||
}
|
||||
|
||||
if (mShowWifi) {
|
||||
if (mShowWifi && hasWifiRadio(context) && hasMobileRadio(context)) {
|
||||
if (!mobileSplit) {
|
||||
mTabHost.addTab(buildTabSpec(TAB_MOBILE, R.string.data_usage_tab_mobile));
|
||||
}
|
||||
mTabHost.addTab(buildTabSpec(TAB_WIFI, R.string.data_usage_tab_wifi));
|
||||
}
|
||||
|
||||
if (mTabWidget.getTabCount() > 0) {
|
||||
final boolean hasTabs = mTabWidget.getTabCount() > 0;
|
||||
mTabWidget.setVisibility(hasTabs ? View.VISIBLE : View.GONE);
|
||||
if (hasTabs) {
|
||||
if (mIntentTab != null) {
|
||||
// select default tab, which will kick off updateBody()
|
||||
mTabHost.setCurrentTabByTag(mIntentTab);
|
||||
@@ -340,11 +374,21 @@ public class DataUsageSummary extends Fragment {
|
||||
* binds them to visible controls.
|
||||
*/
|
||||
private void updateBody() {
|
||||
final String tabTag = mTabHost.getCurrentTabTag();
|
||||
final String currentTab = tabTag != null ? tabTag : TAB_MOBILE;
|
||||
mBinding = true;
|
||||
|
||||
final Context context = getActivity();
|
||||
final String subscriberId = getActiveSubscriberId(context);
|
||||
final String tabTag = mTabHost.getCurrentTabTag();
|
||||
|
||||
final String currentTab;
|
||||
if (tabTag != null) {
|
||||
currentTab = tabTag;
|
||||
} else if (hasMobileRadio(context)) {
|
||||
currentTab = TAB_MOBILE;
|
||||
} else if (hasWifiRadio(context)) {
|
||||
currentTab = TAB_WIFI;
|
||||
} else {
|
||||
throw new IllegalStateException("no mobile or wifi radios");
|
||||
}
|
||||
|
||||
if (LOGD) Log.d(TAG, "updateBody() with currentTab=" + currentTab);
|
||||
|
||||
@@ -360,26 +404,26 @@ public class DataUsageSummary extends Fragment {
|
||||
mDisableAtLimitView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
final String subscriberId = getActiveSubscriberId(context);
|
||||
if (TAB_MOBILE.equals(currentTab)) {
|
||||
mDataEnabled.setTitle(R.string.data_usage_enable_mobile);
|
||||
mDisableAtLimit.setTitle(R.string.data_usage_disable_mobile_limit);
|
||||
setPreferenceTitle(mDataEnabledView, R.string.data_usage_enable_mobile);
|
||||
setPreferenceTitle(mDisableAtLimitView, R.string.data_usage_disable_mobile_limit);
|
||||
mDataEnabled.setChecked(mConnService.getMobileDataEnabled());
|
||||
mTemplate = new NetworkTemplate(MATCH_MOBILE_ALL, subscriberId);
|
||||
|
||||
} else if (TAB_3G.equals(currentTab)) {
|
||||
mDataEnabled.setTitle(R.string.data_usage_enable_3g);
|
||||
mDisableAtLimit.setTitle(R.string.data_usage_disable_3g_limit);
|
||||
setPreferenceTitle(mDataEnabledView, R.string.data_usage_enable_3g);
|
||||
setPreferenceTitle(mDisableAtLimitView, R.string.data_usage_disable_3g_limit);
|
||||
// TODO: bind mDataEnabled to 3G radio state
|
||||
mTemplate = new NetworkTemplate(MATCH_MOBILE_3G_LOWER, subscriberId);
|
||||
|
||||
} else if (TAB_4G.equals(currentTab)) {
|
||||
mDataEnabled.setTitle(R.string.data_usage_enable_4g);
|
||||
mDisableAtLimit.setTitle(R.string.data_usage_disable_4g_limit);
|
||||
setPreferenceTitle(mDataEnabledView, R.string.data_usage_enable_4g);
|
||||
setPreferenceTitle(mDisableAtLimitView, R.string.data_usage_disable_4g_limit);
|
||||
// TODO: bind mDataEnabled to 4G radio state
|
||||
mTemplate = new NetworkTemplate(MATCH_MOBILE_4G, subscriberId);
|
||||
|
||||
}
|
||||
|
||||
// TODO: populate checkbox based on radio preferences
|
||||
mDataEnabled.setChecked(true);
|
||||
|
||||
try {
|
||||
// load stats for current template
|
||||
mHistory = mStatsService.getHistoryForNetwork(mTemplate);
|
||||
@@ -397,8 +441,7 @@ public class DataUsageSummary extends Fragment {
|
||||
// force scroll to top of body
|
||||
mListView.smoothScrollToPosition(0);
|
||||
|
||||
// kick preference views so they rebind from changes above
|
||||
refreshPreferenceViews();
|
||||
mBinding = false;
|
||||
}
|
||||
|
||||
private void setPolicyCycleDay(int cycleDay) {
|
||||
@@ -434,9 +477,6 @@ public class DataUsageSummary extends Fragment {
|
||||
// generate cycle list based on policy and available history
|
||||
updateCycleList(policy);
|
||||
}
|
||||
|
||||
// kick preference views so they rebind from changes above
|
||||
refreshPreferenceViews();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -506,25 +546,23 @@ public class DataUsageSummary extends Fragment {
|
||||
mCycleListener.onItemSelected(mCycleSpinner, null, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Force rebind of hijacked {@link Preference} views.
|
||||
*/
|
||||
private void refreshPreferenceViews() {
|
||||
mDataEnabledView = mDataEnabled.getView(mDataEnabledView, mListView);
|
||||
mDisableAtLimitView = mDisableAtLimit.getView(mDisableAtLimitView, mListView);
|
||||
}
|
||||
|
||||
private OnClickListener mDataEnabledListener = new OnClickListener() {
|
||||
private OnCheckedChangeListener mDataEnabledListener = new OnCheckedChangeListener() {
|
||||
/** {@inheritDoc} */
|
||||
public void onClick(View v) {
|
||||
mDataEnabled.setChecked(!mDataEnabled.isChecked());
|
||||
refreshPreferenceViews();
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||
if (mBinding) return;
|
||||
|
||||
// TODO: wire up to telephony to enable/disable radios
|
||||
final boolean dataEnabled = isChecked;
|
||||
mDataEnabled.setChecked(dataEnabled);
|
||||
|
||||
switch (mTemplate.getMatchRule()) {
|
||||
case MATCH_MOBILE_ALL: {
|
||||
mConnService.setMobileDataEnabled(dataEnabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private OnClickListener mDisableAtLimitListener = new OnClickListener() {
|
||||
private View.OnClickListener mDisableAtLimitListener = new View.OnClickListener() {
|
||||
/** {@inheritDoc} */
|
||||
public void onClick(View v) {
|
||||
final boolean disableAtLimit = !mDisableAtLimit.isChecked();
|
||||
@@ -724,12 +762,10 @@ public class DataUsageSummary extends Fragment {
|
||||
|
||||
for (int i = 0; i < stats.size; i++) {
|
||||
final long total = stats.rx[i] + stats.tx[i];
|
||||
if (total > 0) {
|
||||
final AppUsageItem item = new AppUsageItem();
|
||||
item.uid = stats.uid[i];
|
||||
item.total = total;
|
||||
mItems.add(item);
|
||||
}
|
||||
final AppUsageItem item = new AppUsageItem();
|
||||
item.uid = stats.uid[i];
|
||||
item.total = total;
|
||||
mItems.add(item);
|
||||
}
|
||||
|
||||
Collections.sort(mItems);
|
||||
@@ -995,4 +1031,60 @@ public class DataUsageSummary extends Fragment {
|
||||
return label;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if device has a mobile data radio.
|
||||
*/
|
||||
private static boolean hasMobileRadio(Context context) {
|
||||
final ConnectivityManager conn = (ConnectivityManager) context.getSystemService(
|
||||
Context.CONNECTIVITY_SERVICE);
|
||||
|
||||
// mobile devices should have MOBILE network tracker regardless of
|
||||
// connection status.
|
||||
return conn.getNetworkInfo(TYPE_MOBILE) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if device has a mobile 4G data radio.
|
||||
*/
|
||||
private static boolean hasMobile4gRadio(Context context) {
|
||||
final ConnectivityManager conn = (ConnectivityManager) context.getSystemService(
|
||||
Context.CONNECTIVITY_SERVICE);
|
||||
final TelephonyManager telephony = (TelephonyManager) context.getSystemService(
|
||||
Context.TELEPHONY_SERVICE);
|
||||
|
||||
// WiMAX devices should have WiMAX network tracker regardless of
|
||||
// connection status.
|
||||
final boolean hasWimax = conn.getNetworkInfo(TYPE_WIMAX) != null;
|
||||
final boolean hasLte = telephony.getLteOnCdmaMode() == Phone.LTE_ON_CDMA_TRUE;
|
||||
return hasWimax || hasLte;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if device has a Wi-Fi data radio.
|
||||
*/
|
||||
private static boolean hasWifiRadio(Context context) {
|
||||
return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inflate a {@link Preference} style layout, adding the given {@link View}
|
||||
* widget into {@link android.R.id#widget_frame}.
|
||||
*/
|
||||
private static View inflatePreference(LayoutInflater inflater, ViewGroup root, View widget) {
|
||||
final View view = inflater.inflate(R.layout.preference, root, false);
|
||||
final LinearLayout widgetFrame = (LinearLayout) view.findViewById(
|
||||
android.R.id.widget_frame);
|
||||
widgetFrame.addView(widget, new LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT));
|
||||
return view;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set {@link android.R.id#title} for a preference view inflated with
|
||||
* {@link #inflatePreference(LayoutInflater, View, View)}.
|
||||
*/
|
||||
private static void setPreferenceTitle(View parent, int resId) {
|
||||
final TextView title = (TextView) parent.findViewById(android.R.id.title);
|
||||
title.setText(resId);
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user