Supplementary MyRent lab to demonstrate how to request permissions at run time. We restrict ourselves to the single permission READ_CONTACTS. We consider two scenarios: activity-fragment and viewpager-fragment.
Add the following dependency to build.gradle (Modlule: app)
:
compile "com.android.support:support-v13:23.4.0"
The FragmentCompat class, which we shall be using shortly, requires this library.
Your complete gradle file might look something like this (with the appropriate applicationId):
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.3"
defaultConfig {
applicationId "org.wit.myrent"
minSdkVersion 19
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.4.0'
compile "com.android.support:support-v13:23.4.0"
}
This code will work for both the ViewPager-Fragment and Activity-Fragment situations.
Introduce a new field for the intent data.
// This field is initialized in `onActivityResult`.
Intent data:
This field is required to provide us with access to the data intent outside the method onActivityResult
.
@Override
public void onClick(View v)
{
switch (v.getId())
{
...
...
case R.id.tenant :
Intent i = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
startActivityForResult(i, REQUEST_CONTACT);
break;
case R.id.residence_reportButton :
if(emailAddress == null) emailAddress = ""; // guard against null pointer
sendEmail(getActivity(), emailAddress, getString(R.string.residence_report_subject), residence.getResidenceReport(getActivity()));
break;
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
switch (requestCode) {
case REQUEST_CONTACT:
this.data = data;
checkContactsReadPermission();
break;
}
}
private void readContact() {
String name = ContactHelper.getContact(getActivity(), data);
emailAddress = ContactHelper.getEmail(getActivity(), data);
tenantButton.setText(name + " : " + emailAddress);
residence.tenant = name;
}
`
/**
* http://stackoverflow.com/questions/32714787/android-m-permissions-onrequestpermissionsresult-not-being-called
* This is an override of FragmentCompat.onRequestPermissionsResult
*
* @param requestCode Example REQUEST_CONTACT
* @param permissions String array of permissions requested.
* @param grantResults int array of results for permissions request.
*/
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case REQUEST_CONTACT: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
readContact();
}
break;
}
}
}
/**
* Bespoke method to check if read contacts permission exists.
* If it exists then the contact sought is read.
* Otherwise, the method FragmentCompat.request permissions is invoked and
* The response is via the callback onRequestPermissionsResult.
* In onRequestPermissionsResult, on successfully being granted permission then the sought contact is read.
*/
private void checkContactsReadPermission() {
if (ContextCompat.checkSelfPermission(getActivity(),
Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED) {
readContact();
}
else {
// Invoke callback to request user-granted permission
FragmentCompat.requestPermissions(
this,
new String[]{Manifest.permission.READ_CONTACTS},
REQUEST_CONTACT);
}
}
These import statements are required:
import android.support.v13.app.FragmentCompat;
import android.support.v4.content.ContextCompat;
import android.Manifest;
import android.content.pm.PackageManager;
Replace the existing Fragment import with the following:
import android.app.Fragment;
Activity class: example ResidenceActivity.
Replace:
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
with:
import android.app.Fragment;
import android.app.FragmentManager;
Replace:
FragmentManager manager = getSupportFragmentManager();
with:
FragmentManager manager = getFragmentManager();
ViewPager class: example ResidencePagerActivity
Replace:
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
with:
import android.app.Fragment;
import android.app.FragmentManager;
import android.support.v13.app.FragmentStatePagerAdapter;
Replace:
pagerAdapter = new PagerAdapter(getSupportFragmentManager(), residences);
with:
pagerAdapter = new PagerAdapter(getFragmentManager(), residences);