這里我們以撥打電話申請權限來寫個小例子,也就是CALL_PHONE,因為撥打電話會涉及用戶手機的資費問題,因而被列為了危險權限,在Android6.0系統出現之前,撥打電話功能的實現其實非常簡單,修改activity_mainxml中的代碼,如下:
<?xml version="1.0" encoding="utf-8"?><android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.runtimepermissiontest.MainActivity"> <Button android:id="@+id/make_call" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Make Call" android:textAllCaps="false"/></android.support.constraint.ConstraintLayout>
我們在布局文件中只定義了一個按鈕,當點擊按鈕時就會去觸發撥打電話的邏輯,接著修改MainActivity中的代碼,如下:
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button makeCall = findViewById(R.id.make_call); makeCall.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { try { Intent intent = new Intent(Intent.ACTION_CALL); intent.setData(Uri.parse("tel:10000")); startActivity(intent); }catch (SecurityException e){ e.printStackTrace(); } } }); }}可以看到,在按鈕的點擊事件中,我們構建了一個隱式Intent,Intent的action指定為Intent.ACTION_CALL,這是一個系統內置的打電話的動作,然后在data部分指定了協議是tel,號碼是10000,表示打開撥號界面,這個是不需要聲明權限的,而Intent.ACTION_CALL則可以直接撥打電話,因此必須申明權限,另外為了防止程序崩潰,我們將所有操作都放在了異常捕獲代碼塊當中。
那么接下來修改AndroidManifest.xml文件,在其中聲明如下權限:
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.runtimepermissiontest"> <uses-permission android:name="android.permission.CALL_PHONE" /> <application android: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>
這樣我們就將撥打電話的功能實現了,并且在低于Android6.0系統的手機上都是可以正常運行的,但是如果我們在6.0或者更高版本系統的手機上運行,點擊Make Call按鈕就沒有任何效果,這時觀察logcat中的日志,會報如下錯誤:

錯誤信息中提示我們Permission Denial,可以看出,是由于權限被禁止所導致的,因為6.0及以上系統在使用危險權限時都必須進行運行時權限處理。
那么下面我們就來嘗試修復這個問題,修改MainActivity中的代碼,如下:
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button makeCall = findViewById(R.id.make_call); makeCall.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { 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); intent.setData(Uri.parse("tel:10000")); startActivity(intent); }catch (SecurityException e){ e.printStackTrace(); } } @Override public 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: break; } }}上面的代碼將運行權限的完成流程都覆蓋了,下面我們來具體解析一下,說白了,運行時權限的核心就是在程序運行過程中由用戶授權我們去執行某些危險操作,程序是不可以擅自做主去執行這些危險操作的,因此,第一步就是要去判斷用戶是不是已經給過我們授權了,借助的是ContextCompat.checkSelfPermission()方法,checkSelfPermission()方法接收兩個參數,第一個參數是Context,這個沒什么好說的,第二個參數是具體的權限名,比如打電話的權限名就是Manifest.permission.CALL_PHONE,然后使用方法的返回值和packageManager.PERMISSION_CRANTED做比較,相等就說明用戶已經授權,不等就表示用戶沒有授權。
如果已經授權的話就簡單了,直接去執行撥打電話的邏輯操作就可以了,這里我們把撥打電話的邏輯封裝到call()方法中,如果沒有授權的話,則需要調用ActivityCompat.requestPermissions()方法來向用戶申請授權,requestPermissions()方法接收3個參數,第一個參數要求是Activity的實例,第二個參數是一個String數組,我們把要申請的權限名放在數組中即可,第三個參數是請求碼,只要是唯一值就可以了,這里傳入1。
調用完了requestPermissions()方法之后,系統會彈出一個申請權限的對話框,然后用戶可以選擇同意或拒絕我們的權限申請,不論是哪種結果,最終都會回調到onRequestPermissionsResult()方法中,而授權的結果則封裝在grantResults參數當中,這里我們只需要判斷一下最后的授權結果,如果用戶同意的話就調用call()方法來撥打電話,如果用戶拒絕的話我們只能放棄操作,并且彈出一條失敗提示。
現在重新運行一下程序,并點擊Make Call按鈕,效果如圖:

由于用戶還沒有授權過我們撥打電話權限,因此第一次運行會彈出這樣一個權限申請的對話框,用戶可以選擇同意或者拒絕,比如說這里點擊了DENY,結果如圖:

由于用戶沒有同意授權,我們只能彈出一個操作失敗的提示,下面我們再次點擊Make Call,任然會彈出權限申請的對話框,這次點擊ALLOW,結果如圖:

可以看到,這次我們就成功進入到撥打電話界面了,并且由于用戶已經完成了授權操作,之后再點擊Make Call按鈕就不會再彈出權限申請對話框了,而是可以直接撥打電話,那可能你會擔心,萬一以后我又后悔了怎么辦?沒有關系,用戶隨時都可以將授予程序的危險權限進行關系,進入Settings-->Apps-->RuntimePermissiontTest-->Permissions,界面如圖:

在這里我們就可以對任何授予過的危險權限進行關閉了。
以上這篇Android 在程序運行時申請權限的實例講解就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持VEVB武林網。
新聞熱點
疑難解答