app 연락처 읽기 권한이 부여되었는지 판단

26774 단어 안드로이드 기술
최근 회사의 앱에 수요가 하나 있는데 응용 프로그램의 권한 수여 여부를 판단해야 한다. 권한 수여가 없으면 사용자에게 페이지를 설정하고 권한 수여를 열도록 유도하는 것이 간단하다고 생각했는데 결과적으로 앱이 출시된 후에 많은 문제가 발생했다.프로그램 원숭이 여러분들이 시행착오를 줄이기 위해 해결 방안을 여러분께 바칩니다.쓸데없는 말은 하지 마라.
각 휴대전화 제조업체가 자신의 룸에 대해 엄격한 봉인을 했기 때문에 우리는 안드로이드 시스템을 사용하여 읽기 권한이 있는지의api를 가져올 수 없기 때문에 어떤 권한이 이미 권한을 부여받았는지 판단할 수 없다. 예를 들어 현재 시장에서 가장 핫한 OPPO 휴대전화는 연락처 권한이 열렸는지 읽을 때마다 항상true로 되돌아오기 때문에 판단할 수 없다.이 장에서 우리는 주로 앱이 연락처를 읽는 데 권한을 부여하는지 검사하는 것을 예로 들면 다른 권한 판단도 마찬가지다.
우선 읽기 권한의 방안은 네 가지가 있는데 그것이 바로 패키지 매니저,Activity,Activity Compat,PermissionCheck 등 네 가지 종류를 통해 읽는다. 예를 들어 연락처 권한이 열려 있는지 판단하는 것이다.
boolean permission = (PackageManager.PERMISSION_GRANTED ==
        pm.checkPermission("android.permission.READ_CONTACTS", "  "));

다른 방법은 인터넷에 매우 많은데, 여기서는 더 이상 말하지 않겠다.
앞에서 말했듯이 여러 가지 이유로 이permission은 부정확한 값이다. 우리는 많은 상황에서 권한이 열려 있는지 아닌지를 판단할 수 없다. 오랫동안 시도한 후에 효과적인 방안을 정리했다. 바로 연락처를 직접 읽는 것이다. 우리는 비동기적인 임무를 켜서 연락처를 읽을 수 있다. 여기서 나는 AsyncTask를 사용한다.
  protected ArrayList doInBackground(Context... voids) {
            ContentResolver resolver = context.getContentResolver();
            //   Sims    
            Uri uri = Uri.parse("content://com.android.contacts/contacts"); //  raw_contacts 
            //  _id  
            Cursor cursor = null;
            try {
                cursor = resolver.query(uri, new String[]{ContactsContract.Data._ID}, null, null, "sort_key asc");
            } catch (Exception e) {
                e.printStackTrace();
            }

            if (cursor == null) {
                return null; // error
            }

            ArrayList result = new ArrayList<>();
            while (cursor.moveToNext()) {
                Contact contact = new Contact();
                StringBuilder buf = new StringBuilder();
                //  id   data     
                int id = cursor.getInt(0);
//            buf.append("id="+id);
                uri = Uri.parse("content://com.android.contacts/contacts/" + id + "/data");
                //data1mimetype       ,   、email 
                Cursor phoneCursor = resolver.query(uri, null, null, null, null);

                if (phoneCursor == null) {
                    return result;
                }

                while (phoneCursor.moveToNext()) {


//                String name = phoneCursor.getString(phoneCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));//     name
//                String phoneNumber = phoneCursor.getString(phoneCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); //     number

                    String data = phoneCursor.getString(phoneCursor.getColumnIndex("data1"));

                    if (phoneCursor.getString(phoneCursor.getColumnIndex("mimetype")).equals("vnd.android.cursor.item/name")) {
                        contact.setName(data);   //     
//                    buf.append(",name="+data);
                    } else if (phoneCursor.getString(phoneCursor.getColumnIndex("mimetype")).equals("vnd.android.cursor.item/phone_v2")) {  //     
                        if (TextUtils.isEmpty(contact.getNumber())) {
                            contact.setNumber(data);
                        } else if (TextUtils.isEmpty(contact.getNumber2())) {
                            contact.setNumber2(data);
                        } else {
                            contact.setNumber3(data);
                        }
//                    buf.append(",phone="+data);
                    } else if (phoneCursor.getString(phoneCursor.getColumnIndex("mimetype")).equals("vnd.android.cursor.item/email_v2")) {  //   email
                        if (TextUtils.isEmpty(contact.getEmail())) {
                            contact.setEmail(data);
                        } else if (TextUtils.isEmpty(contact.getEmail2())) {
                            contact.setEmail2(data);
                        } else {
                            contact.setEmail3(data);
                        }

//                    buf.append(",email="+data);
                    } else if (phoneCursor.getString(phoneCursor.getColumnIndex("mimetype")).equals("vnd.android.cursor.item/postal-address_v2")) { //     

                        if (TextUtils.isEmpty(contact.getAddress())) {
                            contact.setAddress(data);
                        } else if (TextUtils.isEmpty(contact.getAddress2())) {
                            contact.setAddress2(data);
                        } else {
                            contact.setAddress3(data);
                        }
//                    buf.append(",address="+data);
                    } else if (phoneCursor.getString(phoneCursor.getColumnIndex("mimetype")).equals("vnd.android.cursor.item/organization")) {  //     
//                    buf.append(",organization=" + data);
                    }
                }

                phoneCursor.close();
                result.add(contact);
            }
            cursor.close();

            return result;
        }
doInbackground에서 읽은 후에 우리는 onPostExcute에서 읽은 결과를 판단한다. 결과에 따라 우리는 응용된 연락처 읽기 권한이 사용자에게 열려 있는지 판단할 수 있다. 만약에 열리지 않으면 대응하는 조작을 한다. 만약에 열리지 않으면 팝업 대화상자에서 사용자에게 페이지 열기 권한을 설정하도록 유도한다.OnPostExcute 방법은 다음과 같습니다.
   protected void onPostExecute(ArrayList result) {
        loadManager.dismiss();

        if (null == result) {
            //     
            //             OPPO R9     
            final Dialog dialog = new Dialog(getActivity(), R.style.dialog);
            dialog.setContentView(R.layout.dialog_oppo_permission_help);
            dialog.setCancelable(false);
            TextView tv_step1 = (TextView) dialog.findViewById(R.id.tv_step1);
            TextView tv_step2 = (TextView) dialog.findViewById(R.id.tv_step2);
            Button btn_go = (Button) dialog.findViewById(R.id.btn_go);
            tv_step1.setText(Html.fromHtml(
                    "             "));
            tv_step2.setText(Html.fromHtml(
                    "       &quot    &quot"));
            btn_go.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    dialog.dismiss();
                    Intent intent = SystemUtils.getAppDetailSettingIntent();
                    startActivityForResult(intent, 0);
                }
            });
            dialog.show();
        } else if (result.isEmpty()) {
            //      
            Toast.makeText(context, "", Toast.LENGTH_SHORT).show();
        } else {
            //        
            Intent selectContact = new Intent();
            selectContact.putExtra(ContactActivity.PARAM_NAME_TAG_FROM, MoreInfoFragment.class.getSimpleName());
            selectContact.putParcelableArrayListExtra(ContactActivity.PARAM_NAME_CONTACT_DATA, result);
            selectContact.setClass(getActivity(), ContactActivity.class);
            startActivityForResult(selectContact, 0);
        }
    }
}
doInbackground에서 읽은 후에 우리는 onPostExcute에서 읽은 결과를 판단한다. 결과에 따라 우리는 응용된 연락처 읽기 권한이 사용자에게 열려 있는지 판단할 수 있다. 만약에 열리지 않으면 대응하는 조작을 한다. 만약에 열리지 않으면 팝업 대화상자에서 사용자에게 페이지 열기 권한을 설정하도록 유도한다.OnPostExcute 방법은 다음과 같습니다.
   protected void onPostExecute(ArrayList result) {
        loadManager.dismiss();

        if (null == result) {
            //     
            //             OPPO R9     
            final Dialog dialog = new Dialog(getActivity(), R.style.dialog);
            dialog.setContentView(R.layout.dialog_oppo_permission_help);
            dialog.setCancelable(false);
            TextView tv_step1 = (TextView) dialog.findViewById(R.id.tv_step1);
            TextView tv_step2 = (TextView) dialog.findViewById(R.id.tv_step2);
            Button btn_go = (Button) dialog.findViewById(R.id.btn_go);
            tv_step1.setText(Html.fromHtml(
                    "             "));
            tv_step2.setText(Html.fromHtml(
                    "       &quot    &quot"));
            btn_go.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    dialog.dismiss();
                    Intent intent = SystemUtils.getAppDetailSettingIntent();
                    startActivityForResult(intent, 0);
                }
            });
            dialog.show();
        } else if (result.isEmpty()) {
            //      
            Toast.makeText(context, "", Toast.LENGTH_SHORT).show();
        } else {
            //        
            Intent selectContact = new Intent();
            selectContact.putExtra(ContactActivity.PARAM_NAME_TAG_FROM, MoreInfoFragment.class.getSimpleName());
            selectContact.putParcelableArrayListExtra(ContactActivity.PARAM_NAME_CONTACT_DATA, result);
            selectContact.setClass(getActivity(), ContactActivity.class);
            startActivityForResult(selectContact, 0);
        }
    }
}

또한, 시장에는 오포폰이 많기 때문에 오포폰인지 아닌지를 판단하는 방법은 다음과 같습니다.
private static boolean isOppoR9() {
    String model = Build.MODEL.toLowerCase();
    return model.contains("oppo") && model.contains("r9");
}

설정 페이지로 들어가서 사용 권한을 여는 코드는 다음과 같습니다.
Intent intent = SystemUtils.getAppDetailSettingIntent();
startActivityForResult(intent, 0);

여러분께 도움이 되었으면 좋겠습니다. 감사합니다!

좋은 웹페이지 즐겨찾기