(调用系统电话薄)运行时权限的基本使用
GitHub項(xiàng)目地址:
https://github.com/Skymqq/RuntimePermissionTest.git
運(yùn)行時(shí)權(quán)限是Android6.0系統(tǒng)引入的新特性,那么為何要引入這種運(yùn)行時(shí)權(quán)限的機(jī)制呢?這是為了保障用戶的安全和隱私,如果系統(tǒng)聲明了某些危險(xiǎn)權(quán)限,而這個(gè)時(shí)候用戶卻一點(diǎn)都不知曉,這就顯得很不人性化,如果在程序安裝界面,彈出一個(gè)對(duì)話框來通知用戶,是否允許當(dāng)前程序擁有一些權(quán)限。這就是運(yùn)行時(shí)權(quán)限最常用的場(chǎng)景。
下面我們新建一個(gè)RuntimePermissionTest項(xiàng)目來實(shí)現(xiàn)調(diào)用系統(tǒng)電話薄的功能,期間通過運(yùn)行時(shí)權(quán)限功能來讓我們抉擇是否允許聲明打電話的權(quán)限。
activity_main.xml代碼:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><Buttonandroid:id="@+id/btn_call"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="Make Call"android:textAllCaps="false"android:textSize="18sp"android:textStyle="bold" /> </LinearLayout>MainActivity.java代碼:
package com.example.administrator.runtimepermissiontest;import android.content.Intent; import android.net.Uri; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button;public class MainActivity extends AppCompatActivity {private Button btn_call;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();//初始化UI控件}private void initView() {btn_call = (Button) findViewById(R.id.btn_call);}@Overrideprotected void onResume() {super.onResume();try {btn_call.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent(Intent.ACTION_CALL);//ACTION_CALL是系統(tǒng)內(nèi)置的打電話的動(dòng)作intent.setData(Uri.parse("tel:10086"));//tel是協(xié)議,10086是號(hào)碼startActivity(intent);}});} catch (Exception e) {e.printStackTrace();}} }可以看到,在按鈕的點(diǎn)擊事件中,我們構(gòu)建了一個(gè)隱式Intent,Intent的action指定為Intent.ACTION_CALL,這是一個(gè)系統(tǒng)內(nèi)置的打電話的動(dòng)作,然后在data部分指定了協(xié)議是tel,號(hào)碼是10086.另外為了防止程序崩潰,我們將所有操作都放在了異常捕獲代碼塊當(dāng)中。
最后在AndroidManifest中聲明權(quán)限:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.example.administrator.runtimepermissiontest"><uses-permission android:name="android.permission.CALL_PHONE" /><applicationandroid:allowBackup="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/AppTheme"><activity android:name=".MainActivity"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity></application></manifest>運(yùn)行程序后,如果你的設(shè)備是6.0以下的版本,那么在你點(diǎn)擊Make Call按鈕后,程序會(huì)直接打開電話薄,如果你的設(shè)備室6.0以上版本,那么你的程序會(huì)打不開電話薄,同時(shí)會(huì)報(bào)錯(cuò)“Permission Denial”,這是由于權(quán)限被禁止所導(dǎo)致的,因?yàn)?.0以上系統(tǒng)在使用危險(xiǎn)權(quán)限時(shí),都必須進(jìn)行運(yùn)行時(shí)權(quán)限處理。
那么下面我們就來嘗試著修復(fù)這個(gè)問題,修改MainActivity.java代碼,如下所示:
package com.example.administrator.runtimepermissiontest;import android.Manifest; import android.content.Intent; import android.content.pm.PackageManager; import android.net.Uri; import android.support.annotation.NonNull; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.Toast;public class MainActivity extends AppCompatActivity {private Button btn_call;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();//初始化UI控件}private void initView() {btn_call = (Button) findViewById(R.id.btn_call);}@Overrideprotected void onResume() {super.onResume();btn_call.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CALL_PHONE}, 1);} else {call();//打電話}}});}private void call() {try {Intent intent = new Intent(Intent.ACTION_CALL);//ACTION_CALL是系統(tǒng)內(nèi)置的打電話的動(dòng)作intent.setData(Uri.parse("tel:10086"));//tel是協(xié)議,10086是號(hào)碼startActivity(intent);} catch (Exception e) {e.printStackTrace();}}@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {switch (requestCode) {case 1:if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {call();//打電話} else {Toast.makeText(this, "You denied the permission", Toast.LENGTH_SHORT).show();}break;default:}} }上面的代碼將運(yùn)行時(shí)權(quán)限的完整流程都覆蓋了,下面我們來具體解析一下。說白了,運(yùn)行時(shí)權(quán)限的核心就是在程序運(yùn)行的過程中由用戶授權(quán)我們?nèi)?zhí)行某些危險(xiǎn)操作,程序是不可以擅自做主去執(zhí)行這些危險(xiǎn)操作的。因此,第一步就是要先判斷用戶是不是已經(jīng)給過我們授權(quán)了,借助的是ContextCompat.checkSelfPermission()。checkSelfPermission方法接收兩個(gè)參數(shù),第一個(gè)參數(shù)是Context,這個(gè)沒什么好說的,第二個(gè)參數(shù)是具體的權(quán)限名,比如打電話的權(quán)限名就是 Manifest.permission.CALL_PHONE,然后我們使用方法的返回值和PackManager.PERMISSION_GRANTED做比較,如果值相等就說明用戶已經(jīng)授權(quán),如果不相等就表示用戶沒有授權(quán)。
如果已經(jīng)授權(quán)就很簡(jiǎn)單了,直接去執(zhí)行撥打電話的邏輯操作就可以了,這里我們把撥打電話的邏輯封裝到了call()方法當(dāng)中。如果沒有授權(quán)的話,則需要調(diào)用ActivityCompat.requestPermission()方法來向用戶申請(qǐng)授權(quán),requestPermission()方法接收3個(gè)參數(shù),第一個(gè)參數(shù)要求Activity的實(shí)例,第二個(gè)參數(shù)是一個(gè)String數(shù)組,我們把要申請(qǐng)的權(quán)限名放在數(shù)組中即可,第三個(gè)參數(shù)是請(qǐng)求碼,只要是唯一值就可以了,這里就傳入了個(gè)1.
調(diào)用玩了requestPermission()方法之后,系統(tǒng)會(huì)彈出一個(gè)權(quán)限申請(qǐng)的對(duì)話框,然后用戶可以選擇同意或拒絕我們的權(quán)限申請(qǐng),不論是那種結(jié)果,最終都會(huì)回調(diào)到onRequestPermissionResult()方法中,而授權(quán)的結(jié)果則會(huì)封裝在grantResults參數(shù)當(dāng)中。這里我們只需要判斷一下最后的授權(quán)結(jié)果,如果用戶同意的話就調(diào)用call()方法來撥打電話,如果用戶拒絕的話我們只能放棄操作,并且彈出一條拒絕權(quán)限的失敗提示。
運(yùn)行程序:
點(diǎn)擊Make Call按鈕之后會(huì)彈出一個(gè)對(duì)話框,這個(gè)對(duì)話框是系統(tǒng)自帶的:
點(diǎn)擊允許后直接打開系統(tǒng)內(nèi)置電話薄,并且撥打了10086:
?
如果你一開始點(diǎn)擊的拒絕,就會(huì)彈出Toast提示。如果你在允許授權(quán)之后,又希望取消授權(quán)撥打電話的權(quán)限,可以主動(dòng)去設(shè)置里面將撥打電話的權(quán)限給取消就行了。
?
?
總結(jié)
以上是生活随笔為你收集整理的(调用系统电话薄)运行时权限的基本使用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用LitePal操作数据库(CRUD增
- 下一篇: 辽宁丹东抗美援朝纪念馆自助参观导引