OnActivityResult is not called and I wonder if it's because I just added a permissionrequest (it was working fine before). Below is the code, it's launching an intent with startactivityforresult after having requested a permission.
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
Log.v("showEmails","build<");
return true;
}
if (checkSelfPermission(READ_CONTACTS) == PackageManager.PERMISSION_GRANTED) {
return true;
}
if (shouldShowRequestPermissionRationale(READ_CONTACTS)) {
Snackbar.make(findViewById(android.R.id.content), "permission_rationale", Snackbar.LENGTH_INDEFINITE)
.setAction(android.R.string.ok, new View.OnClickListener() {
#Override
#TargetApi(Build.VERSION_CODES.M)
public void onClick(View v) {
requestPermissions(new String[]{READ_CONTACTS}, REQUEST_READ_CONTACTS);
}
});
} else {
requestPermissions(new String[]{Manifest.permission.READ_CONTACTS}, REQUEST_READ_CONTACTS);
Log.v("showEmails","requestPermissions");
}
return false;
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions,
#NonNull int[] grantResults) {
if (requestCode == REQUEST_READ_CONTACTS) {
if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Uri imageUri = (Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM);
if (imageUri != null) {
ImageView ivShare = (ImageView) findViewById(R.id.ivShare);
ivShare.setImageURI(imageUri);
Intent emailIntent = new Intent(Intent.ACTION_SEND);
emailIntent.setType("application/image");
emailIntent.putExtra(Intent.EXTRA_TEXT, textIntent);
emailIntent.putExtra(Intent.EXTRA_STREAM, imageUri);
emailIntent.setFlags(0);
startActivityForResult(emailIntent, GMAILSENT);
}
}
}
Related
Presently, in my application, when the user is asked to provide "Access all files" permission, the dialog opens and remains on screen even when the user has allowed permission. Below provided screenshot shows the dialog I am referring to:-
I would like to add something in my code, which closes this dialog and opens target activity screen as soon as the user enables the toggle of "Allow access to all files".
GrantPermissionsActivity :-
public class GrantPermissionsActivity extends AppCompatActivity {
private static final int PERMISSION_REQUEST_CODE = 1;
MaterialButton cancelMaterialButton, grantMaterialButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_grant_permissions);
findViews();
initViews();
}
private void findViews() {
cancelMaterialButton = findViewById(R.id.materialButtonCancel);
grantMaterialButton = findViewById(R.id.materialButtonGrant);
}
private void initViews() {
if (checkPermission()){
Intent intent = new Intent(GrantPermissionsActivity.this,PasswordActivity.class);
}
cancelMaterialButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(GrantPermissionsActivity.this, "Need to give permission!", Toast.LENGTH_SHORT).show();
finish();
overridePendingTransition(R.anim.left_to_right, R.anim.right_to_left);
}
});
grantMaterialButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (checkPermission()) {
Toast.makeText(GrantPermissionsActivity.this, "Permission already granted", Toast.LENGTH_SHORT).show();
} else if (!checkPermission()) {
requestPermission();
}
}
});
}
private boolean checkPermission() {
if (SDK_INT >= Build.VERSION_CODES.R) {
return Environment.isExternalStorageManager();
} else {
int result = ContextCompat.checkSelfPermission(GrantPermissionsActivity.this, READ_EXTERNAL_STORAGE);
int result1 = ContextCompat.checkSelfPermission(GrantPermissionsActivity.this, WRITE_EXTERNAL_STORAGE);
return result == PackageManager.PERMISSION_GRANTED && result1 == PackageManager.PERMISSION_GRANTED;
}
}
private void requestPermission() {
if (SDK_INT >= Build.VERSION_CODES.R) {
try {
Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
intent.addCategory("android.intent.category.DEFAULT");
intent.setData(Uri.parse(String.format("package:%s", getApplicationContext().getPackageName())));
startActivityForResult(intent, 2296);
} catch (Exception e) {
Intent intent = new Intent();
intent.setAction(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
startActivityForResult(intent, 2296);
}
} else {
//below android 11
ActivityCompat.requestPermissions(GrantPermissionsActivity.this, new String[]{WRITE_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == PERMISSION_REQUEST_CODE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED) {
// perform action when allow permission success
Toast.makeText(this, "Permission granted", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Allow permission for storage access!", Toast.LENGTH_SHORT).show();
}
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
Log.d(TAG, "onActivityResult: Reachedinresult");
if (requestCode == 2296 && resultCode == RESULT_OK) {
Log.d(TAG, "onActivityResult: Reached request code");
if (SDK_INT >= Build.VERSION_CODES.R) {
Log.d(TAG, "onActivityResult: Reached SDKINT");
if (Environment.isExternalStorageManager()) {
// perform action when allow permission success
/*Intent intent = new Intent(GrantPermissionsActivity.this,PasswordActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);*/
Log.d(TAG, "onActivityResult: Reached");
} else {
checkPermission();
Toast.makeText(this, "Permission not granted", Toast.LENGTH_SHORT).show();
}
}
}
super.onActivityResult(requestCode, resultCode, data);
}
}
Please let me know the changes in the above code.
Also, check the below sample for reference:-
Replace the method requestPermission() to
private void requestPermission() {
if (SDK_INT >= Build.VERSION_CODES.R) {
try {
Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
intent.addCategory("android.intent.category.DEFAULT");
intent.setData(Uri.parse(String.format("package:%s", getApplicationContext().getPackageName())));
startActivityForResult(intent, 2296);
} catch (Exception e) {
Intent intent = new Intent();
intent.setAction(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
startActivityForResult(intent, 2296);
new Timer().scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
if(Environment.isExternalStorageManager()) {
runOnUiThread(new Runnable() {
#Override
public void run() {
// perform action when allow permission success in android 11
}
});
this.cancel();
}
}
},2000,1000);
}
} else {
//below android 11
ActivityCompat.requestPermissions(GrantPermissionsActivity.this, new String[]{WRITE_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE);
}}
If you want to start an activity from there, add flag Intent.FLAG_ACTIVITY_NEW_TASK in the Intent object, otherwise it may not work.
I am trying to implement dark theme from fragment named as "Fragment_One" in android studio.
This is from that fragment file
if (!isChecked) {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
isChecked = true;
} else {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
isChecked = false;
}
It is giving error in MainActivity in the following line of onRequestPermissionsResult() method
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
The onRequestPermissionsResult() method is as follows:
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_CODE_PERMISSION) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "permission granted on request", Toast.LENGTH_SHORT).show();
files= getAllFiles(this);
FragmentTransaction f_fragmentTransaction = getSupportFragmentManager().beginTransaction();
f_fragmentTransaction.replace(R.id.mainFragment, new Fragment_Two()).commit();
}
if (grantResults[1] == PackageManager.PERMISSION_GRANTED) {
Intent intent = new Intent();
intent.setAction(Settings.ACTION_MANAGE_WRITE_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivity(intent);
}
} else {
ActivityCompat.requestPermissions(MainActivity.this, new String[]
{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE_PERMISSION);
}
if (requestCode == 100) {
if (grantResults.length > 0
&& grantResults[0] + grantResults[1] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(MainActivity.this,"allow settings ",Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this,"permission denied ",Toast.LENGTH_SHORT).show();
}
return;
}
}
I am making an application to capture image once and then save it in SD card and display it on the application's MainActivity's ImageView(image_view)(which is handled in onRequestPermissionsResult() method). The application also helps to send email the picture clicked by user. Now for this I have requested 2 permssions:
1.) Camera Request
2.) External Storage Request
When the app launches the Camera Request dialog box appears but the External Storage Request Dialog box is not appearing and the app crashes displaying the toast as External write permissions has not been granted. Cannot Save File.
I have mentioned the requests in Manifest also
<uses-permission android:name="android.permissions.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
Code for requesting permissions
public void requestPermissions() {
if (ContextCompat.checkSelfPermission(this,
android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
} else {
if (ActivityCompat.shouldShowRequestPermissionRationale(this,android.Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
Toast.makeText(this,
"External storage permission required to save images",
Toast.LENGTH_SHORT).show();
}
ActivityCompat.requestPermissions(this,new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE},
REQUEST_WRITE_EXTERNAL_STORAGE);
}
if (ContextCompat.checkSelfPermission(this,
android.Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
launchCamera();
} else {
if (ActivityCompat.shouldShowRequestPermissionRationale(this,android.Manifest.permission.CAMERA)) {
Toast.makeText(this,
"External storage permission required to save images",
Toast.LENGTH_SHORT).show();
}
ActivityCompat.requestPermissions(this,new String[]{android.Manifest.permission.CAMERA},
REQUEST_CAMERA);
}
}
Here is the Full Code
public class MainActivity extends AppCompatActivity {
Button clickPhotoButton;
private static final String FILE_NAME="image01.jpg";
private static final int CAMERA_PIC_REQUEST = 100;
private static final int REQUEST_WRITE_EXTERNAL_STORAGE = 1;
private static final int REQUEST_CAMERA = 2;
File pictureDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "Prakhar");
Uri fileUri;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
clickPhotoButton = (Button) findViewById(R.id.click_photo_button);
makeFolder();
}
public void makeFolder(){
if(!pictureDir.exists()) {
pictureDir.mkdirs();
}
Log.e("Prakhar", pictureDir.getAbsolutePath());
}
public void requestPermissions() {
if (ContextCompat.checkSelfPermission(this,
android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
} else {
if (ActivityCompat.shouldShowRequestPermissionRationale(this,android.Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
Toast.makeText(this,
"External storage permission required to save images",
Toast.LENGTH_SHORT).show();
}
ActivityCompat.requestPermissions(this,new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE},
REQUEST_WRITE_EXTERNAL_STORAGE);
}
if (ContextCompat.checkSelfPermission(this,
android.Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
launchCamera();
} else {
if (ActivityCompat.shouldShowRequestPermissionRationale(this,android.Manifest.permission.CAMERA)) {
Toast.makeText(this,
"External storage permission required to save images",
Toast.LENGTH_SHORT).show();
}
ActivityCompat.requestPermissions(this,new String[]{android.Manifest.permission.CAMERA},
REQUEST_CAMERA);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if(requestCode == REQUEST_WRITE_EXTERNAL_STORAGE ) {
if(grantResults[0] == PackageManager.PERMISSION_GRANTED) {
launchCamera();
} else {
Toast.makeText(this,
"External write permission has not been granted, cannot saved images",
Toast.LENGTH_SHORT).show();
}
} else {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
if(requestCode == REQUEST_CAMERA) {
if(grantResults[0] == PackageManager.PERMISSION_GRANTED) {
launchCamera();
} else {
Toast.makeText(this,
"External write permission has not been granted, cannot saved images",
Toast.LENGTH_SHORT).show();
}
} else {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
public void onPhotoClicked(View view) {
requestPermissions();
}
public void launchCamera() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File image = new File(pictureDir, FILE_NAME);
fileUri = Uri.fromFile(image);
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
startActivityForResult(intent, CAMERA_PIC_REQUEST);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode == CAMERA_PIC_REQUEST && resultCode == RESULT_OK) {
ImageView imageView = (ImageView) findViewById(R.id.image_view);
File image = new File(pictureDir, FILE_NAME);
fileUri = Uri.fromFile(image);
imageView.setImageURI(fileUri);
}
}
}
Found it. It was really a waste of time. In the manifest file I have written
android.permissions.WRITE_EXTERNAL_STORAGE
however it should have been
android.permission.WRITE_EXTERNAL_STORAGE
Try like this
public void requestPermissions() {
boolean hasStoragePermission = ContextCompat.checkSelfPermission(this,
android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
boolean hasCameraPermission = ContextCompat.checkSelfPermission(this,
android.Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED;
ArrayList<String> permissonList = new ArrayList();
if (!hasCameraPermission) {
permissonList.add(android.Manifest.permission.CAMERA)
}
if (!hasStoragePermission) {
permissonList.add(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
}
if (permissonList.size() > 0) {
String [] permissionArray = permissonList.toArray(new String[]{});
ActivityCompat.requestPermissions(this,permissionArray,
REQUEST_PERMISSION);
}
}
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
if (requestCode == REQUEST_PERMISSION) {
boolean allPermissionGranted = true;
for (int i =0; i < grantResults.length; i++) {
boolean permissionGranted = grantResults[i] == PackageManager.PERMISSION_GRANTED;
if (!permisssionGranted) {
allPermissionGranted = false;
break;
}
}
if (allPermissionGranted) {
launchCamera();
}
}
}
I have implemented a telephonic service in my app their is a button when we click on that button it will make a call but the problem is it not supporting all devices on some devices it is working well and in some devices it is not working now provide me any solution what to do so that it work on all devices.
here is my code.
public class SOSCallHelp extends AppCompatActivity {
private Button call1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_soscall_help);
call1=(Button)findViewById(R.id.call1);
call1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.setData(Uri.parse("tel:9078784565"));
if (ActivityCompat.checkSelfPermission(SOSCallHelp.this,
Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED)
{
return;
}
startActivity(callIntent);
}
});
Please make sure you add the below permission in your App Manifest for Pre-Lollipop devices.
<uses-permission android:name="android.permission.CALL_PHONE" />
Request Permission
<uses-permission android:name="android.permission.CALL_PHONE" />
For Calling
Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.setData(Uri.parse("tel:9078784565"));
if (ActivityCompat.checkSelfPermission(SOSCallHelp.this,
Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED)
{
return;
}
startActivity(callIntent);
try this:
final int PERMISSION_REQUEST_CODE = 111;
if (driverMobile != null) {
if (Build.VERSION.SDK_INT >= 23) {
// Marshmallow+
if (!checkCallPhonePermission() || !checkReadStatePermission()) {
requestPermission();
} else {
Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.setData(Uri.parse("tel:" + 1234567899));
startActivity(callIntent);
}
} else {
Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.setData(Uri.parse("tel:" + + 1234567899));
startActivity(callIntent);
}
} else {
}
//permission
private void requestPermission() {
ActivityCompat.requestPermissions(this, new String[]
{Manifest.permission.CALL_PHONE, Manifest.permission.READ_PHONE_STATE},
PERMISSION_REQUEST_CODE);
}
private void requestPermissions() {
ActivityCompat.requestPermissions(this, new String[]
{Manifest.permission.CALL_PHONE, Manifest.permission.READ_PHONE_STATE},
PERMISSION_REQUEST_CODES);
}
private boolean checkCallPhonePermission() {
int result = ContextCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE);
if (result == PackageManager.PERMISSION_GRANTED) {
return true;
} else {
return false;
}
}
private boolean checkReadStatePermission() {
int result = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE);
if (result == PackageManager.PERMISSION_GRANTED) {
return true;
} else {
return false;
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String
permissions[], int[] grantResults) {
switch (requestCode)
{
case PERMISSION_REQUEST_CODE:
if (grantResults.length > 0 && grantResults[0] ==
PackageManager.PERMISSION_GRANTED) {
Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.setData(Uri.parse("tel:" + 123456789
startActivity(callIntent);
}
break;
}
}
Please change to this -
public class SOSCallHelp extends AppCompatActivity {
private Button call1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_soscall_help);
call1 = (Button) findViewById(R.id.call1);
call1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.setData(Uri.parse("tel:9078784565"));
if (ActivityCompat.checkSelfPermission(SOSCallHelp.this,
Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED)
{
return;
}
PackageManager packageManager = getActivity().getPackageManager();
if (callIntent.resolveActivity(packageManager) != null) {
startActivity(callIntent);
} else {
Log.d("SOSCallHelp", "No Intent available to handle this action");
}
}
});
}
}
Simply use :
private static int REQUEST_CALL_PHONE = 111;
private void requestCallPhonePermission() {
String callPermission = android.Manifest.permission.CALL_PHONE;
int hasPermission = ContextCompat.checkSelfPermission(SOSCallHelp.this, callPermission);
String[] permissions = new String[]{callPermission};
if (hasPermission != PackageManager.PERMISSION_GRANTED) {
requestPermissions(permissions, REQUEST_CALL_PHONE);
} else {
Intent intent = new Intent(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:9078784565"));
startActivity(intent);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_CALL_PHONE) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Intent intent = new Intent(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:9078784565"));
startActivity(intent);
} else {
Toast.makeText(SOSCallHelp.this, "CALL_PHONE DENIED", Toast.LENGTH_SHORT).show();
}
}
}
Now call this requestCallPhonePermission() function on button click
In manifest file add <uses-permission android:name="android.permission.CALL_PHONE" />
permission.
I am trying to take an image from Gallery and set it to an imageview but in Android 6 there are some permission problems. Below is the method to ask for the permission. Should I ask for read external storage or write external storage?
Here is what I have done so far:
private static final int READ_CONTACTS_PERMISSIONS_REQUEST = 1;
public void getPermissionToReadExternalStorage() {
if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
if (shouldShowRequestPermissionRationale(
Manifest.permission.READ_EXTERNAL_STORAGE)) {
requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
READ_CONTACTS_PERMISSIONS_REQUEST);
}}}
#Override
public void onRequestPermissionsResult(int requestCode,
#NonNull String permissions[],
#NonNull int[] grantResults){
// Make sure it's our original READ_CONTACTS request
if (requestCode == READ_CONTACTS_PERMISSIONS_REQUEST) {
if (grantResults.length == 1 &&
grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(getActivity(), "Read Contacts permission granted", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getActivity(), "Read Contacts permission denied", Toast.LENGTH_SHORT).show();
}
} else {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
Now my on click listener to pick data from the Gallery:
pro.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
intent.setType("image/*");
if (android.os.Build.VERSION.SDK_INT >= 23) {
getPermissionToReadExternalStorage();
if (getPermissionToReadExternalStorage () this???? <==)
startActivityForResult(Intent.createChooser(intent, "Select Picture"), 0);
} else {
startActivityForResult(Intent.createChooser(intent, "Select Picture"), 0);
}}
});
return v;
}
Now I want to get result of the method getPermissionToReadExternalStorage() so I can start the Activity for picking gallery for Android 6. How can I get the result of the void class?
And another thing is do I have to write method for every permission my app asks for?
So I have completely rewritten the code to request permissions.
Now it supports requesting for multiple permissions and running code with proper result.
Also it works with preMarshmallow devices, so you don't have to check and copy the code in that case.
First, create an Activity class with this code (You can extend any king of activity you need, e.g. AppCompatActivity):
public abstract class PermissionActivity extends AppCompatActivity {
private final ArrayList<PermissionListener> permissionListeners = new ArrayList<>();
#SuppressWarnings("unused")
public void requestPermissions(int requestCode, String[] requestPermissions, PermissionListener permissionListener) {
requestPermissions(requestCode, requestPermissions, null, permissionListener);
}
#SuppressWarnings("unused")
public void requestPermissions(final int requestCode, String[] requestPermissions, String message, final PermissionListener permissionListener) {
final int[] grantResults = new int[requestPermissions.length];
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
ArrayList<String> list_notGranted = new ArrayList<>();
for (String requestPermission : requestPermissions)
if (ContextCompat.checkSelfPermission(this, requestPermission) != PackageManager.PERMISSION_GRANTED)
list_notGranted.add(requestPermission);
if (list_notGranted.size() > 0) {
permissionListeners.add(permissionListener);
requestPermissions = list_notGranted.toArray(new String[list_notGranted.size()]);
if (message != null) {
boolean shouldShowRequestPermissionRationale = false;
for (String permission : requestPermissions)
if (ActivityCompat.shouldShowRequestPermissionRationale(this, permission)) {
shouldShowRequestPermissionRationale = true;
break;
}
if (shouldShowRequestPermissionRationale) {
final String[] f_requestPermissions = requestPermissions;
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(message);
DialogInterface.OnClickListener onClickListener = new DialogInterface.OnClickListener() {
#TargetApi(Build.VERSION_CODES.M)
#Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
PermissionActivity.super.requestPermissions(f_requestPermissions, requestCode);
break;
default:
for (int i = 0; i < grantResults.length; i++)
grantResults[i] = PackageManager.PERMISSION_DENIED;
if (permissionListener != null)
permissionListener.onResult(requestCode, f_requestPermissions, grantResults);
break;
}
}
};
builder.setPositiveButton("OK", onClickListener);
builder.setNegativeButton("Cancel", onClickListener);
builder.show();
} else {
super.requestPermissions(requestPermissions, requestCode);
}
} else {
super.requestPermissions(requestPermissions, requestCode);
}
} else {
for (int i = 0; i < grantResults.length; i++)
grantResults[i] = PackageManager.PERMISSION_GRANTED;
if (permissionListener != null)
permissionListener.onResult(requestCode, requestPermissions, grantResults);
}
} else {
if (permissionListener != null) {
for (int i = 0; i < grantResults.length; i++)
grantResults[i] = PackageManager.PERMISSION_GRANTED;
permissionListener.onResult(requestCode, requestPermissions, grantResults);
}
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String permissions[], #NonNull int[] grantResults) {
for (Iterator<PermissionListener> it = permissionListeners.iterator(); it.hasNext(); ) {
PermissionListener permissionListener = it.next();
if (permissionListener.onResult(requestCode, permissions, grantResults)) {
it.remove();
}
}
}
public interface PermissionListener {
boolean onResult(int requestCode, String[] requestPermissions, int[] grantResults);
}
}
If you want to request permissions from Fragments, add this class:
public class PermissionFragment extends Fragment {
#SuppressWarnings("unused")
public void requestPermissions(int requestCode, String[] requestPermissions, PermissionActivity.PermissionListener permissionListener) {
requestPermissions(requestCode, requestPermissions, null, permissionListener);
}
#SuppressWarnings("unused")
public void requestPermissions(final int requestCode, String[] requestPermissions, String message, PermissionActivity.PermissionListener permissionListener) {
((PermissionActivity) getActivity()).requestPermissions(requestCode, requestPermissions, message, permissionListener);
}
}
Your Activities and Fragments should extend these classes instead of the standart ones.
Now you are ready to request the permissions by calling a method:
requestPermissions(int requestCode, String[] requestPermissions, PermissionListener permissionListener)
If the permission is required for the app to work, you should call this method and specify the message saying why the permission is required.
requestPermissions(int requestCode, String[] requestPermissions, String message, PermissionListener permissionListener)
DONT MISSCALL THE DEFAULT METHOD, WHICH IS
// DON'T USE THIS ONE!
requestPermissions(String[] requestPermissions, int requestCode)
// DON'T USE THIS ONE!
Here is the example of requesting contacts:
private void requestAndLoadContacts() {
String[] permissions = new String[]{Manifest.permission.READ_CONTACTS};
requestPermissions(REQUEST_PERMISSIONS_CONTACTS, permissions, "Read contacts permission is required for the app to work!", new PermissionListener() {
#Override
public boolean onResult(int requestCode, String[] requestPermissions, int[] grantResults) {
// Check if the requestCode is ours
if (requestCode == REQUEST_PERMISSIONS_CONTACTS) {
// Check if the permission is correct and is granted
if (requestPermissions[0].equals(Manifest.permission.READ_CONTACTS) && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission granted
// Calling a method to actually load the contacts
loadContacts();
} else {
// Permission not granted
Toast.makeText(MainActivity.this, "Access denied!", Toast.LENGTH_SHORT).show();
}
return true;
}
return false;
}
});
}
NOTE:
When you implement the PermissionListener, don't forget to return true when the requestCode is the correct one, otherwise the PermissionListener won't be removed from the ArrayList and you'll most likely get a small memory leak.
EDIT
I have rewritted the code and posted in another answer.
Old answer:
Yes, you have to check and ask for permission every time.
Usually I write the code like this:
private int requestPermissionCode;
private Runnable requestPermissionRunnable;
private void runPermissionCode(String requestPermission, int requestCode, Runnable codeToRun) {
if (android.os.Build.VERSION.SDK_INT >= 23) {
if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
requestPermissionCode = requestCode;
requestPermissionRunnable = codeToRun;
requestPermissions(new String[]{requestPermission},
requestCode);
}
} else {
codeToRun.run();
}
}
#Override
public void onRequestPermissionsResult(int requestCode,
#NonNull String permissions[],
#NonNull int[] grantResults) {
if (requestCode == requestPermissionCode) {
if (grantResults.length == 1 &&
grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (requestPermissionRunnable != null)
requestPermissionRunnable.run();
} else {
Toast.makeText(getActivity(), "Permission denied", Toast.LENGTH_SHORT).show();
}
} else {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
and run it like this:
runPermissionCode(Manifest.permission.READ_EXTERNAL_STORAGE, READ_CONTACTS_PERMISSIONS_REQUEST, new Runnable() {
#Override
public void run() {
// your code here
}
});
I am sure it is not a best way, but at least it gives a possibility to request permission and make actions easier.
Initialize Your Permission
private static final int INITIAL_REQUEST = 1337;
private static final int GET_ACCOUNTS = INITIAL_REQUEST+2;
private static final int LOCATION_REQUEST =INITIAL_REQUEST+3;
private static final String[] INITIAL_PERMS = {
Manifest.permission.GET_ACCOUNTS,
Manifest.permission.INTERNET,
Manifest.permission.ACCESS_FINE_LOCATION
};
Check for device and Request for permissions
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!canAccessAccounts()|| !canAccessLocation() ||!canAccessInternet()) {
requestPermissions(INITIAL_PERMS, INITIAL_REQUEST);
}
}
Check Permission is granted Or not
private boolean canAccessAccounts() {
return (hasPermission(Manifest.permission.GET_ACCOUNTS));
}
private boolean canAccessLocation() {
return (hasPermission(Manifest.permission.ACCESS_FINE_LOCATION));
}
private boolean canAccessInternet() {
return (hasPermission(Manifest.permission.INTERNET));
}
private boolean hasPermission(String perm) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
return (PackageManager.PERMISSION_GRANTED == checkSelfPermission(perm));
}
return (true);
}
Update Permissions and Check method for permissions onRequestPermissionsResult
void UpdatePermissions(){
canAccessInternet();
canAccessLocation();
canAccessInternet();
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
UpdatePermissions();
switch(requestCode) {
case GET_ACCOUNTS:
if (canAccessAccounts()) {
}
else {
}
break;
case LOCATION_REQUEST:
if (canAccessLocation()) {
}
else {
}
break;
case INITIAL_REQUEST:
if(canAccessInternet()){
}else {
}
break;
}
}