編輯:關於Android編程
視頻講解都已經錄了好幾天,但是最近實在抽不開身一直在忙Unity3D,就連光棍節都在寫,上次我們只是寫了Android 6.0 運行時權限處理解析,但是並未對其做代碼封裝,這一次我們做一個徹底的處理。
附視頻講解地址:http://pan.baidu.com/s/1bpqqkGn
2.1. 簡單例子
public class MainActivity extends AppCompatActivity { // 打電話權限申請的請求碼 private static final int CALL_PHONE_REQUEST_CODE = 0x0011; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } public void phoneClick(View view){ if(ContextCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED){ Toast.makeText(this, "申請權限", Toast.LENGTH_SHORT).show(); ActivityCompat.requestPermissions(this, new String[]{"Manifest.permission.CALL_PHONE"}, CALL_PHONE_REQUEST_CODE); }else { callPhone(); } } /** * 撥打電話 **/ private void callPhone() { Intent intent = new Intent(Intent.ACTION_CALL); Uri data = Uri.parse("tel:147****2514"); intent.setData(data); startActivity(intent); } @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if(requestCode == CALL_PHONE_REQUEST_CODE){ if (grantResults !=null&&grantResults[0] == PackageManager.PERMISSION_GRANTED) { // Permission Granted callPhone(); } else { // Permission Denied Toast.makeText(this,"權限被拒絕了",Toast.LENGTH_SHORT).show(); } } } }
這是從上一篇中復制過來的,並沒有做過任何處理,如果每次申請權限的地方都需要這麼做,那就比較麻煩了,那麼我們肯定要對phoneClick()和onRequestPermissionsResult()裡面的代碼進行處理,那麼要處理成什麼樣子?當然是所有的代碼都可以優化成一行,別人都這麼說的。
2.1. 確定方式
到底采用什麼方式去封裝,這個github上面有很多,中國人,日本人,韓國人各國人民都有,這個不是開完笑的真的都有,這裡我才用反射+注解的方式去實現。
2.2. 參數傳遞和傳遞方式
我們肯定要新建類,至於傳什麼參數? 第一個參數反射的類this,第二個參數請求碼用於監聽反饋處理,第三個參數傳請求權限的數組
利用什麼方式傳遞過去那麼?可以在工具類裡面寫一個靜態的方法一把塞過去。但是在這裡我們可以使用鏈式調用這種方式我們也經常使用,比如Okhttp,Gilde,甚至是Android的AlertDialog都是使用的這個方式,可以裝裝B
public class PermissionHelper { // 1. 傳什麼參數 // 1.1. Object Fragment or Activity 1.2. int 請求碼 1.3.需要請求的權限 string[] private Object mObject; private int mRequestCode; private String[] mRequestPermission; private PermissionHelper(Object object){ this.mObject = object; } // 2.已什麼的方式傳參數 // 2.1 直接傳參數 public static void requestPermission(Activity activity,int requestCode,String[] permissions){ PermissionHelper.with(activity).requestCode(requestCode). requestPermission(permissions).request(); } public static void requestPermission(Fragment fragment,int requestCode,String[] permissions){ PermissionHelper.with(fragment).requestCode(requestCode). requestPermission(permissions).request(); } // 2.2 鏈式的方式傳 // 傳Activity public static PermissionHelper with(Activity activity){ return new PermissionHelper(activity); } // 傳Fragment public static PermissionHelper with(Fragment fragment){ return new PermissionHelper(fragment); } // 添加一個請求碼 public PermissionHelper requestCode(int requestCode){ this.mRequestCode = requestCode; return this; } // 添加請求的權限數組 public PermissionHelper requestPermission(String... permissions){ this.mRequestPermission = permissions; return this; } /** * 3.1 真正判斷和發起請求權限 */ public void request() { // 3.2 首先判斷當前的版本是不是6.0 及以上 if(!PermissionUtils.isOverMarshmallow()){ // 3.3 如果不是6.0以上 那麼直接執行方法 反射獲取執行方法 // 執行什麼方法並不確定 那麼我們只能采用注解的方式給方法打一個標記, // 然後通過反射去執行。 注解 + 反射 執行Activity裡面的callPhone PermissionUtils.executeSucceedMethod(mObject,mRequestCode); return; } } }
2.2. 處理6.0以下的版本
對於6.0以下的版本,我們可以直接反射調用執行成功的方法,如果反射不太理解可以看一下這個視頻講解:http://pan.baidu.com/s/1bpqqkGn
/** * 執行成功的方法 */ public static void executeSucceedMethod(Object reflectObject, int requestCode) { // 獲取class中多有的方法 Method[] methods = reflectObject.getClass().getDeclaredMethods(); // 遍歷找我們打了標記的方法 for (Method method:methods){ Log.e("TAG",method+""); // 獲取該方法上面有沒有打這個成功的標記 PermissionSucceed succeedMethod = method.getAnnotation(PermissionSucceed.class); if(succeedMethod != null){ // 代表該方法打了標記 // 並且我們的請求碼必須 requestCode 一樣 int methodCode = succeedMethod.requestCode(); if(methodCode == requestCode){ // 這個就是我們要找的成功方法 // 反射執行該方法 Log.e("TAG","找到了該方法 :"+method); executeMethod(reflectObject,method); } } } } /** * 反射執行該方法 */ private static void executeMethod(Object reflectObject,Method method) { // 反射執行方法 第一個是傳該方法是屬於哪個類 第二個參數是反射方法的參數 try { method.setAccessible(true); // 允許執行私有方法 method.invoke(reflectObject,new Object[]{}); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } }
2.3. 處理6.0以上的版本
/** * 3.1 真正判斷和發起請求權限 */ public void request() { // 3.2 首先判斷當前的版本是不是6.0 及以上 if(!PermissionUtils.isOverMarshmallow()){ // 3.3 如果不是6.0以上 那麼直接執行方法 反射獲取執行方法 // 執行什麼方法並不確定 那麼我們只能采用注解的方式給方法打一個標記, // 然後通過反射去執行。 注解 + 反射 執行Activity裡面的callPhone PermissionUtils.executeSucceedMethod(mObject,mRequestCode); return; } // 3.3 如果是6.0以上 那麼首先需要判斷權限是否授予 // 需要申請的權限中 獲取沒有授予過得權限 ListdeniedPermissions = PermissionUtils.getDeniedPermissions(mObject,mRequestPermission); // 3.3.1 如果授予了 那麼我們直接執行方法 反射獲取執行方法 if(deniedPermissions.size() == 0){ // 全部都是授予過的 PermissionUtils.executeSucceedMethod(mObject,mRequestCode); }else { // 3.3.2 如果沒有授予 那麼我們就申請權限 申請權限 ActivityCompat.requestPermissions(PermissionUtils.getActivity(mObject), deniedPermissions.toArray(new String[deniedPermissions.size()]), mRequestCode); } }
2.4. 處理回調
如果用戶同意或是拒絕那麼會回調onRequestPermissionsResult(),我們肯定也需要對它做處理,這個方法就很簡單了:
/** * 處理申請權限的回調 */ public static void requestPermissionsResult(Object object,int requestCode, String[] permissions) { // 再次獲取沒有授予的權限 ListdeniedPermissions = PermissionUtils.getDeniedPermissions(object,permissions); if(deniedPermissions.size() == 0){ // 權限用戶都同意授予了 PermissionUtils.executeSucceedMethod(object,requestCode); }else{ // 你申請的權限中 有用戶不同意的 PermissionUtils.executeFailMethod(object,requestCode); } }
2.5. 最後的事例
public class MainActivity extends AppCompatActivity { // 打電話權限申請的請求碼 private static final int CALL_PHONE_REQUEST_CODE = 0x0011; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } public void phoneClick(View view){ PermissionHelper.with(this).requestCode(CALL_PHONE_REQUEST_CODE) .requestPermission(Manifest.permission.CALL_PHONE).request(); } @PermissionSucceed(requestCode = CALL_PHONE_REQUEST_CODE) private void callPhone() { Intent intent = new Intent(Intent.ACTION_CALL); Uri data = Uri.parse("tel:147****2514"); intent.setData(data); startActivity(intent); } @PermissionFail(requestCode = CALL_PHONE_REQUEST_CODE) private void callPhoneFail(){ Toast.makeText(this,"您拒絕了撥打電話", Toast.LENGTH_SHORT).show(); } @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { PermissionHelper.requestPermissionsResult(this, CALL_PHONE_REQUEST_CODE,permissions); } }
到最後再處理權限請求的時候會輕松很多,一行代碼解決問題,反正別人都這麼說,我們甚至可以把onRequestPermissionsResult()的處理寫到BaseActivity中,因為權限封裝我沒有把它寫入到基礎架構部分,這裡我就不處理了。
項目的代碼不能夠發給大家,裡面涉及到後台接口以及數據加密,如果大家感興趣可以看一下我錄的視頻:http://pan.baidu.com/s/1bpqqkGn 。
ListView 控件可使用四種不同視圖顯示項目。通過此控件,可將項目組成帶有或不帶有列標頭的列,並顯示伴隨的圖標和文本。最近在網上看到時間軸的布局效果,嘗試按照這個原理
這篇博客為大家介紹一個android常見的功能——ListView下拉刷新:首先下拉未松手時候手機顯示這樣的界面:下面的代碼是自定的扎樣的控件:<span >
雖然隨著RecyclerView的不斷普及,相應的資源也越來越多,許多的項目都在使用RecyclerView,但作為他的前輩ListView,加深對ListView的使用
一個Android項目包含了Android app代碼在內的所有文件。Android SDK工具提供默認的項目目錄和文件讓創建一個項目變得很簡單。 這篇課程會向大家展