編輯:關於Android編程
大家都知道Android 6.0的新特性之一就是應用權限的管理。也就是說凡是涉及用戶隱私的權限,用戶可以自己去設置管理了。然而在6.0以前,我們安裝一款APP是默認同意此APP所需的所有權限(比如定位、訪問通訊錄),不同意就不能安裝。當然,國內的一些手機廠商基於Android定制的系統中,可以實現在6.0以前關閉指定的權限。如下圖:
Dangerous Permission一般都是涉及用戶隱私的權限。
從上面的圖片中可以看到,攝像頭、電話、定位等等都是我們平常開發中常用的權限。
答案是可以,但是不推薦。
首先說怎麼不適配,那就是設置targetSdkVersion小於23(Android 6.0系統默認為targetSdkVersion小於23的應用默認授予了所申請的所有權限,所以如果您APP設置的targetSdkVersion低於23,在運行時也不會崩潰。)
有人一看這不是挺好的嘛,解決問題。那麼我想告訴你,首先這不是長久之計,早晚都要面對的。你不可能永遠targetSdkVersion低於23。其次,它是有一個前提,那就是用戶自己不去操作權限。要知道如果用戶是6.0以上的手機,他可以自己在設置中關閉權限,那麼到時APP因為沒有權限獲取數據異常,導致空指針的異常時,APP就會崩潰。
首先Android Studio:
在build.gradle中聲明targetSdkVersion為23及以上。
Eclipse:
在AndroidManifest.xml中聲明targetSdkVersion為23及以上。
這裡引用高德定位Demo的CheckPermissionsActivity類,代碼如下:
/** * 繼承了Activity,實現Android6.0的運行時權限檢測 * 需要進行運行時權限檢測的Activity可以繼承這個類 * * @創建時間:2016年5月27日 下午3:01:31 * @項目名稱: AMapLocationDemo * @author hongming.wang * @文件名稱:PermissionsChecker.java * @類型名稱:PermissionsChecker * @since 2.5.0 */ public class CheckPermissionsActivity extends Activity implements ActivityCompat.OnRequestPermissionsResultCallback { /** * 需要進行檢測的權限數組 */ protected String[] needPermissions = { Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.READ_PHONE_STATE }; private static final int PERMISSON_REQUESTCODE = 0; /** * 判斷是否需要檢測,防止不停的彈框 */ private boolean isNeedCheck = true; @Override protected void onResume() { super.onResume(); if(isNeedCheck){ checkPermissions(needPermissions); } } /** * * @param needRequestPermissonList * @since 2.5.0 * requestPermissions方法是請求某一權限, */ private void checkPermissions(String... permissions) { ListneedRequestPermissonList = findDeniedPermissions(permissions); if (null != needRequestPermissonList && needRequestPermissonList.size() > 0) { ActivityCompat.requestPermissions(this, needRequestPermissonList.toArray( new String[needRequestPermissonList.size()]), PERMISSON_REQUESTCODE); } } /** * 獲取權限集中需要申請權限的列表 * * @param permissions * @return * @since 2.5.0 * checkSelfPermission方法是在用來判斷是否app已經獲取到某一個權限 * shouldShowRequestPermissionRationale方法用來判斷是否 * 顯示申請權限對話框,如果同意了或者不在詢問則返回false */ private List findDeniedPermissions(String[] permissions) { List needRequestPermissonList = new ArrayList (); for (String perm : permissions) { if (ContextCompat.checkSelfPermission(this, perm) != PackageManager.PERMISSION_GRANTED) { needRequestPermissonList.add(perm); } else { if (ActivityCompat.shouldShowRequestPermissionRationale( this, perm)) { needRequestPermissonList.add(perm); } } } return needRequestPermissonList; } /** * 檢測是否所有的權限都已經授權 * @param grantResults * @return * @since 2.5.0 * */ private boolean verifyPermissions(int[] grantResults) { for (int result : grantResults) { if (result != PackageManager.PERMISSION_GRANTED) { return false; } } return true; } /** * 申請權限結果的回調方法 */ @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] paramArrayOfInt) { if (requestCode == PERMISSON_REQUESTCODE) { if (!verifyPermissions(paramArrayOfInt)) { showMissingPermissionDialog(); isNeedCheck = false; } } } /** * 顯示提示信息 * * @since 2.5.0 * */ private void showMissingPermissionDialog() { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("提示"); builder.setMessage("當前應用缺少必要權限。請點擊\"設置\"-\"權限\"-打開所需權限。"); // 拒絕, 退出應用 builder.setNegativeButton("取消", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { finish(); } }); builder.setPositiveButton("設置", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { startAppSettings(); } }); builder.setCancelable(false); builder.show(); } /** * 啟動應用的設置 * * @since 2.5.0 * */ private void startAppSettings() { Intent intent = new Intent( Settings.ACTION_APPLICATION_DETAILS_SETTINGS); intent.setData(Uri.parse("package:" + getPackageName())); startActivity(intent); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if(keyCode == KeyEvent.KEYCODE_BACK){ this.finish(); return true; } return super.onKeyDown(keyCode, event); } }
我在上面的類中,自己加入了一些注釋,大家仔細看就可以明白了。
當然不止上面一種實現方法,github上有許多大神開源的封裝庫,可以很方便的實現權限適配。我推薦兩個庫,大家根據需求選擇:
1. PermissionsDispatcher
2. 鴻洋大神的MPermissions
可以使用該套 SDK開發適用於Android系統移動設備的地圖應用,通過調用地圖SDK接口,您可以輕松訪問百度地圖服務和數據,構建功能豐富、交互性強的LBS(地圖類)應用
圓形頭像在我們的日常使用的app中很常見,因為圓形的頭像比較美觀.使用圓形圖片的方法可能有我們直接將圖片裁剪成圓形再在app中使用,還有就是使用自定義View對我們設置的
1.Socket簡介Socket也稱作“套接字“,是在應用層和傳輸層之間的一個抽象層,它把TCP/IP層復雜的操作抽象為幾個簡單的接口供應用層調用
前一章我們學習了FM的自動調頻,接下來我們就看看FM手動調頻是如何進行的。如果不清楚FM自動調頻的過程,請打開超鏈接查看FM搜索頻率流程。 首先來看一下流程圖: 2.滑