获取手机基本信息
手机的基本信息分两类,一类是与电话有关的信息,另一类是设备自身的信息。
与电话有关的信息可由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开发笔记的完整目录