(调用系统电话薄)运行时权限的基本使用
GitHub項目地址:
https://github.com/Skymqq/RuntimePermissionTest.git
運行時權限是Android6.0系統引入的新特性,那么為何要引入這種運行時權限的機制呢?這是為了保障用戶的安全和隱私,如果系統聲明了某些危險權限,而這個時候用戶卻一點都不知曉,這就顯得很不人性化,如果在程序安裝界面,彈出一個對話框來通知用戶,是否允許當前程序擁有一些權限。這就是運行時權限最常用的場景。
下面我們新建一個RuntimePermissionTest項目來實現調用系統電話薄的功能,期間通過運行時權限功能來讓我們抉擇是否允許聲明打電話的權限。
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是系統內置的打電話的動作intent.setData(Uri.parse("tel:10086"));//tel是協議,10086是號碼startActivity(intent);}});} catch (Exception e) {e.printStackTrace();}} }可以看到,在按鈕的點擊事件中,我們構建了一個隱式Intent,Intent的action指定為Intent.ACTION_CALL,這是一個系統內置的打電話的動作,然后在data部分指定了協議是tel,號碼是10086.另外為了防止程序崩潰,我們將所有操作都放在了異常捕獲代碼塊當中。
最后在AndroidManifest中聲明權限:
<?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>運行程序后,如果你的設備是6.0以下的版本,那么在你點擊Make Call按鈕后,程序會直接打開電話薄,如果你的設備室6.0以上版本,那么你的程序會打不開電話薄,同時會報錯“Permission Denial”,這是由于權限被禁止所導致的,因為6.0以上系統在使用危險權限時,都必須進行運行時權限處理。
那么下面我們就來嘗試著修復這個問題,修改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是系統內置的打電話的動作intent.setData(Uri.parse("tel:10086"));//tel是協議,10086是號碼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:}} }上面的代碼將運行時權限的完整流程都覆蓋了,下面我們來具體解析一下。說白了,運行時權限的核心就是在程序運行的過程中由用戶授權我們去執行某些危險操作,程序是不可以擅自做主去執行這些危險操作的。因此,第一步就是要先判斷用戶是不是已經給過我們授權了,借助的是ContextCompat.checkSelfPermission()。checkSelfPermission方法接收兩個參數,第一個參數是Context,這個沒什么好說的,第二個參數是具體的權限名,比如打電話的權限名就是 Manifest.permission.CALL_PHONE,然后我們使用方法的返回值和PackManager.PERMISSION_GRANTED做比較,如果值相等就說明用戶已經授權,如果不相等就表示用戶沒有授權。
如果已經授權就很簡單了,直接去執行撥打電話的邏輯操作就可以了,這里我們把撥打電話的邏輯封裝到了call()方法當中。如果沒有授權的話,則需要調用ActivityCompat.requestPermission()方法來向用戶申請授權,requestPermission()方法接收3個參數,第一個參數要求Activity的實例,第二個參數是一個String數組,我們把要申請的權限名放在數組中即可,第三個參數是請求碼,只要是唯一值就可以了,這里就傳入了個1.
調用玩了requestPermission()方法之后,系統會彈出一個權限申請的對話框,然后用戶可以選擇同意或拒絕我們的權限申請,不論是那種結果,最終都會回調到onRequestPermissionResult()方法中,而授權的結果則會封裝在grantResults參數當中。這里我們只需要判斷一下最后的授權結果,如果用戶同意的話就調用call()方法來撥打電話,如果用戶拒絕的話我們只能放棄操作,并且彈出一條拒絕權限的失敗提示。
運行程序:
點擊Make Call按鈕之后會彈出一個對話框,這個對話框是系統自帶的:
點擊允許后直接打開系統內置電話薄,并且撥打了10086:
?
如果你一開始點擊的拒絕,就會彈出Toast提示。如果你在允許授權之后,又希望取消授權撥打電話的權限,可以主動去設置里面將撥打電話的權限給取消就行了。
?
?
總結
以上是生活随笔為你收集整理的(调用系统电话薄)运行时权限的基本使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用LitePal操作数据库(CRUD增
- 下一篇: 运行时权限+读取系统联系人