How can I programmatically grant the permission in Settings -> Apps -> Draw over other apps in Android? I want to use system alert window but unable to in Android Marshmallow without forcing the user to go through the Settings app and grant the permission first.
You can check and ask for overlay permission to draw over other apps using this
if (!Settings.canDrawOverlays(this)) {
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, 0);
}
if (!Settings.canDrawOverlays(this)) {
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, 0);
}
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
Here's the code for automatic granting the SYSTEM_ALERT_WINDOW permission to the package. To run this code, your Android application must be system (signed by platform keys).
This method is based on the following Android source code files: AppOpsManager.java and DrawOverlayDetails.java, see the method DrawOverlayDetails.setCanDrawOverlay(boolean newState).
#TargetApi(Build.VERSION_CODES.KITKAT)
public static void autoSetOverlayPermission(Context context, String packageName) {
PackageManager packageManager = context.getPackageManager();
int uid = 0;
try {
ApplicationInfo applicationInfo = packageManager.getApplicationInfo(packageName, 0);
uid = applicationInfo.uid;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
return;
}
AppOpsManager appOpsManager = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);
final int OP_SYSTEM_ALERT_WINDOW = 24;
try {
Class clazz = AppOpsManager.class;
Method method = clazz.getDeclaredMethod("setMode", int.class, int.class, String.class, int.class);
method.invoke(appOpsManager, OP_SYSTEM_ALERT_WINDOW, uid, packageName, AppOpsManager.MODE_ALLOWED);
Log.d(Const.LOG_TAG, "Overlay permission granted to " + packageName);
} catch (Exception e) {
Log.e(Const.LOG_TAG, Log.getStackTraceString(e));
}
}
}
The code has been tested in Headwind MDM project, it successfully grants "Draw over other apps" permission without any user consent to the Headwind Remote application (disclaimer: I'm the project owner of Headwind MDM and Headwind Remote), when Headwind MDM application is signed by platform keys. The code has been tested on Android 10 (LineageOS 17).
Check this question and the answer:
SYSTEM_ALERT_WINDOW - How to get this permission automatically on Android 6.0 and targetSdkVersion 23
"Every app that requests the SYSTEM_ALERT_WINDOW permission and that is installed through the Play Store (version 6.0.5 or higher is required), will have granted the permission automatically."
Related
Some Android phones don't do anything when the the code below is ran. It's supposed to open the "About device" page in Settings.
For example, I know for a fact that it has no effect on the Huawei Y9 Prime 2019 running Android 10.
startActivity(new Intent(Settings.ACTION_DEVICE_INFO_SETTINGS));
What's the best way to safeguard against this issue when it occurs? (In my app, I open this page to ask the user to perform a specific action there)
Use PackageManager.resolveActivity() to check whether such an Activity exists. If that returns null, there is no activity that matches the Intent and you have to guide your customers to the settings in another way:
Intent intent = new Intent(Settings.ACTION_DEVICE_INFO_SETTINGS);
ResolveInfo resolveInfo = getPackageManager().resolveActivity(intent, 0);
if (resolveInfo == null) {
// help customers by describing how to get to the device info settings
} else {
startActivity(intent);
}
If an activity is not found, the method startActivity will throw android.content.ActivityNotFoundException. You should catch this exception and notify the user:
try {
startActivity(new Intent(Settings.ACTION_DEVICE_INFO_SETTINGS));
} catch (ActivityNotFoundException e) {
// Notify the user, eg. using a popup so they can open settings manually
}
I am new to Android, now I am working on a Project which is based on GPS. I got source code from internet(traccar). my requirement is like the app should update location on each 1Km or each 1hr. but the problem is the app not working in background after some time(10 - 20 mins). Is there any solution for this ?
what should I do(in code) to exclude this app from battery optimisation when the app is launching ? is it possible ?
I think you're having 2 different problems:
1) If you want to keep your app in background you should use a foreground Service. That way your app won't be considered to be in background by the system and the chances of its process being killed are reduced drastically. The downside is that as long as your Service is in foreground you need to show a permanent notification.
2) You cannot exclude your app from battery optimization yourself, but you can prompt the user the settings to whitelist your app. In order to do that you can refer to the official docs, you'll need to add the Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS permission to the manifest and then launch an intent with action ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS. The user will then be able to whitelist your app, only she/he can do that because otherwise every app would whitelist itself and the purpose of the battery optimization would be defied.
Add this permission in your manifest file Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
Request Permission at runtime inside onCreate method of your activity...
PowerManager powerManager = (PowerManager) getApplicationContext().getSystemService(POWER_SERVICE);
String packageName = "org.traccar.client";
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
Intent i = new Intent();
if (!powerManager.isIgnoringBatteryOptimizations(packageName)) {
i.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
i.setData(Uri.parse("package:" + packageName));
startActivity(i);
}
}
This is the image of the code in debug mode:
This will be the view in app:
but the application not working as it is in No Restriction mode (background activity).
I want the application to work as No Restriction mode.
Add this permission in your manifest file
Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
Request Permission at runtime inside onCreate method of your activity...
private final int MY_PERMISSIONS_IGNORE_BATTERY_OPTIMIZATIONS =1;
if (ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)
!= PackageManager.PERMISSION_GRANTED) {
// Permission is not granted
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(this,
arrayOf(Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS),
MY_PERMISSIONS_IGNORE_BATTERY_OPTIMIZATIONS)
// app-defined int constant. The callback method gets the
// result of the request.
}
} else {
// Permission has already been granted
}
Here is the kotlin version of #Shafeeq Mohammed Answer and it worked for me. Thank you
fun checkBatteryOptimization(mContext: Context) {
val powerManager =
mContext.getSystemService(POWER_SERVICE) as PowerManager
val packageName = mContext.packageName
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val i = Intent()
if (!powerManager.isIgnoringBatteryOptimizations(packageName)) {
i.action = Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
i.data = Uri.parse("package:$packageName")
mContext.startActivity(i)
}
}
}
I want to create an app,that's use to only allow access specific apps in a device.So I tried to pinned the device.Now I want to open another application that is in my specific apps list.
I can't open another app while pinned.
This is the code I used to pinned
startLockTask();
and this is the code to I tried to open another appilication in kiosk mode
ComponentName deviceAdmin = new ComponentName(KioskActivity.this, MyAdmin.class);
if (myDevicePolicyManager.isDeviceOwnerApp(getPackageName()))
{
myDevicePolicyManager.setLockTaskPackages(deviceAdmin, new String[]{getPackageName(), "com.example.pan.pocmdmhelper"});
try
{
PackageManager pm = KioskActivity.this.getPackageManager();
Intent it = pm.getLaunchIntentForPackage("com.example.pan.pocmdmhelper");
it.addCategory(Intent.CATEGORY_LAUNCHER);
if (null != it) {
KioskActivity.this.startActivity(it);
Toast.makeText(KioskActivity.this, "Started activity for this package", Toast.LENGTH_SHORT).show();
}
}
catch (Exception e)
{
Toast.makeText(KioskActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
finish();
}
}
At the moment I tried to open single app by using it's package name.It's open if I unpinned only
I have this code working well on Android 4.0.4.
// Create the new Intent using the 'Send' action.
Intent share = new Intent(Intent.ACTION_SEND);
// Set the MIME type
share.setType(type);
// Create the URI from the media
java.io.File media = new java.io.File(mediaPath);
Uri uri = Uri.fromFile(media);
// Add the URI and the caption to the Intent.
share.putExtra(Intent.EXTRA_STREAM, uri);
share.putExtra(Intent.EXTRA_TEXT, caption);
// Broadcast the Intent.
mActivity.startActivity(Intent.createChooser(share, "Share to"));
But on Android 4.4.2 it crashes the Facebook app. Facebook app opens, the image is not shown and the FB app is dead.
In log dump I've noticed this message:
E/JHEAD ( 5850): can't open '/data/data/cz.volten.brili.android.free/files/product_preview_shared.jpg'
V/ContextImpl( 5850): ----- packageName = com.facebook.katana is NOT LOCKED -----
Could the reason be some security restrictions, e.g. The FB app does not have rights to access the image in the application folder even though it is invoked from an intent?
If so, what would be a proper location for an image shared between the apps?
Shall I use something like this: how to share image to facebook via intent
Could the reason be some security restrictions, e.g. The FB app does not have rights to access the image in the application folder even though it is invoked from an intent?
Correct. That image is on internal storage for your app, which is private to your app.
If so, what would be a proper location for an image shared between the apps?
You can stick with internal storage, though you will need to use a FileProvider, perhaps with my LegacyCompatCursorWrapper, to serve the file. This sample app demonstrates this, albeit with a PDF rather than an image.
Or, put the file on external storage.
Shall I use something like this: how to share image to facebook via intent
You could, though that would seem to be overkill, compared to using FileProvider.
This is what I usually use
private void initShareIntent(String type) {
boolean found = false;
Intent share = new Intent(android.content.Intent.ACTION_SEND);
share.setType("image/jpeg");
// gets the list of intents that can be loaded.
List<ResolveInfo> resInfo = getPackageManager().queryIntentActivities(share, 0);
if (!resInfo.isEmpty()) {
for (ResolveInfo info : resInfo) {
if (info.activityInfo.packageName.toLowerCase().contains(type) ||
info.activityInfo.name.toLowerCase().contains(type)) {
share.putExtra(Intent.EXTRA_TEXT, "Elevator Express");
share.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(imagePath))); // Optional, just if you wanna share an image.
share.setPackage(info.activityInfo.packageName);
found = true;
break;
}
}
if (!found) {
Toast.makeText(getApplicationContext(), "Facebook does not exist", Toast.LENGTH_SHORT).show();
return;
}
startActivity(Intent.createChooser(share, "Select"));
}
}
and call it like this :
iniShareIntent("face");
This code works for me.....here "updateImage" is my image location.
if (isFacebookExist()) {
if (hashClick.isChecked()) {
SharePhoto sharePhoto = new SharePhoto.Builder()
.setBitmap(updateImage)
.build();
if (ShareDialog.canShow(SharePhotoContent.class)) {
SharePhotoContent content = new SharePhotoContent.Builder()
.addPhoto(sharePhoto)
.setShareHashtag(new ShareHashtag.Builder()
.setHashtag("#HashTag")
.build())
.build();
shareDialog.show(content);
}
} else {
SharePhoto sharePhoto = new SharePhoto.Builder()
.setBitmap(updateImage)
.build();
if (ShareDialog.canShow(SharePhotoContent.class)) {
SharePhotoContent content = new SharePhotoContent.Builder()
.addPhoto(sharePhoto)
.build();
shareDialog.show(content);
}
}
} else {
showToast(" Facebook is not install.");
}
private boolean isFacebookExist() {
PackageManager pm = getPackageManager();
try {
PackageInfo info = pm.getPackageInfo("com.facebook.katana", PackageManager.GET_META_DATA);
} catch (PackageManager.NameNotFoundException e) {
return false;
}
return true;
}
I want to read permission of other applications installed in my android mobile using programming.
I think Android Cleaner read permission of other apps and display details like
I want get detail like this Image.
In this it's give details of Ad Network
How i get details like this app in my app?
If this app not Read Permission then How it's do it?
Well you can scrape the playstore app page for a given app and get the permissions it needs :)
Well that's just off the top of my head. On a serious note, you can do the following:
Intent intent = new Intent(Intent.ACTION_MAIN, null);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
List appsList = getPackageManager().queryIntentActivities(intent, 0);
for (Object app : appsList) {
ResolveInfo resolveInfo = (ResolveInfo) app;
PackageInfo packageInfo = null;
try {
packageInfo = getPackageManager().getPackageInfo(resolveInfo.activityInfo.packageName, PackageManager.GET_PERMISSIONS);
} catch (NameNotFoundException ex) {
ex.printStackTrace();
}
String[] requestedPermissions = packageInfo.requestedPermissions;
}