1. 程式人生 > >android實現檢測app是否有通知許可權,沒有就跳轉去設定,設定成功返回時並測試發出一條通知訊息

android實現檢測app是否有通知許可權,沒有就跳轉去設定,設定成功返回時並測試發出一條通知訊息

1.判斷是否有通知許可權

2.沒有的話,彈出一個對話方塊,提示使用者是否去設定,使用者點選確定後跳轉到設定頁面

3.手動設定許可權成功後,結果會返回到

onActivityResult方法中,其中返回的請求碼等於傳入的碼時,並且結果碼等於2,編輯正確設定了,此時就可以呼叫發起通知。

4.正式開始:首先先寫好一個工具類,用來判斷是否有通知許可權。

工具類名:NotificationPermissions

首先我們需要理解什麼是appOps,這是一個android的原生許可權管理,當手機系統啟動時,就會自動啟動這個相關的服務。

api:appopsmanager

整體的工作框架:

解釋:當我們打開了設定頁面的ui,並點選允許通知時,就會change permission

,改變app許可權主要是通過appopsmanager這個類來實現。appopsmanager將會和appopsservice進行互動,  使用者改變的許可權將會儲存在/data/system/appops.xml檔案中。appopsservice也會被注入到其他各種服務中,進行許可權的檢測。

相關介面的api:

int checkop(String op,int uid,String  packageName)判斷應用是否含有某個許可權

int noteop(string op,int uid,String packageName)和checkop使用一樣,但是會在檢測的時候記錄一下

int checkopnothrow(string op,int uid,String packageName)和checkop類似,但是許可權錯誤,不會報SecurityException錯誤,會返回appopsmanager.mode_error

int noteopnothrow(string op,int uid,String packageName)和checkopnothrow類似,但是不會返回appopsmanager.mode_error

void setMode(int code,int uid,String packageName,int mode)這個是我們最需要的方法,用來改變APP的許可權。code代表具體的許可權,mode表示(允許/禁止/提示)。

正式程式碼:

public class NotificationPermissions{

           private final string checkopnothrow="CHECKOPNOTHROW";//將要獲取的方法,

           private final string op_post_notification="OP_POST_NOTIFICATION";將要獲取的欄位

           public boolean isNotification(Context context){//需要將上下文傳入進來

                        //1.獲取appopsmanager

                  AppOpsManager   appopsmanager=(AppOpsManager   )context.getSystemtService(Context.APP_OPS_SERBIVE);

                  //2.獲取applicationContextInfo資訊

         ApplicationInfo appInfo =context.getApplicationInfo();

                //3.獲取包名

                     String  packageName=appInfo,packageName;//或者                                                   packageName=context.getAppliacationContext().getPackageName();       

                     int uid=appInfo.uid;使用者身份                                       

                //4.例項化該packageName類

                 Class cla=class.forName(AppOpsManager.class.getName());

               //5.通過反射獲取要呼叫的appopsmanager中的方法

                Method  checkOpNoThrowMethod=appopsmanager.getMthod(checkopnothrow,Integer.TYPE,Integer.TYPE,String.class);

                 checkOpNoThrowMethod這個方法就是上面提到過的紅色第三個方法。

               Field opPostNotificationValue=appopsmanager.getDeclaredField(op_post_notification);

              int value=(Integer)opPostNotificationValue.get(Integer.class);

           return   checkOpNoThrowMethod.invoke(appopsmanager,value,uid,packageName)==AppOpsManager.MODE_ALLOWED;//MODE_ALLOWED表示已經允許了

           }

}

//6.以下程式碼是在mainactivity中,當權限檢測沒有時,執行的方法

//建立通知訊息的方法
private void createNotification(){
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this);//使用NotificationCompat build通知訊息
        builder.setSmallIcon(R.mipmap.ic_launcher);
        builder.setContentTitle("新訊息");
        builder.setContentText("你有一條新的訊息");
        builder.setNumber(num++);
        builder.setAutoCancel(true);//設定點選通知跳轉頁面後,通知消失
        Intent intent = new Intent(this,MainActivity.class);//點選後要跳轉的頁面
//PendingIntent ,不會立即跳轉,是將要跳轉到某個頁面,正好用於點選通知後的操作
        PendingIntent pi = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        builder.setContentIntent(pi);
        Notification notification = builder.build();
    NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);//通知管理器
    Log.e("xx","新訊息");
    mNotificationManager.notify(NO_1,notification);//傳送
    Log.e("xx","你有一條新的訊息");
}

//若是沒有許可權 ,跳轉
private void gotoSet(){
    if (!NotificationPermissions.isNotificationEnabled(this)) {
        final AlertDialog dialog = new AlertDialog.Builder(this).create();
        dialog.show();
        View view = View.inflate(this, R.layout.dialog, null);
        dialog.setContentView(view);
        TextView context = (TextView) view.findViewById(R.id.tv_dialog_context);
        context.setText("檢測到您沒有開啟通知許可權,是否去開啟");
        TextView confirm = (TextView) view.findViewById(R.id.btn_confirm);
        confirm.setText("確定");
        confirm.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                dialog.cancel();
                Intent localIntent = new Intent();
                localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                if (Build.VERSION.SDK_INT >= 9) {//系統8.0以上的
                    localIntent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
                    localIntent.setData(Uri.fromParts("package", MainActivity.this.getPackageName(), null));
                } else if (Build.VERSION.SDK_INT <= 8) {//系統8.0以下的
                    localIntent.setAction(Intent.ACTION_VIEW);
                    localIntent.setClassName("com.android.settings",
                            "com.android.settings.InstalledAppDetails");
                    localIntent.putExtra("com.android.settings.ApplicationPkgName",
                            MainActivity.this.getPackageName());
                }
                startActivityForResult(localIntent,REQUESTCODE);
            }
        });

        TextView cancel = (TextView) view.findViewById(R.id.btn_off);
        cancel.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                dialog.cancel();
            }
        });
    }
}


@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if(resultCode==2){
            if(requestCode==REQUESTCODE){
                createNotification();//傳送測試通知
            }
    }
}