Permission error is still showing even when added permission in manifest - android

I implemented AlertDialog in my class which extend Application class, also added proper permission in manifest file:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
See my code:
private void showAlertDialog(Context context) {
DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// do some stuff eg: context.onCreate(super)
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(context)
.setCancelable(false)
.setMessage("Messag...")
.setTitle("Title")
.setPositiveButton("OK", listener);
Dialog dialog = builder.create();
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
dialog.show();
}
Call Method:
showAlertDialog(getApplicationContext());
I tried this answer, it was working yesterday, now is not working: How to show Dialog Box from the class which extends Application in android?
BTW, it was working yesterday, I don't know why it is not working today, what am I missing?

Did you define runtime permissions if you are checking in marshmallow or above API level devices?
Check the overlay permission
public static int OVERLAY_PERMISSION_REQ_CODE = 1234;
public void someMethod() {
if (!Settings.canDrawOverlays(this)) {
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, OVERLAY_PERMISSION_REQ_CODE);
}}
In onActivityResult,
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == OVERLAY_PERMISSION_REQ_CODE) {
if (!Settings.canDrawOverlays(this)) {
// SYSTEM_ALERT_WINDOW permission not granted...
}
}
}
Finally----
Check if the device has API 23+
if 23+ API then check if the user has permission or not
if had permit once don't drive him to Settings.ACTION_MANAGE_OVERLAY_PERMISSION and if has not to permit yet then ask for runtime permission check
Put below the line in your onCreate() method. Put this after setContentView()
checkPermission();
Now put below code in onActivityResult,
#TargetApi(Build.VERSION_CODES.M)
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE) {
if (!Settings.canDrawOverlays(this)) {
// You don't have permission
checkPermission();
} else {
// Do as per your logic
}
}
}
Now finally the checkPermission method code,
public void checkPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!Settings.canDrawOverlays(this)) {
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE);
}
}}
And declare a variable as global
public static int ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE = 5469;
Happy Coding :)

Related

Passing extra data in startActivityForResult is received null in onActivityResult from another class

I am new to Android development and I am working on a personal project which uses google map and image loading, among others.
I cannot figure out why, when using startActivityForResult combined with onActivityResult from 2 different classes of the same package it does not parse extra data inserted with putExtra
Code:
package com.example.gui;
class InitialMapLoad {
...
lGMap.setOnMapLongClickListener(new GoogleMap.OnMapLongClickListener() {
#Override
public void onMapLongClick(LatLng latLng) {
final LatLng mClickPos = latLng;
ImageView image = new ImageView(lActivity);
image.setImageResource(R.drawable.pin_on_map);
AlertDialog.Builder imgSelectPopup = new AlertDialog.Builder(lActivity);
imgSelectPopup.setTitle(R.string.addImageCoords);
imgSelectPopup.setNegativeButton(R.string.cancelAction, null);
imgSelectPopup.setPositiveButton(R.string.btnOpenGallery, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Intent pickPhoto = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
pickPhoto.putExtra("gpsLng", String.valueOf(mClickPos.longitude));
lActivity.startActivityForResult(pickPhoto , LOAD_IMG_REQUEST);
}
});
}
and the main activity class
package com.example.gui;
public class gui extends AppCompatActivity {
...
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) {
super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
if (requestCode == LOAD_IMG_REQUEST) {
if(resultCode == RESULT_OK){
Uri selectedImage = imageReturnedIntent.getData();
Log.e(TAG, "onActivityResult: " + selectedImage ); // this is OK
Log.e(TAG, "onActivityResult: " + imageReturnedIntent.getStringExtra("gpsLng") ); // this is null
}
}
}
}
As noted in the comments, the getStringExtra("gpsLng") is null.
Am I missing something? Is there another recommended way to do this?
Thank you in advance!

How to start overlay window setting from app in react-native

I need to open overlay setting window for my app. Of course, my manifest file use SYSTEM_ALERT_WINDOW permission already.
public class MainActivity extends ReactActivity {
private static final int CODE_DRAW_OVER_OTHER_APP_PERMISSION = 2084;
#Override
protected String getMainComponentName() {
return "MyToolbox";
}
#Override
protected ReactActivityDelegate createReactActivityDelegate() {
return new ReactActivityDelegate(this, getMainComponentName()) {
#Override
protected ReactRootView createRootView() {
return new RNGestureHandlerEnabledRootView(MainActivity.this);
}
};
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requireDrawOverlayPermission();
}
//Ask draw overlay permission
void requireDrawOverlayPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.canDrawOverlays(this)) {
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package: " + getPackageName()));
startActivityForResult(intent, CODE_DRAW_OVER_OTHER_APP_PERMISSION);
} else {
//TODO: Permission granted
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CODE_DRAW_OVER_OTHER_APP_PERMISSION) {
if (Settings.canDrawOverlays(this)) {
//TODO: Permission granted
} else {
Toast.makeText(this, "Draw over the app is not available", Toast.LENGTH_SHORT).show();
}
} else {
super.onActivityResult(requestCode, resultCode, data);
}
}
}
The first debug run from my Android Studio, my app got crashed.
And next time, it's not crash, but it doesn't show overlay setting window for me. I can see a screen is flashed but close immediately.
What wrong in my code?
Thank you!
Finally, I figured it out afterall. That settings window need package name to know which app require this permission. And the uri can't parse my package name because I put a space between "package:" and "getPackageName()". I removed it as below, and everything works fine!
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName()));

Storage permission not working for Nougat

I want to give storage permission for my app. My code working perfect till Marshmallow, only problem in Nougat
The below method always return false in nougat even permission granted manually from settings.
private boolean checkWriteExternalPermission() {
String permission = "android.permission.WRITE_EXTERNAL_STORAGE";
int res = getApplicationContext().checkCallingOrSelfPermission(
permission);
return (res == PackageManager.PERMISSION_GRANTED);
}
I used this for Nougat and allow permission but above method still returns false.
void storagePermission(){
StorageManager sm = (StorageManager)getSystemService(Context.STORAGE_SERVICE);
StorageVolume volume = sm.getPrimaryStorageVolume();
Intent intent = volume.createAccessIntent(Environment.DIRECTORY_PICTURES);
startActivityForResult(intent, 1);
}
Please help me to resolve this.
You should use libs: https://github.com/hotchemi/PermissionsDispatcher
#RuntimePermissions
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MainActivityPermissionsDispatcher.storagePermissionWithCheck(this);
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
// NOTE: delegate the permission handling to generated method
MainActivityPermissionsDispatcher.onRequestPermissionsResult(this, requestCode, grantResults);
}
#NeedsPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
void storagePermission(){
StorageManager sm =(StorageManager)getSystemService(Context.STORAGE_SERVICE);
StorageVolume volume = sm.getPrimaryStorageVolume();
Intent intent = volume.createAccessIntent(Environment.DIRECTORY_PICTURES);
startActivityForResult(intent, 1);
}
#OnPermissionDenied(Manifest.permission.WRITE_EXTERNAL_STORAGE)
void showDeniedForCamera() {
// don't allow code here
}
#OnNeverAskAgain(Manifest.permission.WRITE_EXTERNAL_STORAGE)
void showNeverAskForCamera() {
// neverAskAgain code here
}
}
You should add this code:
public void onActivityResult(final int requestCode, int resultCode, final Intent data){
if(requestCode==1) {
switch (resultCode) {
case Activity.RESULT_OK:
getContentResolver().takePersistableUriPermission(data.getData(),
Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
break;
}
}
}

Android check permission before Main activity

on my app i have implemented a splash activity that check if is first run app and if is true show a dialog message, this is the code:
public void onConnected(Bundle connectionHint) {
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
myLocation = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
}
SharedPreferences getPrefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
boolean isFirstStart = getPrefs.getBoolean("firstStart", true);
if (isFirstStart) {
android.app.AlertDialog alertDialog = new android.app.AlertDialog.Builder(splashscreen.this).create();
alertDialog.setTitle(getResources().getString(R.string.titolo_intro_sms));
alertDialog.setMessage(getResources().getString(R.string.intro_sms));
alertDialog.setButton(android.app.AlertDialog.BUTTON_NEUTRAL, "OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
Intent i = new Intent(splashscreen.this, MainActivity.class);
startActivity(i);
}
});
alertDialog.show();
SharedPreferences.Editor e = getPrefs.edit();
e.putBoolean("firstStart", false);
e.apply();
} else {
startApp();
}
}
When dialog are show if click ok i open MainActivity. Now after 'Ok' click into dialog befor to start MainActivity i would like to show a dialog request permission.
I have create a abstract class for this and i call in this way:
requestAppPermissions(new String[]{
Manifest.permission.ACCESS_COARSE_LOCATION},
R.string.msg,REQUEST_PERMISSION);
Now i set this line code into OnCreate the permission request are show before the splash activity but if i set into onClick methos of 'ok' allert dialog is not show.
How i can show the permission request after click ok befor to start Main Activity?
Any help is great
Thanks
I have integrate my onRequestPermissionresult into abstract class in this way:
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
int permissionCheck = PackageManager.PERMISSION_GRANTED;
for(int permisson : grantResults) {
permissionCheck = permissionCheck + permisson;
}
if( (grantResults.length > 0) && PackageManager.PERMISSION_GRANTED == permissionCheck) {
onPermissionsGranted(requestCode);
Intent i = new Intent(this, MainActivity.class); //start activity
startActivity(i);
} else {
//Display message when contain some Dangerous permisson not accept
Snackbar.make(findViewById(android.R.id.content), mErrorString.get(requestCode),
Snackbar.LENGTH_INDEFINITE).setAction("ENABLE", new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent();
i.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
i.setData(Uri.parse("package:" + getPackageName()));
i.addCategory(Intent.CATEGORY_DEFAULT);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
i.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
startActivity(i);
}
}).show();
}
}
and the message permission are show after ok click but after the app close and not open MainActivity
i have change my splashcrenn and i have set all method about permsion into it, this is code:
public void onPermissionsGranted(int requestCode) {
}
public void requestAppPermissions(final String[]requestedPermissions, final int stringId, final int requestCode) {
mErrorString.put(requestCode, stringId);
int permissionCheck = PackageManager.PERMISSION_GRANTED;
boolean showRequestPermissions = false;
for(String permission: requestedPermissions) {
permissionCheck = permissionCheck + ContextCompat.checkSelfPermission(this, permission);
showRequestPermissions = showRequestPermissions || ActivityCompat.shouldShowRequestPermissionRationale(this, permission);
}
if (permissionCheck!=PackageManager.PERMISSION_GRANTED) {
if(showRequestPermissions) {
Snackbar.make(findViewById(android.R.id.content), stringId, Snackbar.LENGTH_INDEFINITE).setAction("GRANT", new View.OnClickListener() {
#Override
public void onClick(View v) {
ActivityCompat.requestPermissions(splashscreen.this, requestedPermissions, requestCode);
}
}).show();
} else {
ActivityCompat.requestPermissions(this, requestedPermissions, requestCode);
}
} else {
onPermissionsGranted(requestCode);
}
}
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case 1: {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(getApplicationContext(), "Permission granted", Toast.LENGTH_SHORT).show();
Intent i = new Intent(splashscreen.this, MainActivity.class); //start activity
splashscreen.this.startActivity(i);
} else {
Toast.makeText(getApplicationContext(), "Permission denied", Toast.LENGTH_SHORT).show();
}
return;
}
// other 'case' lines to check for other
// permissions this app might request
}
}
into dialog 'ok' click button i have set this:
alertDialog.setButton(android.app.AlertDialog.BUTTON_NEUTRAL, "OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions(splashscreen.this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, 1);
/*Intent i = new Intent(splashscreen.this, MainActivity.class);
startActivity(i);*/
}
});
alertDialog.show();
but when i click ok the app close and not open MainActivity
try this:
show permission dialog in button click:
alertDialog.setButton(android.app.AlertDialog.BUTTON_NEUTRAL, "OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, 1); //show reuest dialog
}
});
alertDialog.show();
Now catch the result in onRequestPermissionsResult() and start your MainActivity
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case 1: {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(getContext(), "Permission granted", Toast.LENGTH_SHORT).show();
Intent i = new Intent(splashscreen.this, MainActivity.class); //start activity
startActivity(i);
} else {
Toast.makeText(getContext(), "Permission denied", Toast.LENGTH_SHORT).show();
}
return;
}
// other 'case' lines to check for other
// permissions this app might request
}
}
in your abstract class pass your activity context and use it to start MainActivity
To pass context:
class YourAbstractClass{
// variable to hold context
private Context context;
//save the context recievied via constructor in a local variable
public YourAbstractClass(Context context){ //constructor
this.context=context;
}
}
In your splash Activity call your Abstract class like:
YourAbstractClass class = new YourAbstractClass(this); //pass context
Now use the context to startActivity
Intent myIntent = new Intent(context, MainActivity.class);
context.startActivity(myIntent);
Request the permission after you click ok, but don't start the activity right away. Wait for the result in onRequestPermissionResult, and start your MainActivity there.
Use if-else statement in your button call.
If you already have permission then execute the MainActivity call in
if part. If not then ask for permission in else part of if-else.
Now use OnRequestPermissionResult method to which is called when permissions are granted or denied. If permissions are granted in this method then again execute the MainActivity call or else just do what you need to do when permission denied like show him the reason why you need permission and try again or just exit.
Hope it helped. For everything about permissions in android in a simplified version just click HERE (http://www.vogella.com/tutorials/AndroidPermissions/article.html).

Refreshing activity after user changed location settings

User flow: Clicks a button, is redirected to MapActivity where a google maps is shown. A location is given, there is a button to make a route using current location to the given location. When location services is turned off the user is prompted to turn it on.
private void goToLocationSettings(){
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS );
startActivityForResult(intent, 1);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == 1) {
switch (requestCode) {
case 1: Log.e("test", "onActivityResult");
break;
}
}
}
When the user returns the function should be able to complete. But the program again to turn the settings on. The log is never shown.
If I wait a bit after turning on location services on my device I do not get the question to turn it on, but the log message is still not shown.
I have no idea what I am doing wrong.
You are checking for the wrong resultCode, to avoid confusion use constants Activity#RESULT_OK and Activity#RESULT_CANCELED. If you check the docs you can see that RESULT_OK has an int value of -1.
In the case of starting Location Settings Activity for result, the resultCode will always be 0 because the user exits the Settings Activity with a back button, so to the system it looks like he canceled the request.
static final int LOCATION_SETTINGS_REQUEST = 1;
protected void onActivityResult(int requestCode, int resultCode,
Intent data) {
if (requestCode == LOCATION_SETTINGS_REQUEST) {
// user is back from location settings - check if location services are now enabled
checkGPS();
}
}
The dialog box with out a result intent can be like this we need to allow the user to navigate and check the location services
accepted
In the case of starting Location Settings Activity for result, the resultCode will always be 0 because the user exits the Settings Activity with a back button, so to the system it looks like he canceled the request.
The code is here like which allow the dilog to navigate to setting page .
public void showLocationAlert() {
if (!ismctLocationEnabled(this)) {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(ContentTransferBaseActivity.this);
alertDialog.setTitle(R.string.mct_enable_Location_title);
alertDialog.setMessage(R.string.mct_enable_location_message);
alertDialog.setCancelable(true);
alertDialog.setPositiveButton(R.string.mct_button_Enable,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);
}
});
alertDialog.setNegativeButton(R.string.mct_button_Dismiss,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
if(!ismctLocationEnabled(this)) {
alertDialog.show();
}else
{
AlertDialog dialog=alertDialog.create();
dialog.dismiss();
}
}
}
public static boolean ismctLocationEnabled(Context context) {
int locationMode = 0;
String locationProviders;
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
try {
locationMode = Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.LOCATION_MODE);
} catch (Settings.SettingNotFoundException e) {
e.printStackTrace();
return false;
}
return locationMode != Settings.Secure.LOCATION_MODE_OFF;
} else {
locationProviders = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
return !TextUtils.isEmpty(locationProviders);
}
}

Categories

Resources