Android快捷开关实现(转)
在Android源码中,提供的快捷开关相对是比较少的,Android4.0系统默认提供的桌面快捷开关AppWidget上只有5种开关(分别是Wifi开关、蓝牙开关、GPS开关、同步开关、亮度设置开关)如下图所示:
当然,有时候就需要开发实现承载更多的快捷开关的AppWidget来实现用户体验,所以,本文主要针对这些开关的主要代码实现来重点解决开发这些快捷开关。
本文涉及到的快捷开关代码实现有Wifi、蓝牙、GPS、同步、亮度设置、飞行模式、移动数据流量(实现开启和关闭移动网络)、静音模式、重启、关机、锁屏、屏幕旋转等。需要注意的是:实现这些开关控制时都需要在AndroidManifest.xml文件中添加相应的权限。
一般这些开关在被设置改变时,系统会向外界发送相应的广播。所以,当用代码实现操作这些开关时,我们可以通过动态注册广播接收器,来接收这些系统发送的状态改变广播,以此来验证我们是否正常设置改变了这些开关。
当然,在本文以下的一些实例代码中,开关按钮也随着状态的改变而显示不同的文字,动态注册广播接收会显得有点多余,不过这只是证明系统会发送相应的广播,还应用开发还是有用处的,至少我们可以在不同的进程中监听接收这些广播。
1. Wifi开关:
1). Wifi开关由WifiManager这个类控制实现。
2). 当Wifi开关改变时,系统会向外界发送广播android.net.wifi.WIFI_STATE_CHANGED;
示列代码如下:
- package com.example.wst;
- import android.app.Activity;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- import android.content.IntentFilter;
- import android.net.wifi.WifiManager;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.Toast;
- public class WifiSwitchTest extends Activity implements OnClickListener
- {
- private WifiManager mWifiManager;
- private Button mWifiButton;
- //Wifi设置改变系统发送的广播
- public static final String WIFI_STATE_CHANGED = "android.net.wifi.WIFI_STATE_CHANGED";
- private TestChange mTestChange;
- private IntentFilter mIntentFilter;
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- mWifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
- mTestChange = new TestChange();
- mIntentFilter = new IntentFilter();
- // 添加广播接收器过滤的广播
- mIntentFilter.addAction("android.net.wifi.WIFI_STATE_CHANGED");
- mWifiButton = (Button)findViewById(R.id.wifi);
- refreshButton();
- mWifiButton.setOnClickListener(this);
- }
- @Override
- protected void onDestroy()
- {
- // TODO Auto-generated method stub
- super.onDestroy();
- // 解除广播接收器
- unregisterReceiver(mTestChange);
- }
- @Override
- protected void onResume()
- {
- // TODO Auto-generated method stub
- super.onResume();
- // 注册广播接收器
- registerReceiver(mTestChange, mIntentFilter);
- }
- //更新按钮
- private void refreshButton()
- {
- mWifiButton.setText(mWifiManager.isWifiEnabled() ? R.string.wifi_off : R.string.wifi_on);
- }
- @Override
- public void onClick(View v)
- {
- // TODO Auto-generated method stub
- if (mWifiManager.isWifiEnabled())
- {
- //关闭Wifi,按钮显示开启
- mWifiManager.setWifiEnabled(false);
- }
- else
- {
- //开启Wifi,按钮显示关闭
- mWifiManager.setWifiEnabled(true);
- }
- }
- private class TestChange extends BroadcastReceiver
- {
- @Override
- public void onReceive(Context context, Intent intent)
- {
- // TODO Auto-generated method stub
- String action = intent.getAction();
- if (WIFI_STATE_CHANGED.equals(action))
- {
- refreshButton();
- Toast.makeText(WifiSwitchTest.this, "Wifi设置有改变",
- Toast.LENGTH_SHORT).show();
- }
- }
- }
- }
权限添加:
- <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
- <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
2. 蓝牙开关:
1). 蓝牙开关主要调用BluetoothAdapter相关方法实现
2). 蓝牙有四种状态:正在打开、打开、正在关闭、关闭
3). 蓝牙状态改变,系统向外界发送广播android.bluetooth.adapter.action.STATE_CHANGED或android.bluetooth.a2dp.profile.action.CONNECTION_STATE_CHANGED;
示例代码如下:
- package com.example.bts;
- import android.app.Activity;
- import android.bluetooth.BluetoothAdapter;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- import android.content.IntentFilter;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.Toast;
- public class BluetoothSwitch extends Activity implements OnClickListener
- {
- private Button mBluetooth;
- private BluetoothAdapter mBluetoothAdapter;
- private TestChange mTestChange;
- private IntentFilter mIntentFilter;
- public static final String BLUETOOTH_STATE_CHANGED = "android.bluetooth.adapter.action.STATE_CHANGED";
- private static final String BLUETOOTH_ACTION = "android.bluetooth.a2dp.profile.action.CONNECTION_STATE_CHANGED";
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
- mTestChange = new TestChange();
- mIntentFilter = new IntentFilter();
- // 添加广播接收器过滤的广播
- mIntentFilter.addAction("android.bluetooth.adapter.action.STATE_CHANGED");
- mIntentFilter.addAction("android.bluetooth.a2dp.profile.action.CONNECTION_STATE_CHANGED");
- mBluetooth = (Button)findViewById(R.id.blue);
- refreshButton();
- mBluetooth.setOnClickListener(this);
- }
- @Override
- protected void onDestroy()
- {
- // TODO Auto-generated method stub
- super.onDestroy();
- // 解除广播接收器
- unregisterReceiver(mTestChange);
- }
- @Override
- protected void onResume()
- {
- // TODO Auto-generated method stub
- super.onResume();
- // 注册广播接收器
- registerReceiver(mTestChange, mIntentFilter);
- }
- //更新按钮状态
- private void refreshButton()
- {
- switch (getBluetoothStatus())
- {
- case BluetoothAdapter.STATE_ON:
- mBluetooth.setText(R.string.off);
- break;
- case BluetoothAdapter.STATE_TURNING_ON:
- mBluetooth.setText(R.string.oning);
- break;
- case BluetoothAdapter.STATE_OFF:
- mBluetooth.setText(R.string.on);
- break;
- case BluetoothAdapter.STATE_TURNING_OFF:
- mBluetooth.setText(R.string.offing);
- break;
- }
- }
- //获取蓝牙当前状态
- private int getBluetoothStatus()
- {
- return mBluetoothAdapter.getState();
- }
- //设置蓝牙开关
- private void setBluetoothStatus()
- {
- switch (getBluetoothStatus())
- {
- case BluetoothAdapter.STATE_ON:
- mBluetoothAdapter.disable();
- break;
- case BluetoothAdapter.STATE_TURNING_ON:
- mBluetoothAdapter.disable();
- break;
- case BluetoothAdapter.STATE_OFF:
- mBluetoothAdapter.enable();
- break;
- case BluetoothAdapter.STATE_TURNING_OFF:
- mBluetoothAdapter.enable();
- break;
- }
- }
- @Override
- public void onClick(View v)
- {
- // TODO Auto-generated method stub
- setBluetoothStatus();
- }
- private class TestChange extends BroadcastReceiver
- {
- @Override
- public void onReceive(Context context, Intent intent)
- {
- // TODO Auto-generated method stub
- String action = intent.getAction();
- if (BLUETOOTH_STATE_CHANGED.equals(action) || BLUETOOTH_ACTION.equals(action))
- {
- Toast.makeText(BluetoothSwitch.this, "蓝牙模式设置有改变",
- Toast.LENGTH_SHORT).show();
- //动态刷新按钮
- refreshButton();
- }
- }
- }
- }
权限添加:
- <uses-permission android:name="android.permission.BLUETOOTH" />
- <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
3. 屏幕旋转开关:
1). 屏幕旋转开关设置主要调用android.provider.Settings.System的putInt和getInt方法实现。
2). 通过ContentObserver来动态观察屏幕旋转设置的改变。
示例代码如下:
- package com.example.srs;
- import android.app.Activity;
- import android.content.ContentResolver;
- import android.content.Context;
- import android.database.ContentObserver;
- import android.net.Uri;
- import android.os.Bundle;
- import android.os.Handler;
- import android.provider.Settings;
- import android.provider.Settings.SettingNotFoundException;
- import android.util.Log;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.Toast;
- public class ScreenRotationSwitch extends Activity implements OnClickListener
- {
- private Button mRotationButton;
- private RotationObserver mRotationObserver;
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- //创建观察类对象
- mRotationObserver = new RotationObserver(new Handler());
- mRotationButton = (Button) findViewById(R.id.rotation);
- refreshButton();
- mRotationButton.setOnClickListener(this);
- }
- @Override
- protected void onDestroy() {
- // TODO Auto-generated method stub
- super.onDestroy();
- //解除观察变化
- mRotationObserver.stopObserver();
- }
- @Override
- protected void onResume() {
- // TODO Auto-generated method stub
- super.onResume();
- //注册观察变化
- mRotationObserver.startObserver();
- }
- //更新按钮状态
- private void refreshButton()
- {
- if (getRotationStatus(this) == 1)
- {
- mRotationButton.setText(R.string.rotation_off);
- }
- else
- {
- mRotationButton.setText(R.string.rotation_on);
- }
- }
- //得到屏幕旋转的状态
- private int getRotationStatus(Context context)
- {
- int status = 0;
- try
- {
- status = android.provider.Settings.System.getInt(context.getContentResolver(),
- android.provider.Settings.System.ACCELEROMETER_ROTATION);
- }
- catch (SettingNotFoundException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- return status;
- }
- private void setRotationStatus(ContentResolver resolver, int status)
- {
- //得到uri
- Uri uri = android.provider.Settings.System.getUriFor("accelerometer_rotation");
- //沟通设置status的值改变屏幕旋转设置
- android.provider.Settings.System.putInt(resolver, "accelerometer_rotation", status);
- //通知改变
- resolver.notifyChange(uri, null);
- }
- @Override
- public void onClick(View v)
- {
- // TODO Auto-generated method stub
- if (getRotationStatus(this) == 1)
- {
- setRotationStatus(getContentResolver(), 0);
- }
- else
- {
- setRotationStatus(getContentResolver(), 1);
- }
- }
- //观察屏幕旋转设置变化,类似于注册动态广播监听变化机制
- private class RotationObserver extends ContentObserver
- {
- ContentResolver mResolver;
- public RotationObserver(Handler handler)
- {
- super(handler);
- mResolver = getContentResolver();
- // TODO Auto-generated constructor stub
- }
- //屏幕旋转设置改变时调用
- @Override
- public void onChange(boolean selfChange)
- {
- // TODO Auto-generated method stub
- super.onChange(selfChange);
- //更新按钮状态
- refreshButton();
- Toast.makeText(ScreenRotationSwitch.this, "旋转屏幕设置有变化",
- Toast.LENGTH_SHORT).show();
- }
- public void startObserver()
- {
- mResolver.registerContentObserver(Settings.System
- .getUriFor(Settings.System.ACCELEROMETER_ROTATION), false,
- this);
- }
- public void stopObserver()
- {
- mResolver.unregisterContentObserver(this);
- }
- }
- }
权限添加:
- <uses-permission android:name="android.permission.WRITE_SETTINGS"/>
4. 同步开关:
1). 同步开关设置主要由ContentResolver类(抽象类)的静态函数来实现;
2). 当同步模式改变时,系统会向外界发送广播com.android.sync.SYNC_CONN_STATUS_CHANGED;
示例代码如下:
- package com.example.sst;
- import android.app.Activity;
- import android.content.BroadcastReceiver;
- import android.content.ContentResolver;
- import android.content.Context;
- import android.content.Intent;
- import android.content.IntentFilter;
- import android.net.ConnectivityManager;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.Toast;
- public class SyncSwitchTest extends Activity implements OnClickListener
- {
- private Button mSyncButton;
- private TestChange mTestChange;
- private IntentFilter mIntentFilter;
- //同步模式改变系统发送的广播
- private static final String SYNC_CONN_STATUS_CHANGED = "com.android.sync.SYNC_CONN_STATUS_CHANGED";
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- mTestChange = new TestChange();
- mIntentFilter = new IntentFilter();
- //添加广播接收器过滤的广播
- mIntentFilter.addAction("com.android.sync.SYNC_CONN_STATUS_CHANGED");
- mSyncButton = (Button)findViewById(R.id.sync);
- refreshButton();
- mSyncButton.setOnClickListener(this);
- }
- @Override
- protected void onDestroy()
- {
- // TODO Auto-generated method stub
- super.onDestroy();
- //解除广播接收器
- unregisterReceiver(mTestChange);
- }
- @Override
- protected void onResume() {
- // TODO Auto-generated method stub
- super.onResume();
- //注册广播接收器
- registerReceiver(mTestChange, mIntentFilter);
- }
- //更新按钮状态
- private void refreshButton()
- {
- mSyncButton.setText(getSyncStatus(this) ? R.string.sync_off : R.string.sync_on);
- }
- private boolean getSyncStatus(Context context)
- {
- ConnectivityManager connManager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
- return connManager.getBackgroundDataSetting() && ContentResolver.getMasterSyncAutomatically();
- }
- private void setSyncStatus(boolean enbled)
- {
- /*getMasterSyncAutomatically和setMasterSyncAutomatically为抽象类ContentResolver的静态函数,
- * 所以可以直接通过类来调用
- */
- ContentResolver.setMasterSyncAutomatically(enbled);
- }
- @Override
- public void onClick(View v)
- {
- // TODO Auto-generated method stub
- if(getSyncStatus(this))
- {
- setSyncStatus(false);
- }
- else
- {
- setSyncStatus(true);
- }
- }
- private class TestChange extends BroadcastReceiver
- {
- @Override
- public void onReceive(Context context, Intent intent)
- {
- // TODO Auto-generated method stub
- String action = intent.getAction();
- if (SYNC_CONN_STATUS_CHANGED.equals(action))
- {
- refreshButton();
- Toast.makeText(SyncSwitchTest.this, "同步模式设置有改变", Toast.LENGTH_SHORT).show();
- }
- }
- }
- }
权限添加:
- <uses-permission android:name="android.permission.READ_SYNC_STATS" />
- <uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
- <uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
5. 亮度设置开关:
1). 亮度设置的主要调用Settings.System的putInt和getInt方法来处理,已经调用PowerManager的setBacklightBrightness方法来实现调节手机亮度。
2). PowerManager的setBacklightBrightness的方法是隐藏的,通过反射来调用实现。
3). 通过ContentObserver来动态观察亮度设置的改变。
示例代码如下:
- package com.example.bs;
- import java.lang.reflect.Field;
- import java.lang.reflect.InvocationTargetException;
- import java.lang.reflect.Method;
- import android.app.Activity;
- import android.content.ContentResolver;
- import android.content.Context;
- import android.database.ContentObserver;
- import android.os.Bundle;
- import android.os.Handler;
- import android.os.PowerManager;
- import android.provider.Settings;
- import android.provider.Settings.SettingNotFoundException;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.Toast;
- public class BrightnessSwitch extends Activity implements OnClickListener
- {
- private Button mBrightness;
- private static final int LIGHT_NORMAL = 64;
- private static final int LIGHT_50_PERCENT = 127;
- private static final int LIGHT_75_PERCENT = 191;
- private static final int LIGHT_100_PERCENT = 255;
- private static final int LIGHT_AUTO = 0;
- private static final int LIGHT_ERR = -1;
- private BrightObserver mBrightObserver;
- private PowerManager mPowerManager;
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- mPowerManager = (PowerManager)getSystemService(Context.POWER_SERVICE);
- mBrightObserver = new BrightObserver(new Handler());
- mBrightness = (Button)findViewById(R.id.bright);
- refreshButton();
- mBrightness.setOnClickListener(this);
- }
- @Override
- protected void onDestroy()
- {
- // TODO Auto-generated method stub
- super.onDestroy();
- mBrightObserver.stopObserver();
- }
- @Override
- protected void onResume()
- {
- // TODO Auto-generated method stub
- super.onResume();
- mBrightObserver.startObserver();
- }
- //更新按钮
- private void refreshButton()
- {
- switch (getBrightStatus())
- {
- case LIGHT_NORMAL:
- mBrightness.setText(R.string.light_50percent);
- break;
- case LIGHT_50_PERCENT:
- mBrightness.setText(R.string.light_75percent);
- break;
- case LIGHT_75_PERCENT:
- mBrightness.setText(R.string.light_100percent);
- break;
- case LIGHT_100_PERCENT:
- mBrightness.setText(R.string.light_auto);
- break;
- case LIGHT_AUTO:
- mBrightness.setText(R.string.light_normal);
- break;
- case LIGHT_ERR:
- mBrightness.setText(R.string.light_err);
- break;
- }
- }
- //得到当前亮度值状态
- private int getBrightStatus()
- {
- // TODO Auto-generated method stub
- int light = 0;
- boolean auto = false;
- ContentResolver cr = getContentResolver();
- try
- {
- auto = Settings.System.getInt(cr,
- Settings.System.SCREEN_BRIGHTNESS_MODE) == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC;
- if (!auto)
- {
- light = android.provider.Settings.System.getInt(cr,
- Settings.System.SCREEN_BRIGHTNESS, -1);
- if (light > 0 && light <= LIGHT_NORMAL)
- {
- return LIGHT_NORMAL;
- }
- else if (light > LIGHT_NORMAL && light <= LIGHT_50_PERCENT)
- {
- return LIGHT_50_PERCENT;
- }
- else if (light > LIGHT_50_PERCENT && light <= LIGHT_75_PERCENT)
- {
- return LIGHT_75_PERCENT;
- }
- else if (light > LIGHT_75_PERCENT && light <= LIGHT_100_PERCENT)
- {
- return LIGHT_100_PERCENT;
- }
- }
- else
- {
- return LIGHT_AUTO;
- }
- }
- catch (SettingNotFoundException e1)
- {
- // TODO Auto-generated catch block
- e1.printStackTrace();
- }
- return LIGHT_ERR;
- }
- private void setBrightStatus()
- {
- int light = 0;
- switch (getBrightStatus())
- {
- case LIGHT_NORMAL:
- light = LIGHT_50_PERCENT - 1;
- break;
- case LIGHT_50_PERCENT:
- light = LIGHT_75_PERCENT - 1;
- break;
- case LIGHT_75_PERCENT:
- light = LIGHT_100_PERCENT - 1;
- break;
- case LIGHT_100_PERCENT:
- startAutoBrightness(getContentResolver());
- break;
- case LIGHT_AUTO:
- light = LIGHT_NORMAL - 1;
- stopAutoBrightness(getContentResolver());
- break;
- case LIGHT_ERR:
- light = LIGHT_NORMAL - 1;
- break;
- }
- setLight(light);
- setScreenLightValue(getContentResolver(), light);
- }
- /*因为PowerManager提供的函数setBacklightBrightness接口是隐藏的,
- * 所以在基于第三方开发调用该函数时,只能通过反射实现在运行时调用
- */
- private void setLight(int light)
- {
- try
- {
- //得到PowerManager类对应的Class对象
- Class<?> pmClass = Class.forName(mPowerManager.getClass().getName());
- //得到PowerManager类中的成员mService(mService为PowerManagerService类型)
- Field field = pmClass.getDeclaredField("mService");
- field.setAccessible(true);
- //实例化mService
- Object iPM = field.get(mPowerManager);
- //得到PowerManagerService对应的Class对象
- Class<?> iPMClass = Class.forName(iPM.getClass().getName());
- /*得到PowerManagerService的函数setBacklightBrightness对应的Method对象,
- * PowerManager的函数setBacklightBrightness实现在PowerManagerService中
- */
- Method method = iPMClass.getDeclaredMethod("setBacklightBrightness", int.class);
- method.setAccessible(true);
- //调用实现PowerManagerService的setBacklightBrightness
- method.invoke(iPM, light);
- }
- catch (ClassNotFoundException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- catch (NoSuchFieldException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- catch (IllegalArgumentException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- catch (IllegalAccessException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- catch (NoSuchMethodException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- catch (InvocationTargetException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- @Override
- public void onClick(View v)
- {
- // TODO Auto-generated method stub
- setBrightStatus();
- }
- //启动自动调节亮度
- public void startAutoBrightness(ContentResolver cr)
- {
- Settings.System.putInt(cr, Settings.System.SCREEN_BRIGHTNESS_MODE,
- Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
- }
- //关闭自动调节亮度
- public void stopAutoBrightness(ContentResolver cr)
- {
- Settings.System.putInt(cr, Settings.System.SCREEN_BRIGHTNESS_MODE,
- Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL);
- }
- //设置改变亮度值
- public void setScreenLightValue(ContentResolver resolver, int value)
- {
- android.provider.Settings.System.putInt(resolver, Settings.System.SCREEN_BRIGHTNESS,
- value);
- }
- private class BrightObserver extends ContentObserver
- {
- ContentResolver mResolver;
- public BrightObserver(Handler handler)
- {
- super(handler);
- mResolver = getContentResolver();
- }
- @Override
- public void onChange(boolean selfChange)
- {
- // TODO Auto-generated method stub
- super.onChange(selfChange);
- refreshButton();
- Toast.makeText(BrightnessSwitch.this, "亮度设置有改变", Toast.LENGTH_SHORT).show();
- }
- //注册观察
- public void startObserver()
- {
- mResolver.registerContentObserver(Settings.System
- .getUriFor(Settings.System.SCREEN_BRIGHTNESS), false,
- this);
- mResolver.registerContentObserver(Settings.System
- .getUriFor(Settings.System.SCREEN_BRIGHTNESS_MODE), false,
- this);
- }
- //解除观察
- public void stopObserver()
- {
- mResolver.unregisterContentObserver(this);
- }
- }
- }
权限添加:
- <uses-permission android:name="android.permission.WRITE_SETTINGS" />
- <uses-permission android:name="android.permission.DEVICE_POWER" />
6. 飞行模式开关:
1). 飞行模式主要是调用Settings.System的getInt和setInt方法来处理。
2). 当飞行模式改变时,系统会向外界发送广播android.intent.action.AIRPLANE_MODE;
示例代码如下:
- package com.example.apmst;
- import android.app.Activity;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- import android.content.IntentFilter;
- import android.os.Bundle;
- import android.provider.Settings;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.Toast;
- public class AirplaneModeSwitchTest extends Activity implements OnClickListener
- {
- private Button mAirplane;
- //飞行模式设置改变系统发送的广播
- private static final String AIRPLANE_MODE = "android.intent.action.AIRPLANE_MODE";
- private TestChange mTestChange;
- private IntentFilter mIntentFilter;
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- mTestChange = new TestChange();
- mIntentFilter = new IntentFilter();
- // 添加广播接收器过滤的广播
- mIntentFilter.addAction("android.intent.action.AIRPLANE_MODE");
- mAirplane = (Button)findViewById(R.id.airplane);
- refreshButton();
- mAirplane.setOnClickListener(this);
- }
- @Override
- protected void onDestroy()
- {
- // TODO Auto-generated method stub
- super.onDestroy();
- // 解除广播接收器
- unregisterReceiver(mTestChange);
- }
- @Override
- protected void onResume()
- {
- // TODO Auto-generated method stub
- super.onResume();
- // 注册广播接收器
- registerReceiver(mTestChange, mIntentFilter);
- }
- //更新按钮状态
- private void refreshButton()
- {
- mAirplane.setText(getAirplaneModeStatus() ? R.string.airplane_off : R.string.airplane_on);
- }
- //获取飞行模式关闭或开启状态
- private boolean getAirplaneModeStatus()
- {
- boolean status = Settings.System.getInt(this.getContentResolver(),
- Settings.System.AIRPLANE_MODE_ON, 0) == 1 ? true : false;
- return status;
- }
- //开启或关闭飞行模式
- private void setAirplaneMode(Context context, boolean enable)
- {
- Settings.System.putInt(context.getContentResolver(),
- Settings.System.AIRPLANE_MODE_ON, enable ? 1 : 0);
- Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
- intent.putExtra("state", enable);
- context.sendBroadcast(intent);
- }
- @Override
- public void onClick(View v)
- {
- // TODO Auto-generated method stub
- if (getAirplaneModeStatus())
- {
- setAirplaneMode(this, false);
- }
- else
- {
- setAirplaneMode(this, true);
- }
- }
- private class TestChange extends BroadcastReceiver
- {
- @Override
- public void onReceive(Context context, Intent intent)
- {
- // TODO Auto-generated method stub
- String action = intent.getAction();
- if (AIRPLANE_MODE.equals(action))
- {
- refreshButton();
- Toast.makeText(AirplaneModeSwitchTest.this, "飞行模式设置有改变",
- Toast.LENGTH_SHORT).show();
- }
- }
- }
- }
权限添加:
- <uses-permission android:name="android.permission.WRITE_SETTINGS" />
7. 移动数据流量开关:
1). 移动数据流量由ConnectivityManager类控制实现,这个类实现设置和获取移动流量状态的方法是隐藏的,所以我们只能通过反射来实现(或者在源码下编译APK)。
2). 相关广播为android.intent.action.ANY_DATA_STATE;
示例代码如下:
- package com.example.mdst;
- import java.lang.reflect.Field;
- import java.lang.reflect.InvocationTargetException;
- import java.lang.reflect.Method;
- import android.app.Activity;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- import android.content.IntentFilter;
- import android.net.ConnectivityManager;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.Toast;
- public class MobileDataSwitchTest extends Activity implements OnClickListener
- {
- private ConnectivityManager mConnectivityManager;
- private Button mMobileDataButton;
- // 移动数据设置改变系统发送的广播
- private static final String NETWORK_CHANGE = "android.intent.action.ANY_DATA_STATE";
- private TestChange mTestChange;
- private IntentFilter mIntentFilter;
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- mConnectivityManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
- mTestChange = new TestChange();
- mIntentFilter = new IntentFilter();
- // 添加广播接收器过滤的广播
- mIntentFilter.addAction("android.intent.action.ANY_DATA_STATE");
- mMobileDataButton = (Button) findViewById(R.id.mobile_data);
- refreshButton();
- mMobileDataButton.setOnClickListener(this);
- }
- @Override
- protected void onDestroy()
- {
- // TODO Auto-generated method stub
- super.onDestroy();
- // 解除广播接收器
- unregisterReceiver(mTestChange);
- }
- @Override
- protected void onResume()
- {
- // TODO Auto-generated method stub
- super.onResume();
- // 注册广播接收器
- registerReceiver(mTestChange, mIntentFilter);
- }
- private void refreshButton()
- {
- mMobileDataButton.setText(getMobileDataStatus() ? R.string.mobile_data_off : R.string.mobile_data_on);
- }
- //获取移动数据开关状态
- private boolean getMobileDataStatus()
- {
- String methodName = "getMobileDataEnabled";
- Class cmClass = mConnectivityManager.getClass();
- Boolean isOpen = null;
- try
- {
- Method method = cmClass.getMethod(methodName, null);
- isOpen = (Boolean) method.invoke(mConnectivityManager, null);
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- return isOpen;
- }
- // 通过反射实现开启或关闭移动数据
- private void setMobileDataStatus(boolean enabled)
- {
- try
- {
- Class<?> conMgrClass = Class.forName(mConnectivityManager.getClass().getName());
- //得到ConnectivityManager类的成员变量mService(ConnectivityService类型)
- Field iConMgrField = conMgrClass.getDeclaredField("mService");
- iConMgrField.setAccessible(true);
- //mService成员初始化
- Object iConMgr = iConMgrField.get(mConnectivityManager);
- //得到mService对应的Class对象
- Class<?> iConMgrClass = Class.forName(iConMgr.getClass().getName());
- /*得到mService的setMobileDataEnabled(该方法在android源码的ConnectivityService类中实现),
- * 该方法的参数为布尔型,所以第二个参数为Boolean.TYPE
- */
- Method setMobileDataEnabledMethod = iConMgrClass.getDeclaredMethod(
- "setMobileDataEnabled", Boolean.TYPE);
- setMobileDataEnabledMethod.setAccessible(true);
- /*调用ConnectivityManager的setMobileDataEnabled方法(方法是隐藏的),
- * 实际上该方法的实现是在ConnectivityService(系统服务实现类)中的
- */
- setMobileDataEnabledMethod.invoke(iConMgr, enabled);
- } catch (ClassNotFoundException e)
- {
- e.printStackTrace();
- } catch (NoSuchFieldException e)
- {
- e.printStackTrace();
- } catch (SecurityException e)
- {
- e.printStackTrace();
- } catch (NoSuchMethodException e)
- {
- e.printStackTrace();
- } catch (IllegalArgumentException e)
- {
- e.printStackTrace();
- } catch (IllegalAccessException e)
- {
- e.printStackTrace();
- } catch (InvocationTargetException e)
- {
- e.printStackTrace();
- }
- }
- @Override
- public void onClick(View v)
- {
- // TODO Auto-generated method stub
- if (getMobileDataStatus())
- {
- setMobileDataStatus(false);
- mMobileDataButton.setText(R.string.mobile_data_on);
- }
- else
- {
- setMobileDataStatus(true);
- mMobileDataButton.setText(R.string.mobile_data_off);
- }
- }
- private class TestChange extends BroadcastReceiver
- {
- @Override
- public void onReceive(Context context, Intent intent)
- {
- // TODO Auto-generated method stub
- String action = intent.getAction();
- if (NETWORK_CHANGE.equals(action))
- {
- Toast.makeText(MobileDataSwitchTest.this, "移动数据设置有改变",
- Toast.LENGTH_SHORT).show();
- }
- }
- }
- }
权限添加:
- <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
- <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
- <uses-permission android:name="android.permission.WRITE_APN_SETTINGS" />
8. 静音模式开关:
1). 静音模式由AudioManager控制实现,有三种状态:正常(有声音)、震动、静音
2). 当模式改变时,系统会向外界发送广播android.media.RINGER_MODE_CHANGED;
示例代码如下:
- package com.example.sst;
- import android.app.Activity;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- import android.content.IntentFilter;
- import android.media.AudioManager;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.Toast;
- public class SilentSwitchTes extends Activity implements OnClickListener
- {
- private AudioManager mAudioManager;
- private Button mSilentButton;
- private TestChange mTestChange;
- private IntentFilter mIntentFilter;
- //静音模式改变系统发送的广播
- public static final String RINGER_MODE_CHANGED = "android.media.RINGER_MODE_CHANGED";
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
- mTestChange = new TestChange();
- mIntentFilter = new IntentFilter();
- //添加广播接收器过滤的广播
- mIntentFilter.addAction("android.media.RINGER_MODE_CHANGED");
- mSilentButton = (Button)findViewById(R.id.silent);
- refreshButton();
- mSilentButton.setOnClickListener(this);
- }
- @Override
- protected void onDestroy()
- {
- // TODO Auto-generated method stub
- super.onDestroy();
- //解除广播接收器
- unregisterReceiver(mTestChange);
- }
- @Override
- protected void onResume() {
- // TODO Auto-generated method stub
- super.onResume();
- //注册广播接收器
- registerReceiver(mTestChange, mIntentFilter);
- }
- //更新按钮
- private void refreshButton()
- {
- switch (getSilentStatus())
- {
- case AudioManager.RINGER_MODE_SILENT:
- mSilentButton.setText(R.string.mode_vibrate);
- break;
- case AudioManager.RINGER_MODE_NORMAL:
- mSilentButton.setText(R.string.mode_silent);
- break;
- case AudioManager.RINGER_MODE_VIBRATE:
- mSilentButton.setText(R.string.mode_normal);
- break;
- }
- }
- //获取手机当前的静音模式状态
- private int getSilentStatus()
- {
- return mAudioManager.getRingerMode();
- }
- //设置手机的静音、正常、震动模式
- private void setSilentMode()
- {
- switch (getSilentStatus())
- {
- case AudioManager.RINGER_MODE_SILENT:
- mAudioManager.setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
- break;
- case AudioManager.RINGER_MODE_NORMAL:
- mAudioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
- break;
- case AudioManager.RINGER_MODE_VIBRATE:
- mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
- break;
- }
- }
- @Override
- public void onClick(View v)
- {
- // TODO Auto-generated method stub
- setSilentMode();
- }
- private class TestChange extends BroadcastReceiver
- {
- @Override
- public void onReceive(Context context, Intent intent)
- {
- // TODO Auto-generated method stub
- String action = intent.getAction();
- if (RINGER_MODE_CHANGED.equals(action))
- {
- refreshButton();
- Toast.makeText(SilentSwitchTes.this, "静音模式设置有改变", Toast.LENGTH_SHORT).show();
- }
- }
- }
- }
静音模式开关设置不需要添加权限。
<-----以下的开关设置实现需要有系统的UID使用Platform的apk签名,否则是没有权限调用的,会报SecurityException异常----->
注:1). 可以不通过apk签名,直接在android源码下编译生成apk,再将apk安装到手机;
2). 如果手机有root权限,那么也不需要apk签名,直接通过adb工具将apk推到system/app目录下:操作指令为adb remount---->adb push xxx.apk system/app (注:该apk将做为系统应用)
9. GPS开关:
1). GPS开关设置的实现由Secure类的相关静态方法实现。
2).Secure的isLocationProviderEnabled和setLocationProviderEnabled调用需要APK签名;
示例代码如下:
- package com.example.gst;
- import android.app.Activity;
- import android.content.Context;
- import android.location.LocationManager;
- import android.os.Bundle;
- import android.provider.Settings.Secure;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- public class GpsSwitchTest extends Activity implements OnClickListener
- {
- private Button mGpsButton;
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- mGpsButton = (Button)findViewById(R.id.gps);
- refreshButton();
- mGpsButton.setOnClickListener(this);
- }
- //根据当前的Gps状态,初始化按钮的显示
- private void refreshButton()
- {
- mGpsButton.setText(getGpsStatus(this) ? R.string.gps_off : R.string.gps_on);
- }
- //获取Gps开启或关闭状态
- private boolean getGpsStatus(Context context)
- {
- boolean status = Secure.isLocationProviderEnabled(context.getContentResolver(),
- LocationManager.GPS_PROVIDER);
- return status;
- }
- //打开或关闭Gps
- private void setGpsStatus(Context context, boolean enabled)
- {
- Secure.setLocationProviderEnabled(context.getContentResolver(),
- LocationManager.GPS_PROVIDER, enabled);
- }
- @Override
- public void onClick(View v)
- {
- // TODO Auto-generated method stub
- if (getGpsStatus(this))
- {
- setGpsStatus(this, false);
- mGpsButton.setText(R.string.gps_on);
- }
- else
- {
- setGpsStatus(this, true);
- mGpsButton.setText(R.string.gps_off);
- }
- }
- }
权限添加:
- <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
- <uses-permission android:name="android.permission.WRITE_SETTINGS" />
- <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
10. 锁屏:
1). 手机进入锁屏主要由PowerManager的goToSleep函数实现。
2). PowerManager的goToSleep调用需要apk签名。
示例代码:
- package com.example.lsst;
- import android.app.Activity;
- import android.content.Context;
- import android.os.Bundle;
- import android.os.PowerManager;
- import android.os.SystemClock;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- public class LockScreenSwitchTest extends Activity implements OnClickListener
- {
- private PowerManager mPowerManager;
- private Button mLockButton;
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
- mLockButton = (Button)findViewById(R.id.lock);
- mLockButton.setOnClickListener(this);
- }
- private void lockScreen()
- {
- //强制手机进入锁屏,这时候手机会灭屏,点亮后是处于锁屏状态
- mPowerManager.goToSleep(SystemClock.uptimeMillis());
- }
- @Override
- public void onClick(View v)
- {
- // TODO Auto-generated method stub
- lockScreen();
- }
- }
权限添加:
- <uses-permission android:name="android.permission.USES_POLICY_FORCE_LOCK" />
- <uses-permission android:name="android.permission.DEVICE_POWER" />
11. 重启:
1). 手机重启需要调用PowerManager的reboot方法实现,参数为null;
2). 该方法的调用,需要有系统的UID使用Platform的APK签名,否则是没有权限调用的,会报SecurityException异常。
示例代码如下:
- package com.example.rs;
- import android.app.Activity;
- import android.content.Context;
- import android.os.Bundle;
- import android.os.PowerManager;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- public class RebootSwitch extends Activity implements OnClickListener
- {
- private Button mRebootButton;
- private PowerManager mPowerManager;
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- mPowerManager = (PowerManager)getSystemService(Context.POWER_SERVICE);
- mRebootButton = (Button)findViewById(R.id.reboot);
- mRebootButton.setOnClickListener(this);
- }
- private void reboot(String reason)
- {
- mPowerManager.reboot(null);
- }
- @Override
- public void onClick(View v)
- {
- // TODO Auto-generated method stub
- reboot(null);
- }
- }
权限添加:
- <uses-permission android:name="android.permission.REBOOT"/>
12. 关机:
1). 手机关机直接通过创建相关的Intent来启动一个对话框,根据对话框的确认或取消键来选择是否关机
2). 关机实现需要apk签名。
示例代码如下:
- package com.example.sds;
- import android.app.Activity;
- import android.content.Intent;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- public class ShutDownSwitch extends Activity implements OnClickListener
- {
- private Button mShutDown;
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- mShutDown = (Button)findViewById(R.id.shutdown);
- mShutDown.setOnClickListener(this);
- }
- @Override
- public void onClick(View v)
- {
- // TODO Auto-generated method stub
- Intent intent = new Intent("android.intent.action.ACTION_REQUEST_SHUTDOWN");
- intent.putExtra("android.intent.extra.KEY_CONFIRM", true);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- //弹出系统内置的对话框,选择确定关机或取消关机
- startActivity(intent);
- }
- }
权限添加:
- <uses-permission android:name="android.permission.SHUTDOWN" />
ok,本文的快捷开关代码实现介绍就到此结束,有了上面这些快捷开关的实现代码,那么当你想要开发一个AppWidget来承载和实现这些开关时就容易多了,至于如何去开发一个AppWidget,有兴趣的读者可以去找找相关这些方面的资料。
相关代码下载链接:http://download.csdn.net/detail/stevenhu_223/5572751
转载自:http://blog.csdn.net/stevenhu_223/article/details/9052083
Android快捷开关实现(转)的更多相关文章
- Android下拉快捷设置面板添加快捷开关流程
快速设定面板上快捷开关的加载流程,包括图标等的加载和点击事件等的处理过程,以及创建一个快捷开关的主要过程(以增加一个锁屏开关为例).本文所讨论的Android版本为5.1. 快捷开关的加载流程 资源模 ...
- Android源码分析(十三)----SystemUI下拉状态栏如何添加快捷开关
一:如何添加快捷开关 源码路径:frameworks/base/packages/SystemUI/res/values/config.xml 添加headset快捷开关,参考如下修改. Index: ...
- Android快捷便利但不常被使用的原生工具类
Android快捷便利但不常被使用的原生工具类 Android SDK原生 API中,有一些常用的工具类,运用得当可以省事省力省时,何况还是Android官方提供的,现在收集整理一些出来.DateUt ...
- Android系统设置Android adb 开关的方法【转】
本文转载自:http://www.wxtlife.com/2015/11/24/Android-set-adb-status/ 想第一时间获取我的最新文章,请关注公众号: 技术特工队 在整机系统开发中 ...
- android快捷开发之Retrofit网络加载框架的简单使用
大家都知道,安卓最大的特点就是开源化,这自然会产生很多十分好用的第三方API,而基本每一个APP都会与网络操作和缓存处理机制打交道,当然,你可以自己通过HttpUrlConnection再通过返回数据 ...
- android快捷简单的实现音乐播放器
自己做了一个相对完整的音乐播放器,现在把播放模块提取出来,分享给大家.音乐播放器基本功能都实现了的,可能有些BUG,希望谅解. 播放器功能如下: 1.暂停,播放 2.拖动条实现,快进,快退 3.歌词同 ...
- Android快捷支付SDK Demo resultStatus={4001};memo={參数错误};result={}问题
在支付宝中粘贴RSA公钥并提交,然后问题就完美攻克了...
- android 快捷技巧
快捷方式 <!--[if !supportLists]-->0. Ctrl + 1 (快速修复) <!--[if !supportLists]-->1. Ctrl + D (删 ...
- android开关控件Switch和ToggleButton
序:今天项目中用到了开关按钮控件,查阅了一些资料特地写了这篇博客记录下. 1.Switch <Switch android:id="@+id/bt" android:layo ...
随机推荐
- DedeCMS全版本通杀SQL注入漏洞利用代码
EXP: Exp:plus/recommend.php?action=&aid=1&_FILES[type][tmp_name]=\' or mid=@`\'` /*!50000u ...
- (转)DoDataExchange执行时机
void CRegisterDialog::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DAT ...
- Linux中表示“时间”的结构体和相关函数
转载于:http://blog.chinaunix.net/uid-25909722-id-2827364.html Linux中表示“时间”的结构体和相关函数 2011-09-13 17: ...
- Serenity框架官方文档翻译(1-2开始、安装和界面)
1.开始 最好的和最快速地上手Serenity的方法是使用SERENE,它是一个示例应用程序模板. 您有2个选项来安装SERENE 模板到您的Visual Studio: 从Visual Studio ...
- 调用{dede:likewords}为dedecms添加相关搜索词
经常看到一些大型的网站会设置相关搜索,即使访客搜索的内容在本站暂时没有,它们也会展示一些其他搜索关键词,引导用户去点击查看,增加pv,提高用户体验:如果没有这些相关搜索,游客没有找到自己想要的内容就直 ...
- [转]结合轮廓显示,实现完整的框选目标(附Demo代码)
原地址:http://www.cnblogs.com/88999660/articles/2887078.html 几次看见有人问框选物体的做法,之前斑竹也介绍过,用画的框生成的视椎,用经典图形学的视 ...
- xcode arc引起的autorelease报错问题
http://blog.csdn.net/xiechengfa/article/details/37971223 自从用上了真苹果,一直升级,现在xcode版本是4.4,或者说是ios5 一直有个问题 ...
- apache ab压力测试报错(apr_socket_recv: Connection reset by peer (104))
apache ab压力测试报错(apr_socket_recv: Connection reset by peer (104)) 今天用apache 自带的ab工具测试,当并发量达到1000多的时 ...
- Firefox上Web开发工具库一览
Firefox的目标之一就是尽可能地使web开发者的生活更简单高效,并通过提供工具和具有很强扩展性的浏览器使人们创造出神奇的东西.使web开发者使用Firefox的时候,浏览器可以提供大量开发工具和选 ...
- 做网站用UTF-8还是GB2312 & 各国语言对应字符集
经常我们打开外国网站的时候出现乱码,又或者打开很多非英语的外国网站的时候,显示的都是口口口口口的字符, WordPress程序是用的UTF-8,很多cms用的是GB2312. ● 为什么有这么多编码? ...