We are Borg We are Borg - 3 months ago 12
Java Question

Android(6.*) : Permission denial although permissions are assigned, and are not requested

I am working on an Android project in which I am displaying the contacts. I have added contacts permission in android, still I kept getting error for the app. I am trying out the app on Marshmallow and it didn't even ask me for permission, but I went in apps, selected permissions and enabled contacts. After that, the app was not crashing anymore, But I am still getting an error.

ANdroidManifest.xml :

<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-permission android:name="android.permission.read_contacts" />
<uses-permission android:name="android.permission.read_phone_state" />
<uses-permission android:name="android.permission.READ_CALL_LOG" />


Error log :

va.lang.RuntimeException: Unable to start activity ComponentInfo

{com.mycomp.development.myapp/com.mycomp.development.myapp.Activity.SwapContacts}: java.lang.SecurityException: Permission Denial: opening provider com.android.providers.contacts.ContactsProvider2 from ProcessRecord{235a9d5 20566:com.mycomp.development.myapp/u0a157} (pid=20566, uid=10157) requires android.permission.READ_CONTACTS or android.permission.WRITE_CONTACTS
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.SecurityException: Permission Denial: opening provider com.android.providers.contacts.ContactsProvider2 from ProcessRecord{235a9d5 20566:com.mycomp.development.myapp/u0a157} (pid=20566, uid=10157) requires android.permission.READ_CONTACTS or android.permission.WRITE_CONTACTS
at android.os.Parcel.readException(Parcel.java:1599)
at android.os.Parcel.readException(Parcel.java:1552)
at android.app.ActivityManagerProxy.getContentProvider(ActivityManagerNative.java:3550)
at android.app.ActivityThread.acquireProvider(ActivityThread.java:4778)
at android.app.ContextImpl$ApplicationContentResolver.acquireUnstableProvider(ContextImpl.java:2018)
at android.content.ContentResolver.acquireUnstableProvider(ContentResolver.java:1468)
at android.content.ContentResolver.query(ContentResolver.java:475)
at android.content.ContentResolver.query(ContentResolver.java:434)
at com.mycomp.development.myapp.Activity.SwapContacts.initView(SwapContacts.java:77)
at com.mycomp.development.myapp.Activity.SwapContacts.onCreate(SwapContacts.java:53)
at android.app.Activity.performCreate(Activity.java:6237)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476) 
at android.app.ActivityThread.-wrap11(ActivityThread.java) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:148) 
at android.app.ActivityThread.main(ActivityThread.java:5417) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
}


Code at which I have error :

private void initView() {
// etInput = (EditText) findViewById(R.id.et_input);
mIndexerLayout = (LinearLayout) findViewById(R.id.indexer_layout);
mListView = (ListView) findViewById(R.id.contacts_list);
mTitleLayout = (FrameLayout) findViewById(R.id.title_layout);
mTitleText = (TextView) findViewById(R.id.title_text);
mSectionToastLayout = (RelativeLayout) findViewById(R.id.section_toast_layout);
mSectionToastText = (TextView) findViewById(R.id.section_toast_text);
for(int i = 0; i < alphabet.length(); i++) {
TextView letterTextView = new TextView(this);
letterTextView.setText(alphabet.charAt(i)+"");
letterTextView.setTextSize(14f);
letterTextView.setGravity(Gravity.CENTER);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(28, 0, 1.0f);
letterTextView.setLayoutParams(params);
letterTextView.setPadding(4, 0, 2, 0);
mIndexerLayout.addView(letterTextView);
mIndexerLayout.setBackgroundResource(R.drawable.letterslist_bg);
}
Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
// Below line is line nos 77, where the error occurs.
Cursor cursor = getContentResolver().query(uri,
new String[] { "display_name", "sort_key" }, null, null, "sort_key");
if (cursor.moveToFirst()) {
do {
String name = cursor.getString(0);
String sortKey = getSortKey(cursor.getString(1));
Log.e("sortKey from cursor", ""+sortKey);
Glossary glossary = new Glossary();
glossary.setName(name);
glossary.setSortKey(sortKey);
glossaries.add(glossary);
} while (cursor.moveToNext());
}

mAdapter = new ContactsAdapter(this, glossaries);
startManagingCursor(cursor);
mIndexer = new AlphabetIndexer(cursor, 1, alphabet);
mAdapter.setIndexer(mIndexer);

if(glossaries != null && glossaries.size() > 0) {
mListView.setAdapter(mAdapter);
mListView.setOnScrollListener(mOnScrollListener);
mIndexerLayout.setOnTouchListener(mOnTouchListener);
}
}


Thank you.

Answer

Full Demo

public class MainActivity extends AppCompatActivity {
    Context context;
    private static final int REQUEST_RUNTIME_PERMISSION = 123;
    String[] permissons = {Manifest.permission.READ_CONTACTS,
            Manifest.permission.WRITE_CONTACTS,
            Manifest.permission.READ_CONTACTS,
            Manifest.permission.READ_PHONE_STATE,
            Manifest.permission.READ_CALL_LOG};

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        context = this;

        if (CheckPermission(MainActivity.this, permissons[0])) {
            // you have permission go ahead
            YourTaskNow();
        } else {
            // you do not have permission go request runtime permissions
            RequestPermission(MainActivity.this, permissons, REQUEST_RUNTIME_PERMISSION);
        }
    }

    private void YourTaskNow() {
         //your task now
    }

    private boolean isNetworkAvailable() {
        ConnectivityManager connectivityManager
                = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
        return activeNetworkInfo != null && activeNetworkInfo.isConnected();
    }

    @Override
    public void onRequestPermissionsResult(int permsRequestCode, String[] permissions, int[] grantResults) {
        switch (permsRequestCode) {

            case REQUEST_RUNTIME_PERMISSION: {
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // you have permission go ahead
                    YourTaskNow();
                } else {
                    // you do not have permission show toast.
                }
                return;
            }
        }
    }

    public void RequestPermission(Activity thisActivity, String[] Permission, int Code) {
        if (ContextCompat.checkSelfPermission(thisActivity,
                Permission[0])
                != PackageManager.PERMISSION_GRANTED) {
            if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
                    Permission[0])) {
            } else {
                ActivityCompat.requestPermissions(thisActivity, Permission,
                        Code);
            }
        }
    }

    public boolean CheckPermission(Context context, String Permission) {
        if (ContextCompat.checkSelfPermission(context,
                Permission) == PackageManager.PERMISSION_GRANTED) {
            return true;
        } else {
            return false;
        }
    }
}