Android开发笔记(五十五)手机设备基本操作

获取手机基本信息

手机的基本信息分两类,一类是与电话有关的信息,另一类是设备自身的信息。
与电话有关的信息可由TelephonyManager类获得,常用的参数与对应的方法如下所示:
网络运营商名称 : getNetworkOperatorName
网络运营商编号 : getNetworkOperator,返回五位数字,前三位表示国家代码(中国的为460),后两位表示运营商代码(中国移动为0,中国联通为1,中国电信为2)
手机类型 : getPhoneType
网络类型 : getNetworkType获得细分类型,getNetworkClass获得大类如2G/3G/4G
SIM卡状态 : getSimState
SIM卡运营商名称 : getSimOperatorName
SIM卡运营商编号 : getSimOperator
SIM卡序列号 : getSimSerialNumber
IMSI : getSubscriberId
IMEI : getDeviceId
手机号码 : 实测发现多数情况下getLine1Number和getMsisdn都无法正确取到号码,但是很多APP又需要用户的手机号,那又得想办法获取号码,获取的方法大致有如下几种:
1、用户首次使用,提示用户注册手机号,然后保存起来,下次就能取到手机号了;
2、APP自动用该手机发一条免费短信(比如向10086发),然后到发件箱中寻找该短信的发送号码;
3、如果能连到运营商的支撑系统,那么根据IMSI去后台系统查询手机号,这也是可以的;

设备自身的信息可由Build类获得,常用的参数与对应的方法如下所示:
手机厂商 : Build.MANUFACTURER
手机品牌 : Build.BRAND
手机型号 : Build.MODEL
设备名称 : Build.DEVICE
CPU指令 : Build.CPU_ABI
芯片型号 : Build.HARDWARE
手机序列号 : Build.SERIAL
SDK版本 : Build.VERSION.SDK_INT
系统版本 : Build.VERSION.RELEASE
版本代号 : Build.VERSION.CODENAME


功能开关的查询与设置

常用的设备功能主要有:屏幕自动旋转、亮度自动调节、飞行模式开关、GPS开关、蓝牙开关、WLAN开关、数据连接开关、闪光灯/手电筒开关。各功能的设置途径各不相同,废话少说,直接上代码:
import java.lang.reflect.Method;

import android.annotation.TargetApi;
import android.app.PendingIntent;
import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.content.Intent;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.location.LocationManager;
import android.net.ConnectivityManager;
import android.net.Uri;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.util.Log;

//屏幕自动旋转、亮度自动调节、飞行模式开关、GPS开关、蓝牙开关、WLAN开关、数据连接开关、闪光灯/手电筒开关
public class SwitchUtil {
	private static final String TAG = "SwitchUtil";

	//获取屏幕的自动旋转状态
	public static boolean getRotationStatus(Context context) {
	    int status = 0;
	    try {
	        status = android.provider.Settings.System.getInt(context.getContentResolver(),
	                android.provider.Settings.System.ACCELEROMETER_ROTATION);
	    } catch (SettingNotFoundException e) {
            Log.d(TAG, "getRotationStatus error: "+e.getMessage());
	    }
	    return status==1?true:false;
	}

	//设置屏幕的自动旋转开关
	public static void setRotationStatus(Context context, boolean enabled) {
		int status = (enabled==true)?1:0;
	    Uri uri = android.provider.Settings.System.getUriFor("accelerometer_rotation");
	    android.provider.Settings.System.putInt(context.getContentResolver(), "accelerometer_rotation", status);
	    context.getContentResolver().notifyChange(uri, null);
	}

	//设置亮度自动调节的开关
	public static void setAutoBrightStatus(Context context, boolean enabled) {
		int screenMode = (enabled==true)?Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC
				:Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL;
	    Settings.System.putInt(context.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS_MODE,
	    		screenMode);
	}

	//获取亮度自动调节的状态
	public static boolean getAutoBrightStatus(Context context) {
		int screenMode = Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL;
		try {
			screenMode = Settings.System.getInt(context.getContentResolver(),
					Settings.System.SCREEN_BRIGHTNESS_MODE);
		} catch (Exception e) {
            Log.d(TAG, "getAutoBrightStatus error: "+e.getMessage());
		}
		return screenMode==Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC?true:false;
	}
	
	//获取飞行模式的开关状态
	public static boolean getAirplaneStatus(Context context) {
	    boolean status = Settings.System.getInt(context.getContentResolver(),
	            Settings.Global.AIRPLANE_MODE_ON, 0) == 1 ? true : false;
	    return status;
	}

	//开启或关闭飞行模式。注意只有系统应用才能发送广播,普通app发送广播会提示无权限
	@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
	public static void setAirplaneStatus(Context context, boolean enable) {
	    Settings.System.putInt(context.getContentResolver(),
	            Settings.Global.AIRPLANE_MODE_ON, enable ? 1 : 0);
	    Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
	    intent.putExtra("state", enable);
	    context.sendBroadcast(intent);
	}
	
	//获取Gps的开关状态
	public static boolean getGpsStatus(Context context) {
        LocationManager locationMgr = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
        boolean gps_enabled = locationMgr.isProviderEnabled(LocationManager.GPS_PROVIDER);
        return gps_enabled;
	}

	//打开或关闭Gps
	@TargetApi(Build.VERSION_CODES.KITKAT)
	public static void setGpsStatus(Context context, boolean enabled) {
        Intent gpsIntent = new Intent();
        gpsIntent.setClassName("com.android.settings",
                "com.android.settings.widget.SettingsAppWidgetProvider");
        gpsIntent.addCategory("android.intent.category.ALTERNATIVE");
        gpsIntent.setData(Uri.parse("custom:3"));
        try {
            PendingIntent.getBroadcast(context, 0, gpsIntent, 0).send();
        } catch (Exception e) {
            Log.d(TAG, "setGpsStatus error: "+e.getMessage());
        }  
	}

	//获取定位的开关状态
	public static boolean getLocationStatus(Context context) {
        LocationManager locationMgr = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
        boolean gps_enabled = locationMgr.isProviderEnabled(LocationManager.GPS_PROVIDER);
        boolean network_enabled = locationMgr.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
        return gps_enabled || network_enabled;
	}

	//获取蓝牙的开关状态
    public static boolean getBlueToothStatus(Context context) {
    	BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    	boolean enabled = false;
		switch (bluetoothAdapter.getState()) {
		case BluetoothAdapter.STATE_ON:
		case BluetoothAdapter.STATE_TURNING_ON:
			enabled = true;
			break;
		case BluetoothAdapter.STATE_OFF:
		case BluetoothAdapter.STATE_TURNING_OFF:
		default:
			enabled = false;
			break;
		}
    	return enabled;
    }

	//打开或关闭蓝牙
    public static void setBlueToothStatus(Context context, boolean enabled) {
    	BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    	if (enabled == true) {
    		bluetoothAdapter.enable();
    	} else {
    		bluetoothAdapter.disable();
    	}
    }

	//获取Wifi的开关状态
	public static boolean getWlanStatus(Context context) {
		WifiManager wifiMgr = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
		return wifiMgr.isWifiEnabled();
	}

	//打开或关闭Wifi
	public static void setWlanStatus(Context context, boolean enabled) {
		WifiManager wifiMgr = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
		wifiMgr.setWifiEnabled(enabled);
	}

	//获取数据连接的开关状态
	public static boolean getMobileDataStatus(Context context) {
		ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        boolean isOpen = false;
        try {
            String methodName = "getMobileDataEnabled";
            Method method = connMgr.getClass().getMethod(methodName);
            isOpen = (boolean) method.invoke(connMgr);
        } catch (Exception e) {
            Log.d(TAG, "getMobileDataStatus error: "+e.getMessage());
        }
        return isOpen;
	}

	//打开或关闭数据连接
	public static void setMobileDataStatus(Context context, boolean enabled) {
		ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        try {
            String methodName = "setMobileDataEnabled";
            Method method = connMgr.getClass().getMethod(methodName, Boolean.TYPE);
            //method.setAccessible(true);
            method.invoke(connMgr, enabled);
        } catch (Exception e) {
            Log.d(TAG, "setMobileDataStatus error: "+e.getMessage());
        }
	}

	//Camera对象需要做成单例模式,因为Camera不能重复打开
	private static Camera mCamera = null;
	//获取闪光灯/手电筒的开关状态
	public static boolean getFlashStatus(Context context) {
		if (mCamera == null) {
			mCamera = Camera.open();
		}
		Parameters parameters = mCamera.getParameters();
		String flashMode = parameters.getFlashMode();
		boolean enabled;
		if (flashMode.equals(Parameters.FLASH_MODE_TORCH)) {
			enabled = true;
		} else {
			enabled = false;
		}
		return enabled;
	}

	//打开或关闭闪光灯/手电筒
	public static void setFlashStatus(Context context, boolean enabled) {
		if (mCamera == null) {
			mCamera = Camera.open();
		}
		Parameters parameters = mCamera.getParameters();
		if (enabled == true) {
			parameters.setFlashMode(Parameters.FLASH_MODE_TORCH);// 开启
			mCamera.setParameters(parameters);
		} else {
			parameters.setFlashMode(Parameters.FLASH_MODE_OFF);// 关闭
			mCamera.setParameters(parameters);
			mCamera.release();
			mCamera = null;
		}
	}

}

看完了代码,总结一下功能开关的注意事项:
1、开启或关闭飞行模式,除了修改Settings,还得发送广播通知系统完成其他处理,因为开启飞行模式得同时关闭wifi、数据连接、蓝牙等功能。但是只有系统应用才能发送广播,普通app发送广播会提示无权限。
2、定位不等于GPS,定位包括GPS定位和网络定位,因此若要判断定位功能是否开启,得同时判断GPS定位和网络定位都不可用才是定位关闭。
3、开关闪光灯/手电筒借助了Camera类,不过Camera不能多次打开,否则会报错无效连接,所以在工具代码中要把Camera做成单例模式,确保每次使用Camera都只Open一次。


跳转到系统设置界面

上面可在代码中直接设置的仅仅是些基本的设备功能,还有更多的系统管理需要在专门的系统设置界面来完成。这些无法在我们代码中完成的工作,就得跳到系统设置页面,由用户去手工操作。下面是具体设置页面与Action的对应关系:
系统应用Settings中的设置
系统设置页面 : Settings.ACTION_SETTINGS
应用管理页面 : Settings.ACTION_APPLICATION_SETTINGS
存储管理页面 : Settings.ACTION_MEMORY_CARD_SETTINGS或者Settings.ACTION_INTERNAL_STORAGE_SETTINGS
显示设置页面 : Settings.ACTION_DISPLAY_SETTINGS
声音/铃声设置页面 : Settings.ACTION_SOUND_SETTINGS (有的手机是情景设置页面)
日期设置页面 : Settings.ACTION_DATE_SETTINGS
定位设置页面 : Settings.ACTION_LOCATION_SOURCE_SETTINGS
同步设置页面 : Settings.ACTION_SYNC_SETTINGS
输入法设置页面 : Settings.ACTION_INPUT_METHOD_SETTINGS
系统应用Phone中的设置
通话设置页面 : 按如下方式跳转(有的手机不在这个路径)
	Intent intent = new Intent(Intent.ACTION_MAIN);
	intent.setClassName("com.android.phone","com.android.phone.CallFeaturesSetting");
	startActivity(intent);



使用通讯功能

打电话/拨号

打电话调用系统的拨号应用即可,示例代码如下:
			Intent intent = new Intent();
			Uri uri = Uri.parse("tel:"+"15960238696");
			intent.setAction(Intent.ACTION_CALL);
			intent.setData(uri);
			startActivity(intent);


发短信

发短信有两种方式,分别是手工发送和自动发送,手工发送是调用系统的短消息应用,自动发送则是调用SmsManager的相关API。使用SmsManager类有三个注意点:
1、因手机短信有长度限制,故需对过长的短信内容进行拆分,具体是调用SmsManager类的divideMessage方法;
2、SmsManager同时支持短短信和长短信两种方式,发送短短信调用的是sendTextMessage方法,发送长短信调用的是sendMultipartTextMessage方法。长短信虽然在发送时也需要拆分,但对方收到的是一条完整的短信;另外,长短信方式可以只发送一次广播,而短短信方式每发一条短信就会发送一次广播。
3、如果需要处理短信发送成功通知事件和短信接收成功事件,则需确保打开发送短信的完全权限,不是那种还需提示的不完整权限,不然不但收不到广播,连短信都无法发送了。


发邮件

发邮件需要调用手机上的其他邮件客户端,如QQ邮箱,这样发送时在列表中选择QQ邮箱才能完成邮件发送操作,示例代码如下:
			Intent intent = new Intent(Intent.ACTION_SEND);
			String[] to = {"[email protected]"};
			String[] cc = {"[email protected]"};
			String[] bcc = {"[email protected]"};
			intent.putExtra(Intent.EXTRA_EMAIL, to);
			intent.putExtra(Intent.EXTRA_CC, cc);
			intent.putExtra(Intent.EXTRA_BCC, bcc);
			intent.putExtra(Intent.EXTRA_SUBJECT, "这里是邮件标题");
			intent.putExtra(Intent.EXTRA_TEXT, "这里是邮件内容");
			intent.setType("message/rfc822");
			startActivity(Intent.createChooser(intent, "请选择邮件客户端"));


代码例子

打电话、发短信、发邮件的完整代码例子如下:
import java.util.ArrayList;

import android.app.Activity;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.Bundle;
import android.telephony.PhoneNumberUtils;
import android.telephony.SmsManager;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class MobileActivity extends Activity implements OnClickListener {

	private static final String TAG = "MobileActivity";
	private TextView tv_send, tv_deliver;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_mobile);

		Button btn_dial = (Button) findViewById(R.id.btn_dial);
		Button btn_sms_manual = (Button) findViewById(R.id.btn_sms_manual);
		Button btn_sms_auto = (Button) findViewById(R.id.btn_sms_auto);
		Button btn_sms_long = (Button) findViewById(R.id.btn_sms_long);
		Button btn_email = (Button) findViewById(R.id.btn_email);
		btn_dial.setOnClickListener(this);
		btn_sms_manual.setOnClickListener(this);
		btn_sms_auto.setOnClickListener(this);
		btn_sms_long.setOnClickListener(this);
		btn_email.setOnClickListener(this);
		
		tv_send = (TextView) findViewById(R.id.tv_send);
		tv_deliver = (TextView) findViewById(R.id.tv_deliver);
	}

	@Override
	public void onClick(View v) {
		if (v.getId() == R.id.btn_dial) {
			Intent intent = new Intent();
			Uri uri = Uri.parse("tel:"+"15960238696");
			intent.setAction(Intent.ACTION_CALL);
			intent.setData(uri);
			startActivity(intent);
		} else if (v.getId() == R.id.btn_sms_manual) {
			sendSmsManual("15960238696", "我把短信丢过去就不管结果啦");
		} else if (v.getId() == R.id.btn_sms_auto) {
			sendSmsAuto("15960238696", "快来看看短信发成功了没有。快来看看短信发成功了没有。快来看看短信发成功了没有。快来看看短信发成功了没有。快来看看短信发成功了没有。快来看看短信发成功了没有。快来看看短信发成功了没有。", SMS_SHORT);
		} else if (v.getId() == R.id.btn_sms_long) {
			sendSmsAuto("15960238696", "快来看看短信发成功了没有。快来看看短信发成功了没有。快来看看短信发成功了没有。快来看看短信发成功了没有。快来看看短信发成功了没有。快来看看短信发成功了没有。快来看看短信发成功了没有。", SMS_LONG);
		} else if (v.getId() == R.id.btn_email) {
			Intent intent = new Intent(Intent.ACTION_SEND);
			String[] to = {"[email protected]"};
			String[] cc = {"[email protected]"};
			String[] bcc = {"[email protected]"};
			intent.putExtra(Intent.EXTRA_EMAIL, to);  //主送
			intent.putExtra(Intent.EXTRA_CC, cc);  //抄送
			intent.putExtra(Intent.EXTRA_BCC, bcc);  //密送
			intent.putExtra(Intent.EXTRA_SUBJECT, "这里是邮件标题");
			intent.putExtra(Intent.EXTRA_TEXT, "这里是邮件内容");
			intent.setType("message/rfc822");
			startActivity(Intent.createChooser(intent, "请选择邮件客户端"));
		}
	}

	public void sendSmsManual(String phoneNumber, String message) {
		if (PhoneNumberUtils.isGlobalPhoneNumber(phoneNumber)) {
			Intent intent = new Intent(Intent.ACTION_SENDTO, Uri.parse("smsto:"
					+ phoneNumber));
			intent.putExtra("sms_body", message);
			startActivity(intent);
		}
	}

	public void sendSmsAuto(String phoneNumber, String message, int type) {
		Intent sentIntent = new Intent(SENT_SMS_ACTION);
		sentIntent.putExtra(PHONE, phoneNumber);
		sentIntent.putExtra(MESSAGE, message);
		PendingIntent sentPI = PendingIntent.getBroadcast(this, 0, sentIntent, PendingIntent.FLAG_UPDATE_CURRENT);
		
		Intent deliverIntent = new Intent(DELIVERED_SMS_ACTION);
		deliverIntent.putExtra(PHONE, phoneNumber);
		deliverIntent.putExtra(MESSAGE, message);
		PendingIntent deliverPI = PendingIntent.getBroadcast(this, 1, deliverIntent, PendingIntent.FLAG_UPDATE_CURRENT);
		
		SmsManager smsManager = SmsManager.getDefault();
		// 拆分短信内容(手机短信长度限制)
		ArrayList<String> divideContents = smsManager.divideMessage(message);
		if (type == SMS_SHORT) {
			for (String text : divideContents) {
				//要确保打开发送短信的完全权限,不是那种还需提示的不完整权限
				smsManager.sendTextMessage(phoneNumber, null, text, sentPI, deliverPI);
			}
		} else if (type == SMS_LONG) {
			ArrayList<PendingIntent> sendPiArray = new ArrayList<PendingIntent>();
			sendPiArray.add(sentPI);
			ArrayList<PendingIntent> deliverPiArray = new ArrayList<PendingIntent>();
			deliverPiArray.add(deliverPI);
			//发送长短信使用方法sendMultipartTextMessage
			//长短信方式可以只发送一次广播,短短信方式每发一条短信就会发送一次广播
			smsManager.sendMultipartTextMessage(phoneNumber, null, divideContents, sendPiArray, deliverPiArray);
		}
	}

	private int SMS_SHORT=0, SMS_LONG=1;
	private String SENT_SMS_ACTION = "com.example.exmdevice.SENT_SMS_ACTION";
	private String DELIVERED_SMS_ACTION = "com.example.exmdevice.DELIVERED_SMS_ACTION";
	private String PHONE = "phone";
	private String MESSAGE = "message";
	
	@Override
	public void onStart() {
		super.onStart();
		sendReceiver = new SendReceiver();
		registerReceiver(sendReceiver, new IntentFilter(SENT_SMS_ACTION));
		deliverReceiver = new DeliverReceiver();
		registerReceiver(deliverReceiver, new IntentFilter(DELIVERED_SMS_ACTION));
	}

	@Override
	public void onStop() {
		unregisterReceiver(sendReceiver);
		unregisterReceiver(deliverReceiver);
		super.onStop();
	}

    private SendReceiver sendReceiver;
    private class SendReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
        	Log.d(TAG, "SendReceiver onReceive");
			switch (getResultCode()) {
			case Activity.RESULT_OK:
				String phone = intent.getStringExtra(PHONE);
				String message = intent.getStringExtra(MESSAGE);
				String desc = String.format("您的短信已发送成功。接收人为%s,短信内容为:%s", 
						phone, message);
				tv_send.setText(desc);
				break;
			case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
			case SmsManager.RESULT_ERROR_RADIO_OFF:
			case SmsManager.RESULT_ERROR_NULL_PDU:
				tv_send.setText("短信发送异常代码为"+getResultCode());
				break;
			}
        }
    }

    private DeliverReceiver deliverReceiver;
    private class DeliverReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
        	Log.d(TAG, "DeliverReceiver onReceive");
			if (intent != null) {
				String phone = intent.getStringExtra(PHONE);
				String message = intent.getStringExtra(MESSAGE);
				String desc = String.format("您的短信已成功接收。接收人为%s,短信内容为:%s", 
						phone, message);
				tv_deliver.setText(desc);
			}
        }
    }
    
}




权限申请

通过前面对设备的基本操作介绍,可看到Android四大组件各显神通,各组件协同配合完成了许多功能。具体的组件使用分类如下:
1、Activity:包括拨号(Intent.ACTION_CALL)、手工发短信(Intent.ACTION_SENDTO)、发邮件(Intent.ACTION_SEND)、系统设置页面(Settings.ACTION_SETTINGS)以及其他分项设置页面。
2、Service:包括获取子系统服务的管理器,如电话管理器TelephonyManager(Context.TELEPHONY_SERVICE)、定位管理器LocationManager(Context.LOCATION_SERVICE)、蓝牙管理器BluetoothAdapter(BLUETOOTH_MANAGER_SERVICE)、WLAN管理器WifiManager(Context.WIFI_SERVICE)、数据连接管理器ConnectivityManager(Context.CONNECTIVITY_SERVICE)。
3、Broadcast:包括开关飞行模式、开关GPS、自动发送短信的发送成功通知与接收成功通知。
4、ContentProvider:包括通过ContentResolver获取与开关的功能,如屏幕自动旋转、亮度自动调节、飞行模式等等。


由于操作设备涉及到一些系统层面与硬件层面的交互,因此需要给APP赋予相关的权限,这样才能合法的使用系统服务与硬件设施。本节中用到的权限主要有:
    <!-- 读取手机设置 -->
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <!-- 更改手机设置 -->
    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
    <!-- 定位 -->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <!-- 蓝牙 -->
    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    <!-- WLAN -->
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <!-- 数据连接 -->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
    <!-- 摄像头与闪光灯/手电筒 -->
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.FLASHLIGHT" />
    <!-- 拨号/打电话 -->
    <uses-permission android:name="android.permission.CALL_PHONE" />
    <!-- 发短信/收短信/写短信/读短信 -->
    <uses-permission android:name="android.permission.SEND_SMS" />
    <uses-permission android:name="android.permission.RECEIVE_SMS" />
    <uses-permission android:name="android.permission.WRITE_SMS" />
    <uses-permission android:name="android.permission.READ_SMS" />
    
    <!-- 下面是其他常用的权限 -->
    <!-- 上网 -->
    <uses-permission android:name="android.permission.INTERNET" />
    <!-- 震动 -->
    <uses-permission android:name="android.permission.VIBRATE" />
    <!-- 录像/录音 -->
    <uses-permission android:name="android.permission.RECORD_VIDEO"/>
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <!-- SD卡 -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
    <!-- 读写联系人 -->
    <uses-permission android:name="android.permission.READ_CONTACTS" />
    <uses-permission android:name="android.permission.WRITE_CONTACTS" />
    <!-- 读写通话记录 -->
    <uses-permission android:name="android.permission.READ_CALL_LOG"/>
    <uses-permission android:name="android.permission.WRITE_CALL_LOG"/>
    <!-- 接收开机广播 -->
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <!-- 无需通知的下载 -->
    <uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" />
    <!-- 允许Service服务弹出对话框 -->
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />






点此查看Android开发笔记的完整目录

你可能感兴趣的:(android,短信,smsmanager,拨号)