安卓应用开发的权限可以分为三个大类:普通权限、危险权限和特殊权限。
- 普通权限:
普通权限不涉及用户隐私,任何应用都可以随意使用,不需要用户授权,例如:
- android.permission.INTERNET:访问互联网;
- android.permission.ACCESS_NETWORK_STATE:获取网络状态;
- android.permission.VIBRATE:控制震动;
- android.permission.ACCESS_WIFI_STATE:获取wifi状态。
- 危险权限:
危险权限涉及到用户隐私信息,需要用户授权才能使用,例如:
- android.permission.READ_PHONE_STATE:读取电话状态;
- android.permission.CAMERA:使用照相机;
- android.permission.RECORD_AUDIO:录制音频;
- android.permission.READ_EXTERNAL_STORAGE:读取外部存储中的内容;
- android.permission.ACCESS_FINE_LOCATION:获取精确定位信息等。
在应用运行时,当需要使用危险权限时,需要调用系统API,弹出权限对话框,提示用户授权使用对应的权限,例如:
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 1);
}
- 特殊权限:
特殊权限是Android系统针对某些特殊场景开放的权限,一般只有系统应用才能申请使用,例如:
- android.Manifest.permission.INSTALL_PACKAGES:安装应用程序包;
- android.Manifest.permission.REBOOT:重启设备;
- android.Manifest.permission.CLEAR_APP_CACHE:清除应用缓存等。
需要注意的是,权限管理是一项非常重要的工作,不当的权限使用可能会导致严重的信息泄露或数据损失。在使用权限时,应该经过谨慎的评估,遵循最小权限原则,只申请必需的权限,并向用户十分明确地说明其使用目的。
除了权限分类,以下是一些常见的权限理解和实际应用代码示例:
- READ_PHONE_STATE 权限
这个权限用来获取设备的IMEI、IMSI、运营商、网络类型等信息。
TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
String imei = tm.getDeviceId();
String imsi = tm.getSubscriberId();
int networkType = tm.getNetworkType();
需要注意的是,READ_PHONE_STATE权限属于危险权限,需要通过运行时动态申请权限。
- CAMERA 权限
这个权限用来打开设备相机进行拍照或拍视频。
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(intent, REQUEST_IMAGE_CAPTURE);
}
需要注意的是,打开相机之前需要先申请CAMERA权限。
- READ_EXTERNAL_STORAGE/ WRITE_EXTERNAL_STORAGE 权限
这个权限用来读写设备外部存储的文件,例如读取照片、音乐、视频等文件。
String path = Environment.getExternalStorageDirectory().getPath() + "/Pictures/test.jpg";
File file = new File(path);
if (file.exists()) {
// do something
}
需要注意的是,读写外部存储的文件也属于危险权限,在需要使用时需要先申请权限。
- ACCESS_FINE_LOCATION 权限
这个权限用来获取设备精确的地理位置信息。
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
String provider = locationManager.getBestProvider(criteria, true);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// request location permission
return;
}
Location location = locationManager.getLastKnownLocation(provider);
if (location != null) {
double latitude = location.getLatitude();
double longitude = location.getLongitude();
}
需要注意的是,精确获取设备位置信息也属于危险权限,在需要使用时需要先申请权限。
- RECORD_AUDIO 权限
这个权限用来录制音频。
MediaRecorder recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile(outputFile);
try {
recorder.prepare();
recorder.start();
} catch (IOException e) {
e.printStackTrace();
}
需要注意的是,录制音频也属于危险权限,在需要使用时需要先申请权限。
- ACCESS_WIFI_STATE 权限
这个权限用来获取设备当前连接的WIFI信息。
WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
if (!wifiManager.isWifiEnabled()) {
wifiManager.setWifiEnabled(true);
}
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
String ssid = wifiInfo.getSSID();
int rssi = wifiInfo.getRssi();
需要注意的是,获取WIFI信息不属于危险权限,无需申请权限。
- READ_CONTACTS 权限
这个权限用来读取设备联系人列表。
ContentResolver cr = getContentResolver();
Cursor cursor = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
if(cursor.moveToFirst()) {
do {
String id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
Cursor phones = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + id, null, null);
if (phones.moveToFirst()) {
do {
String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
} while (phones.moveToNext());
}
} while (cursor.moveToNext());
}
需要注意的是,读取联系人列表也属于危险权限,在需要使用时需要先申请权限。
- GET_ACCOUNTS 权限
这个权限用来获取设备上已登录的账户列表。
AccountManager accountManager = AccountManager.get(this);
Account[] accounts = accountManager.getAccounts();
for (Account account : accounts) {
String name = account.name;
String type = account.type;
}
需要注意的是,获取账户列表也属于危险权限,在需要使用时需要先申请权限。
- READ_SMS/ SEND_SMS/ RECEIVE_SMS 权限
这些权限用来读取短信、发送短信、接收短信等操作。
SmsManager smsManager = SmsManager.getDefault();
String message = "hello";
String destination = "10010";
smsManager.sendTextMessage(destination, null, message, null, null);
需要注意的是,短信相关操作也属于危险权限,在需要使用时需要先申请权限。
- BLUETOOTH 权限
这个权限用来开启设备蓝牙功能。
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (!bluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
需要注意的是,开启蓝牙功能不属于危险权限,无需申请权限。
- ACCESS_NETWORK_STATE 权限
这个权限用来获取设备网络状态信息,例如是否有网络连接等。
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
// has network connection
}
需要注意的是,获取网络状态信息不属于危险权限,无需申请权限。
- INTERNET 权限
这个权限用来访问网络,例如发送HTTP请求等。
URL url = new URL("https://www.example.com");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
try {
InputStream in = urlConnection.getInputStream();
// do something with input stream
} finally {
urlConnection.disconnect();
}
需要注意的是,访问网络属于危险权限,需要在AndroidManifest.xml文件中声明。
- ACCESS_COARSE_LOCATION 权限
这个权限用来获取设备粗略的地理位置信息。
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_COARSE);
String provider = locationManager.getBestProvider(criteria, true);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// request location permission
return;
}
Location location = locationManager.getLastKnownLocation(provider);
if (location != null) {
double latitude = location.getLatitude();
double longitude = location.getLongitude();
}
需要注意的是,获取设备粗略地理位置信息也属于危险权限,在需要使用时需要先申请权限。
- READ_EXTERNAL_STORAGE/ WRITE_EXTERNAL_STORAGE 权限
这些权限用来读取和写入外部存储器中的文件。
File file = new File(Environment.getExternalStorageDirectory(), "my_file.txt");
try {
FileOutputStream fos = new FileOutputStream(file);
String content = "Hello world";
fos.write(content.getBytes());
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
FileInputStream fis = new FileInputStream(file);
BufferedReader reader = new BufferedReader(new InputStreamReader(fis));
String line;
while ((line = reader.readLine()) != null) {
Log.d(TAG, line);
}
fis.close();
需要注意的是,涉及到外部存储器中的文件读写属于危险行为,在需要使用时需要先申请权限。
- ACCESS_FINE_LOCATION 权限
这个权限用来获取设备精准的地理位置信息。
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
String provider = locationManager.getBestProvider(criteria, true);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// request location permission
return;
}
Location location = locationManager.getLastKnownLocation(provider);
if (location != null) {
double latitude = location.getLatitude();
double longitude = location.getLongitude();
}
需要注意的是,获取设备精准地理位置信息也属于危险权限,在需要使用时需要先申请权限。
以上是另外几个常见权限的理解和使用示例,需要注意的是,在应用开发中,需要仔细评估每个权限的必要性,并根据具体业务场景合理使用权限,以保障用户隐私和数据安全。