content: package com.wm.remusic.uitl;
  
  import android.Manifest;
  import android.app.Activity;
  import android.app.AlertDialog;
  import android.content.DialogInterface;
  import android.content.Intent;
  import android.content.pm.PackageManager;
  import android.net.Uri;
  import android.provider.Settings;
  import android.support.v4.app.ActivityCompat;
  import android.support.v4.content.ContextCompat;
  import android.util.Log;
  
  /**
   * Android 6.0 上权限分为<b>正常</b>和<b>危险</b>级别
   * <ul>
   * <li>正常级别权限：开发者仅仅需要在AndroidManifext.xml上声明，那么应用就会被允许拥有该权限，如：android.permission.INTERNET</li>
   * <li>危险级别权限：开发者需要在AndroidManifext.xml上声明，并且在运行时进行申请，而且用户允许了，应用才会被允许拥有该权限，如：android.permission.WRITE_EXTERNAL_STORAGE</li>
   * </ul>
   * 有米的以下权限需要在Android6.0上被允许，有米广告sdk才能正常工作，开发者需要在调用有米的任何代码之前，提前让用户允许权限
   * <ul>
   * <li>必须申请的权限
   * <ul>
   * <li>android.permission.READ_PHONE_STATE</li>
   * <li>android.permission.WRITE_EXTERNAL_STORAGE</li>
   * </ul>
   * </li>
   * <li>可选申请的权限
   * <ul>
   * <li>android.permission.ACCESS_FINE_LOCATION</li>
   * </ul>
   * </li>
   * </ul>
   * <p>Android 6.0 权限申请助手</p>
   * Created by Alian on 16-1-12.
   */
  public class PermissionHelper {
  
  	private static final String TAG = "PermissionHelper";
  
  	/**
  	 * 小tips:这里的int数值不能太大，否则不会弹出请求权限提示，测试的时候,改到1000就不会弹出请求了
  	 */
  	private final static int READ_PHONE_STATE_CODE = 101;
  
  	private final static int WRITE_EXTERNAL_STORAGE_CODE = 102;
  
  	private final static int REQUEST_OPEN_APPLICATION_SETTINGS_CODE = 12345;
  
  	/**
  	 * 有米 Android SDK 所需要向用户申请的权限列表
  	 */
  	private PermissionModel[] mPermissionModels = new PermissionModel[] {
  			new PermissionModel("电话", Manifest.permission.READ_PHONE_STATE, "我们需要读取手机信息的权限来标识您的身份", READ_PHONE_STATE_CODE),
  			new PermissionModel("存储空间", Manifest.permission.WRITE_EXTERNAL_STORAGE, "我们需要您允许我们读写你的存储卡，以方便我们临时保存一些数据",
  					WRITE_EXTERNAL_STORAGE_CODE)
  	};
  
  	private Activity mActivity;
  
  	private OnApplyPermissionListener mOnApplyPermissionListener;
  
  	public PermissionHelper(Activity activity) {
  		mActivity = activity;
  	}
  
  	public void setOnApplyPermissionListener(OnApplyPermissionListener onApplyPermissionListener) {
  		mOnApplyPermissionListener = onApplyPermissionListener;
  	}
  
  	/**
  	 * 这里我们演示如何在Android 6.0+上运行时申请权限
  	 */
  	public void applyPermissions() {
  		try {
  			for (final PermissionModel model : mPermissionModels) {
  				if (PackageManager.PERMISSION_GRANTED != ContextCompat.checkSelfPermission(mActivity, model.permission)) {
  					ActivityCompat.requestPermissions(mActivity, new String[] { model.permission }, model.requestCode);
  					return;
  				}
  			}
  			if (mOnApplyPermissionListener != null) {
  				mOnApplyPermissionListener.onAfterApplyAllPermission();
  			}
  		} catch (Throwable e) {
  			Log.e(TAG, "", e);
  		}
  	}
  
  	/**
  	 * 对应Activity的 {@code onRequestPermissionsResult(...)} 方法
  	 *
  	 * @param requestCode
  	 * @param permissions
  	 * @param grantResults
  	 */
  	public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
  		switch (requestCode) {
  		case READ_PHONE_STATE_CODE:
  		case WRITE_EXTERNAL_STORAGE_CODE:
  			// 如果用户不允许，我们视情况发起二次请求或者引导用户到应用页面手动打开
  			if (PackageManager.PERMISSION_GRANTED != grantResults[0]) {
  
  				// 二次请求，表现为：以前请求过这个权限，但是用户拒接了
  				// 在二次请求的时候，会有一个“不再提示的”checkbox
  				// 因此这里需要给用户解释一下我们为什么需要这个权限，否则用户可能会永久不在激活这个申请
  				// 方便用户理解我们为什么需要这个权限
  				if (ActivityCompat.shouldShowRequestPermissionRationale(mActivity, permissions[0])) {
  					AlertDialog.Builder builder =
  							new AlertDialog.Builder(mActivity).setTitle("权限申请").setMessage(findPermissionExplain(permissions[0]))
  									.setPositiveButton("确定", new DialogInterface.OnClickListener() {
  
  										@Override
  										public void onClick(DialogInterface dialog, int which) {
  											applyPermissions();
  										}
  									});
  					builder.setCancelable(false);
  					builder.show();
  				}
  				// 到这里就表示已经是第3+次请求，而且此时用户已经永久拒绝了，这个时候，我们引导用户到应用权限页面，让用户自己手动打开
  				else {
  					AlertDialog.Builder builder = new AlertDialog.Builder(mActivity).setTitle("权限申请")
  							.setMessage("请在打开的窗口的权限中开启" + findPermissionName(permissions[0]) + "权限，以正常使用本应用")
  							.setPositiveButton("去设置", new DialogInterface.OnClickListener() {
  
  								@Override
  								public void onClick(DialogInterface dialog, int which) {
  									openApplicationSettings(REQUEST_OPEN_APPLICATION_SETTINGS_CODE);
  								}
  							}).setNegativeButton("取消", new DialogInterface.OnClickListener() {
  								@Override
  								public void onClick(DialogInterface dialog, int which) {
  									mActivity.finish();
  								}
  							});
  					builder.setCancelable(false);
  					builder.show();
  				}
  				return;
  			}
  
  			// 到这里就表示用户允许了本次请求，我们继续检查是否还有待申请的权限没有申请
  			if (isAllRequestedPermissionGranted()) {
  				if (mOnApplyPermissionListener != null) {
  					mOnApplyPermissionListener.onAfterApplyAllPermission();
  				}
  			} else {
  				applyPermissions();
  			}
  			break;
  		}
  	}
  
  	/**
  	 * 对应Activity的 {@code onActivityResult(...)} 方法
  	 *
  	 * @param requestCode
  	 * @param resultCode
  	 * @param data
  	 */
  	public void onActivityResult(int requestCode, int resultCode, Intent data) {
  		switch (requestCode) {
  		case REQUEST_OPEN_APPLICATION_SETTINGS_CODE:
  			if (isAllRequestedPermissionGranted()) {
  				if (mOnApplyPermissionListener != null) {
  					mOnApplyPermissionListener.onAfterApplyAllPermission();
  				}
  			} else {
  				mActivity.finish();
  			}
  			break;
  		}
  	}
  
  	/**
  	 * 判断是否所有的权限都被授权了
  	 *
  	 * @return
  	 */
  	public boolean isAllRequestedPermissionGranted() {
  		for (PermissionModel model : mPermissionModels) {
  			if (PackageManager.PERMISSION_GRANTED != ContextCompat.checkSelfPermission(mActivity, model.permission)) {
  				return false;
  			}
  		}
  		return true;
  	}
  
  	/**
  	 * 打开应用设置界面
  	 *
  	 * @param requestCode 请求码
  	 *
  	 * @return
  	 */
  	private boolean openApplicationSettings(int requestCode) {
  		try {
  			Intent intent =
  					new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:" + mActivity.getPackageName()));
  			intent.addCategory(Intent.CATEGORY_DEFAULT);
  
  			// Android L 之后Activity的启动模式发生了一些变化
  			// 如果用了下面的 Intent.FLAG_ACTIVITY_NEW_TASK ，并且是 startActivityForResult
  			// 那么会在打开新的activity的时候就会立即回调 onActivityResult
  			// intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
  			mActivity.startActivityForResult(intent, requestCode);
  			return true;
  		} catch (Throwable e) {
  			Log.e(TAG, "", e);
  		}
  		return false;
  	}
  
  	/**
  	 * 查找申请权限的解释短语
  	 *
  	 * @param permission 权限
  	 *
  	 * @return
  	 */
  	private String findPermissionExplain(String permission) {
  		if (mPermissionModels != null) {
  			for (PermissionModel model : mPermissionModels) {
  				if (model != null && model.permission != null && model.permission.equals(permission)) {
  					return model.explain;
  				}
  			}
  		}
  		return null;
  	}
  
  	/**
  	 * 查找申请权限的名称
  	 *
  	 * @param permission 权限
  	 *
  	 * @return
  	 */
  	private String findPermissionName(String permission) {
  		if (mPermissionModels != null) {
  			for (PermissionModel model : mPermissionModels) {
  				if (model != null && model.permission != null && model.permission.equals(permission)) {
  					return model.name;
  				}
  			}
  		}
  		return null;
  	}
  
  	private static class PermissionModel {
  
  		/**
  		 * 权限名称
  		 */
  		public String name;
  
  		/**
  		 * 请求的权限
  		 */
  		public String permission;
  
  		/**
  		 * 解析为什么请求这个权限
  		 */
  		public String explain;
  
  		/**
  		 * 请求代码
  		 */
  		public int requestCode;
  
  		public PermissionModel(String name, String permission, String explain, int requestCode) {
  			this.name = name;
  			this.permission = permission;
  			this.explain = explain;
  			this.requestCode = requestCode;
  		}
  	}
  
  	/**
  	 * 权限申请事件监听
  	 */
  	public interface OnApplyPermissionListener {
  
  		/**
  		 * 申请所有权限之后的逻辑
  		 */
  		void onAfterApplyAllPermission();
  	}
  	
  }
  