Cannot find getContext() as per Android dedicated device documentation - android

I know a similar question has been asked several times before but I have been through those and they do not help me.
I am trying to set up a Samsung Tab A (Android 8.1) as a single-use device. I have already written the app which works perfectly but as the device will be used by the public I need to lock it down into kiosk mode.
I am trying to follow the developer guide at the link below but immediately hit problems.
https://developer.android.com/work/dpc/dedicated-devices/lock-task-mode
So first thing I try to do is whitelist the app as per the example given:
// Whitelist two apps.
private static final String KIOSK_PACKAGE = "com.example.kiosk";
private static final String PLAYER_PACKAGE = "com.example.player";
private static final String[] APP_PACKAGES = {KIOSK_PACKAGE, PLAYER_PACKAGE};
// ...
Context context = getContext();
DevicePolicyManager dpm =
(DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
ComponentName adminName = getComponentName(context);
dpm.setLockTaskPackages(adminName, APP_PACKAGES);
The documentation is not clear on where this code should go but I have put it in an override for onResume().
I am using auto-import in Android Studio but it tells me that getContext() cannot be found. I have tried changing to getApplicationContext() and just using this as suggested elsewhere but then it complains that getComponentName() should not have any parameters. I have tried simply removing the context parameter, using context.getComponentName() and also using no context variables. These compile but the app crashes on the device (at setLockTaskPackages()).
I suspect that the key is to find out why getContext() cannot be found and then hopefully everything else falls into place. Any idea what might be missing?

If you're using activity use the keyword this, instead of getContext.

getContext() is used in fragment to get context.Is this is Activity,You can use Yourclass.this or this. also you can get knowladge about what can you use for context using this

Related

How to detect programmatically if "Android App" is running in chrome book or in Android phone

Since Google has announced that chromebook also support "Android Application" so I also wanted to support my app on chromebook although it is running fine with few exception which I need to fix.
I want to write code in such a way that that is will execute only for chromebook and will not execute for android phones and tablet.
I have check with Chromebook documentation in android developer site, I didn't get any such API which tell that your app is running in chrome book environment.
Suggestion from ARC Beta documentation did not work:
If you need to check if your app is running on Chrome OS, look for chromium as the android.os.Build.BRAND and android.os.Build.MANUFACTURER.
Both return google on an ASUS Chromebook.
Finally I figure out a way to know if app in running in ARC:
context.getPackageManager().hasSystemFeature("org.chromium.arc.device_management");
Jan 15, 2023 Note-- Jump to the bottom of this answer to read how Google has changed their own method for checking YET AGAIN.
(Or keep reading for the history of the ARC check.)
Another method Google uses in their own code (updated several times now from link) is to check if Build.DEVICE ends with "_cheets". I don't know if ending device names like this is some kind of long-term strategy or a fast workaround, but it's also worth a look in addition to dex's proposed solution.
FWIW, since ARCWelder's method is deprecated and there's no official documentation on this (yet), I've also started a discussion in the XDA forums here for people to discuss what works/doesn't work on various devices.
Update 5/18: Looks like the code above was moved and updated, so Google's new ARC check as of May 2018 is here, particularly in this bit:
... } else if (Build.DEVICE != null && Build.DEVICE.matches(ARC_DEVICE_PATTERN)) {
mFormFactor = FORM_FACTOR_ARC;
} else { ...
where ARC_DEVICE_PATTERN is defined as
private static final String ARC_DEVICE_PATTERN = ".+_cheets|cheets_.+";
So it's not just a device ending with _cheets. It can start with cheets_ as well.
Update 8/26/20 -- As of 7 months ago, the source has been moved around from FormFactors.java to FeatureSupport.java. If you were looking for where it went- here it the code as of today.
public static boolean isArc() {
return (Build.DEVICE != null && Build.DEVICE.matches(".+_cheets|cheets_.+"));
}
The test remains the same.
Jan 15, 2023 -- The code has changed again! isArc() is now built into the FeatureUtil class (see commit here) The current version of isArc() :
/** Returns {#code true} if device is an ARC++ device. */
public static boolean isArc() {
return hasAnySystemFeature(ARC_FEATURE, ARC_DEVICE_MANAGEMENT_FEATURE);
}
Where ARC_FEATURE and ARC_DEVICE_MANAGEMENT_FEATURE are defined like this:
public static final String ARC_FEATURE = "org.chromium.arc";
public static final String ARC_DEVICE_MANAGEMENT_FEATURE = "org.chromium.arc.device_management";
the function hasAnySystemFeature() simply checks individual features and returns true if any is true.
Therefore the following might work as a simple standalone check in kotlin (where context is the activity context):
fun isArc(): Boolean {
return ((context.packageManager.hasSystemFeature("org.chromium.arc")) || (context.packageManager.hasSystemFeature("org.chromium.arc.device_management")))
Note this is similar to #dex's answer below, but includes both tests used by the Android source.
Incidentally, from looking at the code linked above you can also check other device characteristics like like isWatch(), isTV(), isAutomotive(), isPC(), isVrHeadset(), isLowRam(), etc. using similar feature checks.
PackageManager pm = context.getPackageManager();
if (pm.hasSystemFeature(PackageManager.FEATURE_PC))
// it's a chromebook
I found the solution in Android CTS code.
public static boolean isArc(#NonNull Context context) {
PackageManager pm = context.getPackageManager();
return pm.hasSystemFeature( "org.chromium.arc" ) || pm.hasSystemFeature( "org.chromium.arc.device_management" );
}

Android 7.0/API24: How to check for notification access (Settings.Secure.enabled_notification_listeners)

In Android 6.0/API23 and earlier, the following used to work:
String settingEnabled = android.provider.Settings.Secure.getString(this.getContentResolver(), "enabled_notification_listeners");
In Android 7.0 Nougat/API24 this seems to be no longer supported, because the code above returns null.
It actually was never mentioned here: https://developer.android.com/reference/android/provider/Settings.Secure.html
How do we check if our app has notification access in Android 7.0 Nougat API24?
Edit: It seems that actually that after you first gained the access in the settings, the code above returns the correct state. But not on the initial request after installation.
Use this:
Set<String> packageNames = NotificationManagerCompat.getEnabledListenerPackages (context);

make getSystemService() recognize our new system service

I'm using the book "Embedded Android".
I'm making a new System Service using AOSP(4.0.3_r1).
I want my system service to be registered in frameworks/base/core/java/android/content/app/ContextImpl.java so that I can use it through getSystemService() method.
The problem is, I can't find the app folder under content:androidroot/frameworks/base/core/java/android/content/app/ContextImpl.java
But, I found it in:androidroot/frameworks/base/core/java/android/app/ContextImpl.java
Are these 2 files the same? or is it just missing(the content/app folder)?
Any idea on what to do?
Karim wrote his book mostly orienting on Android 2.3.4 version. Something can be changed from this time. This is an example what has been changed.
Are these 2 files the same? or is it just missing(the content/app folder)?
These are the same files.
Any idea on what to do?
As I said the implementation has been changed. I looked into the code and here what you can change to make your code working (I can only suppose because I did not actually build my code). In the static block of ContextImpl class you need to add the following code:
registerService(ACCOUNT_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
IBinder b = ServiceManager.getService(OPERSYS_SERVICE);
IOpersysService service = IOpersysService.Stub.asInterface(b);
return new OpersysManager(service);
}});
You need to use SystemServer which holds all system services' names.
You should check this link out:
http://processors.wiki.ti.com/index.php/Android-Adding_SystemService

Detect if an android app is running on background

I want to check if my app is running on a background mode.
The problem is that i have many activities(list activities, map activities etc.). Initially I have tried in the life cycle's resume and pause(or the onUserLeaveHint) methods to set a static boolean as true or false and work with this way. But this obviously can't work because when I move from one activity to another, the previous one get paused.
Also, I've read here on stackoverflow that the getRunningTasks() should be used only for debugging purposes. I did a huge research but I can't find a solution. All I want to do is to be able to detect if a the app is running on a background. Can anyone propose me a way, or express any thought on how can I do that?
You can try the same mechanism (a boolean attribute) but on application side rather than activity side. Create a class which extends Application, declare it in the manifest file under <application android:name=YourClassApp>.
EDIT: I assume you know that activities aren't intended for background processing, if not you should take a look at the Services.
I don't know if this will help but you can use
getApplicaton().registerActivityLifecycleCallbacks(yourClass);
To get a birds eye view of how your activities are displayed in the FG. (For older s/w you can use this)
If your Application has a Service you could have a static get/set which accesses a static variable. Do not do this in Activities though, it causes mem leaks.
But realistically speaking there is no tidy way of tracking if your application is running or not.
I had the same problemen when overwriting the Firebase push messaging default behavior (show notifications only when in the background) I checked how Firebase did this by looking in the .class file com.google.firebase.messaging.zzb:53 (firebase-messaging:19.0.1) which appears to us getRunningAppProcesses. Mind you FireBase is created by Google them self. So I'm assuming it's pretty save to use. Cleaned up version:
List<ActivityManager.RunningAppProcessInfo> runningApps;
boolean isInForeground =false;
if ((runningApps = ((ActivityManager)this.getApplication().getSystemService(Context.ACTIVITY_SERVICE)).getRunningAppProcesses()) != null) {
Iterator runningApp = runningApps.iterator();
int myPid = Process.myPid();
while(runningApp.hasNext()) {
ActivityManager.RunningAppProcessInfo processInfo;
if ((processInfo = (ActivityManager.RunningAppProcessInfo)runningApp.next()).pid == myPid) {
isInForeground = processInfo.importance == 100;
break;
}
}
}

Android: Programmatically open "Recent Apps" dialog

I would like to be able to open the "Recent Apps" dialog from my application. This is the dialog that is opened by long-pressing the home button. I am programming for Android 4.1 or earlier. I found a way to do it by implementing a custom AccessibilityService and calling AccessibilityService.performGlobalAction(GLOBAL_ACTION_RECENTS), but this requires enabling accessibility on the phone, which is not very desirable. Is there any other way to open this dialog from an app?
Thanks for the help!
This code won't work on Nougat or later
It is possible to trigger the recent apps activity.
The StatusBarManagerService implements an public method which you can use through reflection.
You can use the following code:
Class serviceManagerClass = Class.forName("android.os.ServiceManager");
Method getService = serviceManagerClass.getMethod("getService", String.class);
IBinder retbinder = (IBinder) getService.invoke(serviceManagerClass, "statusbar");
Class statusBarClass = Class.forName(retbinder.getInterfaceDescriptor());
Object statusBarObject = statusBarClass.getClasses()[0].getMethod("asInterface", IBinder.class).invoke(null, new Object[] { retbinder });
Method clearAll = statusBarClass.getMethod("toggleRecentApps");
clearAll.setAccessible(true);
clearAll.invoke(statusBarObject);
Have fun
You cannot access that. However, it isn't super hard to roll your own. The getRecentTasks() method returns a list of recently run apps. Simply take the list and add your own UI to it.
One advantage to this is that the default one, at least on older versions of Android, only shows you about 8 apps. If you roll your own can show as many as you want.
This can be done using the TOGGLE_RECENTS Intent.
Intent intent = new Intent ("com.android.systemui.recent.action.TOGGLE_RECENTS");
intent.setComponent (new ComponentName ("com.android.systemui", "com.android.systemui.recent.RecentsActivity"));
startActivity (intent);
Note Package would be changed basis on Api level. See here.
Android 4.1: "com.android.internal.policy.impl.RecentApplicationsDialog"
Android 4.2 - 4.4: "com.android.systemui.recent.RecentsActivity"
Android 5.0 - 7.1: "com.android.systemui.recents.RecentsActivity" ("s" letter was added)

Categories

Resources