I'm not able to allow the app to write to external storage when other background app like twilight (dims screen) runs in the background. In this case, I can only deny it and it says screen overlay detected. But can't allow.
My code:
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
boolean hasPermission = (ContextCompat.checkSelfPermission(Timetable.this,
Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED);
if (!hasPermission) {
ActivityCompat.requestPermissions(Timetable.this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
1);
}
}
Override code:
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode)
{
case 1: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
{
//Intent i=new Intent(this,Timetable.class);
//startActivity(i);
//reload my activity with permission granted or use the features what required the permission
} else
{
Toast.makeText(Timetable.this, "The app was not allowed to write to your storage. Hence, it cannot function properly. Please consider granting it this permission", Toast.LENGTH_LONG).show();
}
}
}
}
I want it running even if some background apps like twilight are running.
Downloading a certain file using Android's built in Download Manager provides integrity and a more User Friendly approach. Also the requestPermission method should be called before doing that if the devices having Marshmallow and above are to be supported as well.
And about the allow button not working, that issue is because of apps or activities who capture the screen overlay. Like for instance Facebook messenger or any screen dimming apps. Hence to make it robust you need to check the permission everytime you download something.
public void downloadFile(String uRl) {
File direct = new File(Environment.getExternalStorageDirectory()
+ "/" + "MyFolder");
if (!direct.exists()) {
direct.mkdirs();
}
DownloadManager mgr = (DownloadManager) getSystemService(this.DOWNLOAD_SERVICE);
Uri downloadUri = Uri.parse(uRl);
DownloadManager.Request request = new DownloadManager.Request(downloadUri);
request.setAllowedNetworkTypes(
DownloadManager.Request.NETWORK_WIFI
| DownloadManager.Request.NETWORK_MOBILE)
.setAllowedOverRoaming(false)
.setTitle("AppNameAsTitle")
.setDescription("Downloaded using My app")
.setDestinationInExternalPublicDir("/MyFolder", "filename.jpg")
.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
mgr.enqueue(request);
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
downloadFile(url);
} else {
Toast.makeText(this, "Permission not granted", Toast.LENGTH_SHORT).show();
}
}
Related
So i'm trying to request both Location and Camera permissions from the user, and my app all works apart from the part where it has to request Location permissions from the user. The user never gets a request to access location. Is it even possible to request 2 different permissions and have onRequestPermissionsResults to handle them both in the same class?
#Override
public void onClick(View v) {
if (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(
HomePageActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_CODE_LOCATION_PERMISSION
);
} else {
getCurrentLocation();
}
askCameraPermissions();
}
this is how it starts, then I think it goes here
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case REQUEST_CODE_LOCATION_PERMISSION:
if (grantResults.length > 0) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
getCurrentLocation();
} else {
Toast.makeText(this, "Permission denied", Toast.LENGTH_LONG).show();
}
}
break;
case CAMERA_PERM_CODE:
//if both are true then user has granted requests
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
dispatchTakePictureIntent();
} else {
Toast.makeText(this, "Camera permission is required to Use camera.", Toast.LENGTH_SHORT).show();
}
break;
}
}
'''
except I believe this is where the application is doing something wrong. The camera request and permission works perfectly and I am able to continue and have my camera methods work. However when it comes to Location permissions, as i said, the user is never prompted to allow permissions, so I think something is going wrong here. Any help is appreciated, this is my first post so maybe formatting will be strewn with errors.
I have tried to post only relevant code. I will post more if requested
Rather then asking permission two times which is causing the problem you can actually ask it in a single time like
....
ActivityCompat.requestPermissions(
HomePageActivity.this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.CAMERA},
REQUEST_CODE_MULTIPLE_PERMISSION
);
....
if you still want to ask separate permission then you should ask after the first one result has arrived.
EDIT
while asking for access fine location you should also ask for coarse location
I am trying to code a quick application which gives me the needed 3G values, when I click a button.
But first I need to check if I am connected to 3G network.
However I am having some issues with my Permissions.
I am having the following code:
public void calculate(View view) {
TextView rscp = (TextView) findViewById(R.id.RSCP);
TextView rssi = (TextView) findViewById(R.id.RSSI);
TextView ecno = (TextView) findViewById(R.id.EcNo);
TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
if (Arrays.stream(values_3G).anyMatch(n -> n == tm.getDataNetworkType())) {
for (CellInfo cellInfo : tm.getAllCellInfo()) {
if (cellInfo instanceof CellInfoWcdma) {
CellSignalStrengthWcdma cellSignalStrength = ((CellInfoWcdma) cellInfo).getCellSignalStrength();
rscp.setText(cellSignalStrength.getDbm());
ecno.setText(cellSignalStrength.getEcNo());
int rssiValue = -113 + 2 * cellSignalStrength.getAsuLevel();
rssi.setText(rssiValue);
}
}
} else {
rscp.setText(0);
rssi.setText(0);
ecno.setText(0);
Log.i(TAG, "No 3G Mobile connection detected!");
Toast.makeText(getApplicationContext(), "Connect to 3G", Toast.LENGTH_SHORT).show();
}
}
tm.getDataNetworkType() is giving me the following issue with READ_PHONE_STATE:
Call requires permission which may be rejected by user: code should explicitly check to see if permission is available (with checkPermission) or explicitly handle a potential SecurityException
If I follow the instructions to check permission in Android Studio I get the following:
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
What do I need to fill in between the brackets?
Create a global final int of the permission request code
final int PHONE_REQUEST_CODE = 101;
And request the permission if not granted
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.READ_PHONE_STATE},
PHONE_REQUEST_CODE); // triggers onRequestPermissionsResult()
} else {
// calculate(myView); // Do whatever you want as the permission is already granted
}
And override onRequestPermissionsResult() in activity
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (grantResults.length == 0)
return;
if (requestCode == PHONE_REQUEST_CODE) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// calculate(myView); // Do whatever you want after the permission is granted
}
And add the permission in manifest.xml as well.
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
I cannot make this work, I have an application with a webview that requires permissions to access storage when downloading, I am trying that, when the user rejects permissions, my application tells them how to activate the permission by accessing the application settings.
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
Uri.fromParts("package", getActivity().getPackageName(), null));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivityForResult(intent, MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE);
s
#Override
public void onRequestPermissionsResult(int requestCode,
String[] permissions, int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE: {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//Permission is granted
myWebView.loadUrl(urlDownload);
} else {
}
return;
}
case MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
openImageChooserActivity();
} else {
}
return;
}
// other 'case' lines to check for other
// permissions this app might request.
}
}
myWebView.loadUrl(urlDownload); this code snippet runs without problem when permission is granted from android alert but I can't control it if the user grants the permission from the settings.
Finally, a newbie question, I have seen several examples of similar codes that seem to work, but I do not understand how setResult is handled in the configurations because I do not have access to it, if for example MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE = 101 how is it that android configurations know to put setResult (101) when user activates storage?
I have this app that will pick image to gallery and display it to the test using Imageview. My problem is it won't work on Android M. I can pick image but won't show on my test.They say i need to ask permission to access images on android M but don't know how. please help.
Beginning in Android 6.0 (API level 23), users grant permissions to apps while the app is running, not when they install the app.
Type 1- When your app requests permissions, the system presents a dialog box to the user. When the user responds, the system invokes your app's onRequestPermissionsResult() method, passing it the user response. Your app has to override that method to find out whether the permission was granted. The callback is passed the same request code you passed to requestPermissions().
private static final int PICK_FROM_GALLERY = 1;
ChoosePhoto.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick (View v){
try {
if (ActivityCompat.checkSelfPermission(EditProfileActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(EditProfileActivity.this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, PICK_FROM_GALLERY);
} else {
Intent galleryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(galleryIntent, PICK_FROM_GALLERY);
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String permissions[], #NonNull int[] grantResults)
{
switch (requestCode) {
case PICK_FROM_GALLERY:
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Intent galleryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(galleryIntent, PICK_FROM_GALLERY);
} else {
//do something like displaying a message that he didn`t allow the app to access gallery and you wont be able to let him select from gallery
}
break;
}
}
Type 2- If you want to give runtime permission back to back in one place then you can follow below link
Android 6.0 multiple permissions
And in Manifest add permission for your requirements
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
Note- If Manifest.permission.READ_EXTERNAL_STORAGE produce error then please replace this with android.Manifest.permission.READ_EXTERNAL_STORAGE.
==> If you want to know more about runtime permission then please follow below link
https://developer.android.com/training/permissions/requesting.html
-----------------------------UPDATE 1--------------------------------
Runtime Permission Using EasyPermissions
EasyPermissions is a wrapper library to simplify basic system permissions logic when targeting Android M or higher.
Installation
Add dependency in App level gradle
dependencies {
// For developers using AndroidX in their applications
implementation 'pub.devrel:easypermissions:3.0.0'
// For developers using the Android Support Library
implementation 'pub.devrel:easypermissions:2.0.1'
}
Your Activity (or Fragment) override the onRequestPermissionsResult method:
#Override
public void onRequestPermissionsResult(int requestCode, String[]
permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions,grantResults);
// Forward results to EasyPermissions
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
}
Request Permissions
private static final int LOCATION_REQUEST = 222;
Call this method
#AfterPermissionGranted(LOCATION_REQUEST)
private void checkLocationRequest() {
String[] perms = {Manifest.permission.ACCESS_FINE_LOCATION};
if (EasyPermissions.hasPermissions(this, perms)) {
// Already have permission, do the thing
// ...
} else {
// Do not have permissions, request them now
EasyPermissions.requestPermissions(this,"Please grant permission",
LOCATION_REQUEST, perms);
}
}
Optionally, for a finer control, you can have your Activity / Fragment implement the PermissionCallbacks interface.
implements EasyPermissions.PermissionCallbacks
#Override
public void onPermissionsGranted(int requestCode, List<String> list) {
// Some permissions have been granted
// ...
}
#Override
public void onPermissionsDenied(int requestCode, List<String> list) {
// Some permissions have been denied
// ...
}
Link -> https://github.com/googlesamples/easypermissions
-----------------------------UPDATE 2 For KOTLIN--------------------------------
Runtime Permission Using florent37
Installation Add dependency in App level gradle
dependency
implementation 'com.github.florent37:runtime-permission-kotlin:1.1.2'
In Code
askPermission(
Manifest.permission.CAMERA,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
) {
// camera or gallery or TODO
}.onDeclined { e ->
if (e.hasDenied()) {
AlertDialog.Builder(this)
.setMessage(getString(R.string.grant_permission))
.setPositiveButton(getString(R.string.yes)) { dialog, which ->
e.askAgain()
} //ask again
.setNegativeButton(getString(R.string.no)) { dialog, which ->
dialog.dismiss()
}
.show()
}
if (e.hasForeverDenied()) {
e.goToSettings()
}
}
Link-> https://github.com/florent37/RuntimePermission
public void pickFile() {
int permissionCheck = ContextCompat.checkSelfPermission(getActivity(),
CAMERA);
if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(
getActivity(),
new String[]{CAMERA},
PERMISSION_CODE
);
return;
}
openCamera();
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String permissions[],
#NonNull int[] grantResults) {
if (requestCode == PERMISSION_CODE) {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
openCamera();
}
}
}
private void openCamera() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, CAMERA_CODE);
}
<uses-permission android:name="android.permission.CAMERA" />
I have a weird bug that is driving me crazy. I'm working on Android Marshmallow and I'm implementing the new permissions. When I click my Login button, I check to see if the user has gps permissions. If not, I request them. The way the code works is that after permissions are asked, an Async task is called to get some settings from a REST service, then on the onPostExecute of the Async task, it will fire an Intent.
When the user Allows permissions, everything works fine. If the user denies permissions, it will call the Async task and call the Intent, but it will not activate the Intent. It simply stays on the screen.
The Button Click
Button btnLogin = (Button) findViewById(R.id.btnLogin);
btnLogin.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view)
{
int has_permission = 0;
if (Build.VERSION.SDK_INT >= 23)
{
has_permission = Check_Permission(Manifest.permission.ACCESS_FINE_LOCATION);
}
action = "login";
if(has_permission == 0)
{
Get_Location();
load_system_settings_async = new Load_System_Settings_Async();
load_system_settings_async.execute((Void) null);
}
}
});
Check Permission Code
protected int Check_Permission(final String permission)
{
int has_permission = checkSelfPermission(permission);
if (has_permission != PackageManager.PERMISSION_GRANTED)
{
if (!shouldShowRequestPermissionRationale(permission) && (request_times > 0))
{
String title="";
if(permission.equals(Manifest.permission.ACCESS_FINE_LOCATION))
{
title = "You need to allow GPS access";
}
else if(permission.equals(Manifest.permission.WRITE_EXTERNAL_STORAGE))
{
title = "You need to allow storage access";
}
else if(permission.equals(Manifest.permission.CALL_PHONE))
{
title = "You need to allow access phone access";
}
Show_Alert_Dialog("Ok", title,
new DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface dialog, int which)
{
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
Uri.fromParts("package", getPackageName(), null));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
//requestPermissions(new String[] {permission}, REQUEST_CODE_ASK_PERMISSIONS);
}
});
return has_permission;
}
requestPermissions(new String[] {permission}, REQUEST_CODE_ASK_PERMISSIONS);
request_times++;
return has_permission;
}
return has_permission;
}
Permission Request
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults)
{
if (requestCode == 123)
{
if(grantResults[0] == 0)
{
Get_Location();
}
load_system_settings_async = new Load_System_Settings_Async();
load_system_settings_async.execute((Void) null);
//request_times = 0;
}
else
{
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
it seems like the problem is when user denied the permission ,control fall in onRequestPermissionsResult where you are executing your asynch task even if the permission is not granted .check comment in following code
public void onRequestPermissionsResult(int requestCode, #NonNull String[]
permissions, #NonNull int[] grantResults)
{
if (requestCode == 123) // yes request code is the same go on
{
if(grantResults[0] == 0) //yes we get the approval
{
Get_Location();
}
// oh even if we didn't get the approval we still gonna execute the task
load_system_settings_async = new Load_System_Settings_Async();
load_system_settings_async.execute((Void) null);
//request_times = 0;
}
else //control only come here when request code will not match
{
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
you need to combine the if condition like this
if (requestCode == 123 && grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Ok, I figured it out .. When I was passing a custom Object with putExtra in the Intent, there was a property that was null, so when it was executing writeToParcel in the object, it was crashing. Unfortunately, Android kept executing with out crashing .. it just did nothing. I simply added a setter to the object and set the value to false. Issue had nothing to do with the Permission code. Four hours of life and sleep lost that I will not get back. Thanks all for who viewed.