安卓6.0棉花糖权限不正常工作

3

我尝试在Android 6 Marshmallow中访问所有联系人和所有者电子邮件ID,并进行多个权限检查,但是我的应用程序有时会崩溃并显示SecurityException,有时会显示权限请求。当我允许权限时,它不会触发读取联系人,直到我重新启动应用程序。

我在代码中漏掉了什么吗?

  public static final int REQUEST_ID_MULTIPLE_PERMISSIONS = 1;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            if(checkAndRequestPermissions()) {
                // carry on the normal flow, as the case of  permissions  granted.
     try {
                    Account[] accounts = AccountManager.get(getApplicationContext()).getAccountsByType("com.google");
                    for (Account account : accounts) {
                        String emailid = account.name;
                        Log.e("account", emailid);
                    }
                } catch (Exception e) {
                    Log.e("Exception", "Exception:" + e);
                }
                ContentResolver cr = getApplicationContext().getContentResolver(); //Activity/Application android.content.Context
                Cursor cursor = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
                if (cursor.moveToFirst()) {
                    do {
                        String contactid = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
                        if (Integer.parseInt(cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
                            Cursor pCur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[]{contactid}, null);
                            while (pCur.moveToNext()) {
                                String contactName = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
                                String contactNumber = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                                alContacts.add(contactNumber);
                                alName.add(contactName);
                                Log.e("Contact Name", contactName);
                                Log.e("Contact Number", contactNumber);
                                break;
                            }
                            pCur.close();
                        }

                    } while (cursor.moveToNext());
                }
              }
            }
        }

        private  boolean checkAndRequestPermissions() {
            int permissionSendMessage = ContextCompat.checkSelfPermission(this,
                    Manifest.permission.SEND_SMS);
            int locationPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION);
            List<String> listPermissionsNeeded = new ArrayList<>();
            if (locationPermission != PackageManager.PERMISSION_GRANTED) {
                listPermissionsNeeded.add(Manifest.permission.ACCESS_FINE_LOCATION);
            }
            if (permissionSendMessage != PackageManager.PERMISSION_GRANTED) {
                listPermissionsNeeded.add(Manifest.permission.SEND_SMS);
            }
            if (!listPermissionsNeeded.isEmpty()) {
                ActivityCompat.requestPermissions(this, listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]),REQUEST_ID_MULTIPLE_PERMISSIONS);
                return false;
            }
            return true;
        }
         @Override
            public void onRequestPermissionsResult(int requestCode,
                                                   String permissions[], int[] grantResults) {
                Log.d(TAG, "Permission callback called-------");
                switch (requestCode) {
                    case REQUEST_ID_MULTIPLE_PERMISSIONS: {

                        Map<String, Integer> perms = new HashMap<>();
                        // Initialize the map with both permissions
                        perms.put(Manifest.permission.SEND_SMS, PackageManager.PERMISSION_GRANTED);
                        perms.put(Manifest.permission.ACCESS_FINE_LOCATION, PackageManager.PERMISSION_GRANTED);
                        // Fill with actual results from user
                        if (grantResults.length > 0) {
                            for (int i = 0; i < permissions.length; i++)
                                perms.put(permissions[i], grantResults[i]);
                            // Check for both permissions
                            if (perms.get(Manifest.permission.SEND_SMS) == PackageManager.PERMISSION_GRANTED
                                    && perms.get(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                                Log.d(TAG, "sms & location services permission granted");
                                // process the normal flow
                                //else any one or both the permissions are not granted
                            } else {
                                    Log.d(TAG, "Some permissions are not granted ask again ");
                                    //permission is denied (this is the first time, when "never ask again" is not checked) so ask again explaining the usage of permission
        //                        // shouldShowRequestPermissionRationale will return true
                                    //show the dialog or snackbar saying its necessary and try again otherwise proceed with setup.
                                    if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.SEND_SMS) || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)) {
                                        showDialogOK("SMS and Location Services Permission required for this app",
                                                new DialogInterface.OnClickListener() {
                                                    @Override
                                                    public void onClick(DialogInterface dialog, int which) {
                                                        switch (which) {
                                                            case DialogInterface.BUTTON_POSITIVE:
                                                                checkAndRequestPermissions();
                                                                break;
                                                            case DialogInterface.BUTTON_NEGATIVE:
                                                                // proceed with logic by disabling the related features or quit the app.
                                                                break;
                                                        }
                                                    }
                                                });
                                    }
                                    //permission is denied (and never ask again is  checked)
                                    //shouldShowRequestPermissionRationale will return false
                                    else {
                                        Toast.makeText(this, "Go to settings and enable permissions", Toast.LENGTH_LONG)
                                                .show();
            //                            //proceed with logic by disabling the related features or quit the app.
                                    }
                            }
                        }
                    }
                }

            }

            private void showDialogOK(String message, DialogInterface.OnClickListener okListener) {
                new AlertDialog.Builder(this)
                        .setMessage(message)
                        .setPositiveButton("OK", okListener)
                        .setNegativeButton("Cancel", okListener)
                        .create()
                        .show();
            }

抱歉,这与我的问题无关。 - Mr Robot
1
最好每次读取联系人时都进行检查。用户可能会在启用权限后禁用该权限。 - Madhukar Hebbar
1
你的代码看起来相当复杂,乍一看我以为你会引用那个链接并替换权限代码checkAndRequestPermissions(),但是现在阅读你的代码后,我发现了崩溃的原因:在你的checkAndRequestPermissions()方法中,最后一个返回语句是true,它应该返回false。 - HAXM
2个回答

1
用下面的方法替换您的checkAndRequestPermissions()方法。
private  boolean checkAndRequestPermissions() {
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {  
    if(this.checkSelfPermission(permission.SEND_SMS)== PackageManager.PERMISSION_GRANTED && this.checkSelfPermission(permission.ACCESS_FINE_LOCATION)== PackageManager.PERMISSION_GRANTED){
                return true;
            }else{
                if(shouldShowRequestPermissionRationale(Manifest.permission.SEND_SMS)){
                    Toast.makeText(MainActivity.this,"Your Permissions is required to send msg .....",Toast.LENGTH_LONG).show();
                    return false;
                }
                if(shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION)){
                    Toast.makeText(MainActivity.this,"Your Permissions is required to get your current location .....",Toast.LENGTH_LONG).show();
                    return false;
                }
                requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.permission.SEND_SMS}, REQUEST_ID_MULTIPLE_PERMISSIONS);
            return false;
            }
    }else{
            return true;
        }
        return false;

    }

1

尝试使用this简单的Android权限库。它可以使开发者的生活更加轻松。

只需在您的Gradle中包含以下依赖项即可。

dependencies {
    compile 'com.vistrav:ask:1.2'
}

并在您的活动中使用以下代码片段来请求权限。

Ask.on(context)
                .forPermissions(Manifest.permission.ACCESS_COARSE_LOCATION
                        , Manifest.permission.WRITE_EXTERNAL_STORAGE) //one or more permissions
                .withRationales("Location permission need for map to work properly", 
                        "In order to save file you will need to grant storage permission") //optional
                .when(new Ask.Permission() {
                    @Override
                    public void granted(List<String> permissions) {
                        Log.i(TAG, "granted :: " + permissions);
                    }

                    @Override
                    public void denied(List<String> permissions) {
                        Log.i(TAG, "denied :: " + permissions);
                    }
                }).go();

这就是你所需要的全部。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接