1

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.

We are Borg
  • 5,117
  • 17
  • 102
  • 225

5 Answers5

4

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;
        }
    }
}
Sohail Zahid
  • 8,099
  • 2
  • 25
  • 41
  • Can you tell me what does REQUEST_RUNTIME_PERMISSION = 123; mean? What's it for? For network operations? – We are Borg Sep 01 '16 at 11:34
  • And this specific identifier signifies? – We are Borg Sep 01 '16 at 11:38
  • its identifier for used for different permission against it ...like your are getting set of other permissions and want to do some tasks against every single of them then this identifier will you let you know which set of permission is trigger by user. – Sohail Zahid Sep 01 '16 at 11:40
3

The Android will not ask for permission itself, You have to add code to

ask the user everytime to check whether the required permissions are

available or not and act accordingly.

Refer this link

Community
  • 1
  • 1
Ashish Shukla
  • 1,027
  • 16
  • 36
1

The problem is that in Android 6.0 (API level 23) you must check permissions at runtime. You can find more info here.

Refer this for a better understanding.

shinilms
  • 1,494
  • 3
  • 22
  • 35
1

Since Android 6, (targetSdkVersion >=23 in your build.gradle file) you need to explicitly request for those permissions that are dangerous.

To check for permissions you should use ContextCompat.checkSelfPermission(). To request for permission you should useActivityCompat.requestPermissions().

More info here.

Check here for the list of normal/dangerous permissions.

fernandospr
  • 2,976
  • 2
  • 22
  • 43
1

You should first have to check READ_CONTACTS permission. Here is the code to check the permission.

   public boolean checkPermissionForReadContacts() {
      int result = ContextCompat.checkSelfPermission(activity, Manifest.permission.READ_CONTACTS);
   if (result == PackageManager.PERMISSION_GRANTED) {
        return true;
    } else {
        return false;
    }
   }

This might help!

  • If the permission is not granted then display an alert of permission request. Try out this library for permissions it will handle everything: https://github.com/Karumi/Dexter – Abdullah Mehmood Sep 01 '16 at 11:19