I make an AARplugins for android which accesses Camera.
But it does not activate onActivityResult.
public static void showCamera ( ) // Connect Camera
{
String Uri;
Activity CameraActivity = UnityPlayer.currentActivity;
Toast.makeText(CameraActivity , "first" ,Toast.LENGTH_LONG).show();
Log.d(" before ImageUrl###### ", "first");
CameraActivity.runOnUiThread(new Runnable()
{
public void run() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
CameraActivity.startActivityForResult(intent,1);
}
});
}
///////////////Don't activate↓//////////////////////////////////
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
Log.d(" before ImageUrl###### ", "twotwotwotwotwotwotwo"); //Don't activate
}
////////////////////////////////////////////////////////////////////////////
why don't activate this?
Try This,
Camera permission
private static final int REQUEST_CAMERA = 112;
btn_cam.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (Build.VERSION.SDK_INT >= 23) {
String[] PERMISSIONS = {android.Manifest.permission.CAMERA};
if (!hasPermissions(mContext, PERMISSIONS)) {
ActivityCompat.requestPermissions((Activity) mContext, PERMISSIONS, REQUEST_CAMERAE );
} else {
//open camera
}
} else {
//open camera
}
}
});
}
get Permissions Result
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case REQUEST_CAMERA: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//open camera
}
}
}
}
check permissions for marshmallow
private static boolean hasPermissions(Context context, String... permissions) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && context != null && permissions != null) {
for (String permission : permissions) {
if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
}
return true;
}
AndroidManifest.xml
<uses-permission android:name="android.permission.CAMERA" />
Related
I'm trying to download file via Download Manager in Instant app:
Uri uri = Uri.parse("https://images.pexels.com/photos/67636/rose-blue-flower-rose-blooms-67636.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260");
DownloadManager downloadManager = (DownloadManager) context.getSystemService(DOWNLOAD_SERVICE);
downloadManager.enqueue(new DownloadManager.Request(uri)
.setTitle("Demo")
.setDescription("Something useful. No, really.")
.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS,
"test.mp4"));
But getting an exception:
java.lang.IllegalStateException: Unable to create directory: /storage/emulated/0/Download
at android.app.DownloadManager$Request.setDestinationInExternalPublicDir(DownloadManager.java:539)
Is there other way to download files in Instant apps?
Issue seems it be related with Android Runtime Permission introduced in Android 6.0
When your app targeting API Level 23, by default all the permission is false you have to request permission dialog and approve the permission before using that into your app.
Ask the permission
public class RequestPermissionHandler {
private Activity mActivity;
private RequestPermissionListener mRequestPermissionListener;
private int mRequestCode;
public void requestPermission(Activity activity, #NonNull String[] permissions, int requestCode,
RequestPermissionListener listener) {
mActivity = activity;
mRequestCode = requestCode;
mRequestPermissionListener = listener;
if (!needRequestRuntimePermissions()) {
mRequestPermissionListener.onSuccess();
return;
}
requestUnGrantedPermissions(permissions, requestCode);
}
private boolean needRequestRuntimePermissions() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M;
}
private void requestUnGrantedPermissions(String[] permissions, int requestCode) {
String[] unGrantedPermissions = findUnGrantedPermissions(permissions);
if (unGrantedPermissions.length == 0) {
mRequestPermissionListener.onSuccess();
return;
}
ActivityCompat.requestPermissions(mActivity, unGrantedPermissions, requestCode);
}
private boolean isPermissionGranted(String permission) {
return ActivityCompat.checkSelfPermission(mActivity, permission)
== PackageManager.PERMISSION_GRANTED;
}
private String[] findUnGrantedPermissions(String[] permissions) {
List<String> unGrantedPermissionList = new ArrayList<>();
for (String permission : permissions) {
if (!isPermissionGranted(permission)) {
unGrantedPermissionList.add(permission);
}
}
return unGrantedPermissionList.toArray(new String[0]);
}
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions,
#NonNull int[] grantResults) {
if (requestCode == mRequestCode) {
if (grantResults.length > 0) {
for (int grantResult : grantResults) {
if (grantResult != PackageManager.PERMISSION_GRANTED) {
mRequestPermissionListener.onFailed();
return;
}
}
mRequestPermissionListener.onSuccess();
} else {
mRequestPermissionListener.onFailed();
}
}
}
public interface RequestPermissionListener {
void onSuccess();
void onFailed();
}
Use in Activity like this:
public class MainActivity extends AppCompatActivity {
private RequestPermissionHandler mRequestPermissionHandler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRequestPermissionHandler = new RequestPermissionHandler();
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
handleButtonClicked();
}
});
}
private void handleButtonClicked(){
mRequestPermissionHandler.requestPermission(this, new String[] {
Manifest.permission.RECEIVE_SMS, Manifest.permission.READ_EXTERNAL_STORAGE
}, 123, new RequestPermissionHandler.RequestPermissionListener() {
#Override
public void onSuccess() {
Toast.makeText(MainActivity.this, "request permission success", Toast.LENGTH_SHORT).show();
}
#Override
public void onFailed() {
Toast.makeText(MainActivity.this, "request permission failed", Toast.LENGTH_SHORT).show();
}
});
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions,
#NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
mRequestPermissionHandler.onRequestPermissionsResult(requestCode, permissions,
grantResults);
}
}
and don't forget to add this in your manifest
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
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'm trying to Call a number programmatically with the code provided below:
if(ActivityCompat.checkSelfPermission(MainActivity.this,Manifest.permission.CALL_PHONE)!=PackageManager.PERMISSION_GRANTED)
{
ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.CALL_PHONE},CALL);
}
else
{
String number="56789855";
Intent intent4=new Intent(Intent.ACTION_CALL);
intent4.setData(Uri.parse("tel:"+number));
startActivity(intent4);
}
I've set the permission in Android Manifest File as well:
<uses-permission android:name="android.permission.CALL_PHONE"> </uses-permission>
Android Studio throws an error called:
Missing Permissions required be intent Intent.ACTION_CALL:android.permission.CALL_PHONE
I can't seem to find why this error occurs.Any help will be appreciated.
Try this,
Required android.Manifest.permission.CALL_PHONE instead of Manifest.permission.CALL_PHONE
private Context mContext=YourActivity.this;
private static final int REQUEST = 112;
if (Build.VERSION.SDK_INT >= 23) {
String[] PERMISSIONS = {android.Manifest.permission.CALL_PHONE};
if (!hasPermissions(mContext, PERMISSIONS)) {
ActivityCompat.requestPermissions((Activity) mContext, PERMISSIONS, REQUEST );
} else {
makeCall();
}
} else {
makeCall();
}
get Permissions Result
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case REQUEST: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
makeCall();
} else {
Toast.makeText(mContext, "The app was not allowed to call.", Toast.LENGTH_LONG).show();
}
}
}
}
check permissions for marshmallow
private static boolean hasPermissions(Context context, String... permissions) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && context != null && permissions != null) {
for (String permission : permissions) {
if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
}
return true;
}
Manifest
<uses-permission android:name="android.permission.CALL_PHONE" />
call function:
public void makeCall()
{
String number="56789855";
Intent intent4=new Intent(Intent.ACTION_CALL);
intent4.setData(Uri.parse("tel:"+number));
startActivity(intent4);
}
I am trying to send sms targeted version 24 with runtime permission. It gives SecurityException in Redmi Mi 3s device but working fine on other device with Marshmallow OS.
final int REQ_CODE = 100;
void requestPermission(){
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.SEND_SMS) != PackageManager.PERMISSION_GRANTED) {
CTLogs.printLogs( "Permission is not granted, requesting");
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.SEND_SMS,Manifest.permission.READ_SMS,Manifest.permission.RECEIVE_SMS}, REQ_CODE);
// button.setEnabled(false);
} else {
CTLogs.printLogs("Permission has been granted");
sendSMS();
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == REQ_CODE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
CTLogs.printLogs("Permission has been granted");
sendSMS();
} else {
CTLogs.printLogs("Permission denied !!!");
}
}
}
Try this:
// The permission required by the application to work properly
protected static final String[] requiredPermissions;
private static final int PERMISSION_REQUEST = 0;
static {
List<String> perms = new ArrayList<>(Arrays.asList(
Manifest.permission.RECEIVE_SMS,
Manifest.permission.READ_SMS,
Manifest.permission.SEND_SMS
));
requiredPermissions = perms.toArray(new String[perms.size()]);
}
Call verifyPermissions() method in onCreate():
private void verifyPermissions() {
if (!hasAllPermissions()) {
// We don't have permission so prompt the user
ActivityCompat.requestPermissions(
this,
requiredPermissions,
PERMISSION_REQUEST
);
}
}
private boolean hasAllPermissions() {
// Check if we have all required permissions.
for (String perm : requiredPermissions) {
if (ActivityCompat.checkSelfPermission(this, perm) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
return true;
}
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case PERMISSION_REQUEST: {
// If request is cancelled, the result arrays are empty.
if (!hasAllPermissions()) {
finish();
}
return;
}
}
}
once a uninstall app then put this and then install it.
if (ContextCompat.checkSelfPermission(MainActivity.this,
Manifest.permission.SEND_SMS)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.SEND_SMS},
MY_PERMISSIONS_REQUEST_READ_CONTACTS);
}
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;
}
}