Check if app runs on tablet - android

You can check if your app is running on different versions of Android using the following:
int sdk = Build.VERSION.SDK_INT;
if (sdk <= Build.VERSION_CODES.ECLAIR){
//do stuff
} else {
//do some other stuff
}
Is there such a check for tablet use? Currently I have two ways to find out that I don't like:
Configuration configuration = getResources().getConfiguration();
if (configuration.orientation == Configuration.ORIENTATION_LANDSCAPE) {
try {
return configuration.screenWidthDp >= 1024;
} catch (NoSuchFieldError ex) {
return false;
}
} else {
return false;
}
And, if I use a different layout file with different view ids:
return findViewById(R.id.mytabletlinearlayout) == null;
Is there something like the version codes available for this? Or is there another more elegant solution?
Edit
For some clarity, I need to perform some different actions if I'm running my app on a tablet, because then I am using a multi-pane layout.

Rather than attempting to detect tablets, consider detecting screen sizes and detecting features that the device supports, since the difference between a phone and a tablet isn't exactly well defined (and subject to change).
To detect a feature, use the PackageManager class, specifically hasSystemFeature or getSystemAvailableFeatures. For detecting screen sizes, your second approach of sniffing changes in the layouts in your different folders is an appropriate way to handle it.
If you check available features at runtime, you won't be forced to make generalizations about tablets ahead of time, like assuming they don't have a back facing camera, or other features like that.

To check if it is running on a tablet this answer should be sufficient. Bear in mind though that you may be asking the wrong question. Your program should be more worried about the specific characteristics of the device that you are using. (e.g. Screen Size, Memory Capabilities, etc.)

Related

Android differentiate between a TV and a STB

How can I differentiate between a TV and a STB/game console on AndroidTV programatically? This method (https://developer.android.com/training/tv/start/hardware) won't work because an STB running AndroidTV is considered a television.
What's Your Goal?
The obvious reason for doing this would be to determine if a device is suitable for a game to be played on. If it's for any other reason, then the purpose needs to be elaborated on in order to receive applicable assistance.
With that said ...
Since it's not possible to query the device type directly -- personally, I'd look for something that only a game console would be likely to have.
In other words: a game controller/gamepad.
public ArrayList<Integer> getGameControllerIds() {
ArrayList<Integer> gameControllerDeviceIds = new ArrayList<Integer>();
int[] deviceIds = InputDevice.getDeviceIds();
for (int deviceId : deviceIds) {
InputDevice dev = InputDevice.getDevice(deviceId);
int sources = dev.getSources();
// Verify that the device has gamepad buttons, control sticks, or both.
if (((sources & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD)
|| ((sources & InputDevice.SOURCE_JOYSTICK)
== InputDevice.SOURCE_JOYSTICK)) {
// This device is a game controller. Store its device ID.
if (!gameControllerDeviceIds.contains(deviceId)) {
gameControllerDeviceIds.add(deviceId);
}
}
}
return gameControllerDeviceIds;
}
Of course, it's not fool-proof. Obviously, nothing would be returned if the gamepad(s) were unplugged at the time (not sure when that would happen). Not to mention, some TVs support gamepads (Samsung comes to mind first) -- but, if you're intention is to verify that there's an adequate input available for the application, this would be ideal.
If a gamepad isn't present, a message could be displayed stating, "Please connect a gamepad." -- while continuously checking in the background, and automatically proceeding once one is detected.

android open battery settings programically

I'm looking for a way to open the battery settings screen from an android app.
So far I found the two intents :
Intent.ACTION_POWER_USAGE_SUMMARY
Settings.ACTION_BATTERY_SAVER_SETTINGS
but none of them open this screen.
I was wondering if anyone knows of such a way. It sounds strange that an intent for something so simple doesn't exist
Settings.ACTION_BATTERY_SAVER_SETTINGS on "plain" Android versions will show the settings page you want to show.
Intent.ACTION_POWER_USAGE_SUMMARY will lead to the overview page showing the battery consumption.
Some manufactures such as Samsung build their own implementation over the system one, e.g. in this the "Battery" page. On Samsung devices, you can call this by calling the SmartManager interface directly. An code example:
if (Build.MANUFACTURER == "samsung") {
val intent = Intent()
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N) {
intent.component = ComponentName("com.samsung.android.lool", "com.samsung.android.sm.ui.battery.BatteryActivity")
} else if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
intent.component = ComponentName("com.samsung.android.sm", "com.samsung.android.sm.ui.battery.BatteryActivity")
}
try {
activity?.startActivity(intent);
} catch (ex: ActivityNotFoundException) {
// Fallback to global settings
startActivity(Intent(Settings.ACTION_SETTINGS))
}
} else {
startActivity(Intent(Settings.ACTION_BATTERY_SAVER_SETTINGS))
}
It can be the case that you need additional cases for Huawei or Xiaomi as well.
Huawei can be "com.huawei.systemmanager", "com.huawei.systemmanager.optimize.process.ProtectActivity"...
...and the MIU based ones "com.miui.securitycenter", "com.miui.permcenter.autostart.AutoStartManagementActivity"
I know this is quite old. But a trick I use is going to the appropriate settings screen in the device settings and then while connected to the phone run:
adb shell
dumpsys window windows | grep -E 'mCurrentFocus'
This returns the package name and Activity name currently in focus.
Using that I can check in code if the intent is callable. If it is, I launch it. If it isnt, I might have better luck with a different screen that is near by or explain to the user he needs to do something manually etc... Obviously the more devices you have, the more Intents you can create and check at run time. Im sure there is a list of Intents for different devices online.

How to make layout for Android app intended for wearables with api under 20

I bought cheap Chinese Android watch with Android 4.4.2, API 19. I would like to create an app which would work on the watch as well as android phones. The problem is that if I put some special layout into layout-watch folder, this qualifier does not work since it can be used only with minimal API version 20. Also, If I write something like this:
if(conf.uiMode == conf.UI_MODE_TYPE_WATCH) {
it returns false and behaves like non-watch device. Could you please give me some hints how to create "watch app" for this kind of devices which should also work on API 20+ ? How to specify special layout for wearables/watches ? How to write a condition which can determine if current device is a wearable device/watch ?
Thanks
I am using this:
public static boolean isWatch(Activity activity) {
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.KITKAT_WATCH) {
Configuration conf = activity.getResources().getConfiguration();
return conf.uiMode == conf.UI_MODE_TYPE_WATCH;
} else {
if(UIUtil.getDisplayWidth(activity)<320||UIUtil.getDisplayHeight(activity)<320) {
return true; //Some dump Chinese watch
} else {
return false;
}
}
}

Wake lock for Mac OS X

In Android, there's wake lock to keep the screen on. So, is there Mac equivalent to keep the screen on for a PC running Mac OS X? If that is the case, what are the APIs?
To add to it, there are also command-line tools, like the built-in caffeinate.
Yes, in OS X it is done at the OS level through IOPMLib, the Power Management subsystem, which is also the subsystem that controls AppNap under OS X Mavericks.
Here's an example of what we do when performing heavy calculations. In our case, we keep the CPU from sleeping, but you can prevent the display from sleeping by using kIOPMAssertionTypePreventUserIdleDisplaySleep where we used kIOPMAssertionTypePreventUserIdleSystemSleep.
#property IOPMAssertionID currentPowerAssertion;
- (void)assertPowerRequirement:(NSString*)reason
{
// don't re-assert if we're already here
if (_currentPowerAssertion)
return;
IOPMAssertionID assertionID;
IOReturn success = IOPMAssertionCreateWithName(
kIOPMAssertionTypePreventUserIdleSystemSleep, // prevent CPU from going to sleep
kIOPMAssertionLevelOn, // we are turning this on
(__bridge CFStringRef)reason, // here's why
&assertionID); // reference for de-asserting
if (success == kIOReturnSuccess) {
_currentPowerAssertion = assertionID;
} else {
NSLog(#"Power assert failed");
}
}
- (void)deassertPowerRequirement
{
if (!_currentPowerAssertion)
return;
IOReturn success = IOPMAssertionRelease(_currentPowerAssertion);
if (success !=kIOReturnSuccess) {
NSLog(#"Power de-assert failed");
}
_currentPowerAssertion = 0;
}
In this case, this is in our App delegate, and we have the currentPowerAssertion property to keep track. Since we only use one assertion state and only for one purpose, we use a single storage mechanism. However, you can assert multiple times from different parts of your program, as long as you balance the assertions with de-assertions and use appropriate reason. Specifications from Apple mandate a reason be given (not NULL), and suggest that the Application name and task be described in the assertion.
It's important to make sure that you de-assert when you don't need this any longer, although assertions are kept on a per-app basis, so when your App quits, they will automatically be de-asserted.

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;
}
}
}

Categories

Resources