How to determine the target device programmatically in Android? - android

I would like to programmatically determine (on the Android platform), if the target device is a phone or a tablet.
Is there a way to do this?
I tried using Density Metrics to determine the resolution and used resources (images and layouts) accordingly but, it did not turn out well. There are differences when I launch the app on a phone (Droid X) and a tablet (Samsung Galaxy 10.1).
Please advise.

You can use this code
private boolean isTabletDevice() {
if (android.os.Build.VERSION.SDK_INT >= 11) { // honeycomb
// test screen size, use reflection because isLayoutSizeAtLeast is only available since 11
Configuration con = getResources().getConfiguration();
try {
Method mIsLayoutSizeAtLeast = con.getClass().getMethod("isLayoutSizeAtLeast", int.class);
Boolean r = (Boolean) mIsLayoutSizeAtLeast.invoke(con, 0x00000004); // Configuration.SCREENLAYOUT_SIZE_XLARGE
return r;
} catch (Exception x) {
x.printStackTrace();
return false;
}
}
return false;
}
Link: http://www.androidsnippets.com/how-to-detect-tablet-device

As James has already mentioned, You can determine screen size programatically and use a threshold Number to differrentiate between your logic.

Based on Aracem's answer, I updated the snippet with normal tablet check for 3.2 or higher (sw600dp):
public static boolean isTablet(Context context) {
try {
if (android.os.Build.VERSION.SDK_INT >= 13) { // Honeycomb 3.2
Configuration con = context.getResources().getConfiguration();
Field fSmallestScreenWidthDp = con.getClass().getDeclaredField("smallestScreenWidthDp");
return fSmallestScreenWidthDp.getInt(con) >= 600;
} else if (android.os.Build.VERSION.SDK_INT >= 11) { // Honeycomb 3.0
Configuration con = context.getResources().getConfiguration();
Method mIsLayoutSizeAtLeast = con.getClass().getMethod("isLayoutSizeAtLeast", int.class);
Boolean r = (Boolean) mIsLayoutSizeAtLeast.invoke(con, 0x00000004); // Configuration.SCREENLAYOUT_SIZE_XLARGE
return r;
}
} catch (Exception e) {
}
return false;
}

Related

Function to check development settings not working as expected

I have a function that checks if developer mode is enabled or not, as the suggestion here:
Android - How to check if Developer option is enabled
Here is the code:
public boolean isDevMode() {
if(Build.VERSION.SDK_INT >= 17) {
return android.provider.Settings.Global.getInt(getApplicationContext().getContentResolver(),
Settings.Global.DEVELOPMENT_SETTINGS_ENABLED , 0) != 0;
} else {
return false;
}
}
It works perfectly on API 26+ but I've just tested it on the emulator on API 24 and it returns false regardless of if developer settings are enabled or not.
What am I missing? Is it a different option for < 26?
Fixed it by changing the default value to true for builds under oreo only.
public boolean isDevMode() {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
return Settings.Secure.getInt(context.getContentResolver(), Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0;
} else {
return Settings.Secure.getInt(context.getContentResolver(), Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 1) != 0;
}
}

Detecting if device is from Samsung Galaxy family

Is there a reliable way of detecting if device is one from Samsung Galaxy phones? Currently, I do it in this way:
private static boolean isSamsungGalaxyN() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
try {
PackageInfo info = getContext().getPackageManager().getPackageInfo("com.samsung.android.app.galaxyfinder", 0);
if (info != null) {
return true;
}
} catch (PackageManager.NameNotFoundException e) {
// ignored
}
}
return false;
}
So, I just check if there is such apk (which is S Finder, actually):
com.samsung.android.app.galaxyfinder
But is this method reliable and is there some better method?
Use Build.MANUFACTURER and Build.MODEL.
With Model you can get device family. For Galaxy S7 it will be SM-G903x. You need to have list of known Galaxy model names.
https://www.techwalls.com/samsung-galaxy-s7-edge-model-numbers-differences/

Correctly detect Android device type

Is there any a way to precisely detect the device type (phone, tablet, watch, TV, auto, PC)?
Right now, I found a way to detect if the app is running on a car (uiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_CAR), on a TV (uiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_TELEVISION), or on a watch (uiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_WATCH).
Is it correct? Does a phone connected to a car appears as a phone or as "Android Auto"?
To differentiate between a phone, tablet or computer I can check for the minimum screen size (600dp to qualify as tablet or laptop for example).
The problem now is to differentiate between a tablet and a laptop. Have you got any idea?
PS: I'm not asking this to make a responsive UI, it's a question related to the device management for an account
You can detect using this code application running on large screen or not.
public static boolean isTablet(Context context) {
return (context.getResources().getConfiguration().screenLayout
& Configuration.SCREENLAYOUT_SIZE_MASK)
>= Configuration.SCREENLAYOUT_SIZE_LARGE;
}
This link would be also helpful to you.
Get Width of screen and check that with this break-points.
/* Tablet (portrait and landscape) ----------- */
min-device-width : 768px
max-device-width : 1024px
/* Desktops and laptops ----------- */
min-width : 1224px
To differentiate between a phone and a tablet or computer I can check for the minimum screen size (600dp to qualify as talet or laptop for example).
There is a better way to do that and it's using values. For example, if you have 2 type of devices (say phone and tablet), create two folder for values too. Then for values folder add this:
<resources>
<bool name="isLarge">false</bool>
</resources>
and in your values-large folder:
<resources>
<bool name="isLarge">true</bool>
</resources>
Then in your activity:
boolean isLarge = getResources().getBoolean(R.bool.isLarge);
if (isLarge) {
// do something
} else {
// do something else
}
Using this, you can do same thing for phone, sw-600dp, sw-720dp and etc. I'm not sure if you can use this for TV and etc, but I think it worth to try.
please refer this link,
http://developer.android.com/training/multiscreen/screensizes.html#TaskUseSWQuali
here below i put the code for checking Tablet or android TV, please check, it will works
for tablet
private boolean checkIsTablet() {
boolean isTablet;
Display display = ((Activity) this.mContext).getWindowManager().getDefaultDisplay();
DisplayMetrics metrics = new DisplayMetrics();
display.getMetrics(metrics);
float widthInches = metrics.widthPixels / metrics.xdpi;
float heightInches = metrics.heightPixels / metrics.ydpi;
double diagonalInches = Math.sqrt(Math.pow(widthInches, 2) + Math.pow(heightInches, 2));
if (diagonalInches >= 7.0) {
isTablet = true;
}
return isTablet;
}
or
public static boolean checkIsTablet(Context ctx){
return (ctx.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE;
}
for TV
#TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
private boolean checkIsTelevision() {
boolean isAndroidTV;
int uiMode = mContext.getResources().getConfiguration().uiMode;
if ((uiMode & Configuration.UI_MODE_TYPE_MASK) == Configuration.UI_MODE_TYPE_TELEVISION) {
isAndroidTV = true;
}
It will works, enjoy...
Check whether the physical screen size is large (=tablet or laptop-like device):
private static boolean isTabletDevice(Context activityContext) {
boolean device_large = ((activityContext.getResources().getConfiguration().screenLayout &
Configuration.SCREENLAYOUT_SIZE_MASK) ==
Configuration.SCREENLAYOUT_SIZE_LARGE);
if (device_large) {
DisplayMetrics metrics = new DisplayMetrics();
Activity activity = (Activity) activityContext;
activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
if (metrics.densityDpi == DisplayMetrics.DENSITY_DEFAULT
|| metrics.densityDpi == DisplayMetrics.DENSITY_HIGH
|| metrics.densityDpi == DisplayMetrics.DENSITY_MEDIUM
|| metrics.densityDpi == DisplayMetrics.DENSITY_TV
|| metrics.densityDpi == DisplayMetrics.DENSITY_XHIGH) {
AppInstance.getLogger().logD("DeviceHelper","IsTabletDevice-True");
return true;
}
}
AppInstance.getLogger().logD("DeviceHelper","IsTabletDevice-False");
return false;
}
Check whether the app is running in the Android SDK emulator:
public static boolean isEmulator() {
return Build.FINGERPRINT.startsWith("generic")
|| Build.FINGERPRINT.startsWith("unknown")
|| Build.MODEL.contains("google_sdk")
|| Build.MODEL.contains("Emulator")
|| Build.MODEL.contains("Android SDK built for x86")
|| Build.MANUFACTURER.contains("Genymotion")
|| (Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic"))
|| "google_sdk".equals(Build.PRODUCT);
}
Check whether the device is an Android TV:
public static final String TAG = "DeviceTypeRuntimeCheck";
UiModeManager uiModeManager = (UiModeManager) getSystemService(UI_MODE_SERVICE);
if (uiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_TELEVISION) {
Log.d(TAG, "Running on a TV Device")
} else {
Log.d(TAG, "Running on a non-TV Device")
}
Use following static methods for getting device name,id, height, and width. For more detail visit at this link. Project includes all common feature that basic android application want.
public static String getDeviceName() {
String manufacturer = Build.MANUFACTURER;
String model = Build.MODEL;
if (model.startsWith(manufacturer)) {
return capitalize(model);
} else {
return capitalize(manufacturer) + " " + model;
}
}
public static String getDeviceID(Context context) {
TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
return telephonyManager.getDeviceId();
}
public static int getDeviceHeight(Context mContext) {
DisplayMetrics displaymetrics = new DisplayMetrics();
((Activity) mContext).getWindowManager().getDefaultDisplay()
.getMetrics(displaymetrics);
return displaymetrics.heightPixels;
}
public static int getDeviceWidth(Context mContext) {
DisplayMetrics displaymetrics = new DisplayMetrics();
((Activity) mContext).getWindowManager().getDefaultDisplay()
.getMetrics(displaymetrics);
return displaymetrics.widthPixels;
}
Check this class. https://developer.android.com/reference/android/os/Build.html
String manufacturer = Build.MANUFACTURER
String model = Build.MODEL
You can know if its phone, tab or TV from Build.MODEL

Unable to get data roaming status on Moto Devices Android?

I need to get access to the Data Roaming Status on Moto Device(5.0.1)
if (Settings.Secure.getInt(context.getContentResolver(),Settings.Secure.DATA_ROAMING) == 1) {
//Data Roaming Enabled
flag = true;
} else {
// Data Roaming Disabled
flag = false;
}
I found problem with this when using a Motorola device. Secure Settings in this device are found in android.provider.MotorolaSettings.Secure where as in other devices it's android.provider.Settings.Secure.
Is there a way to resolve this or any other way to get roaming status?
One solution here, use reflection to check if Motorola classes are availables.
If they're not here, you need to use the default api, then call getInt on the available system.
Not able to test it on a Motorola device.
public static boolean isEnabled(Context context){
Class<?> baseSettingsClass = null;
// Retrieve the 'default' settings api
try {
if (android.os.Build.VERSION.SDK_INT >= 17){
baseSettingsClass = Class.forName( "android.provider.Settings$Global");
}
else{
baseSettingsClass = Class.forName( "android.provider.Settings$Secure" );
}
}catch(Exception e){}
Class<?> secureClass = null;
// Try retrieve the motorola class
try{
secureClass = Class.forName("com.motorola.android.provider.MotorolaSettings$Secure" );
}catch(Exception e){}
// If it failed, use the 'default' api class
if (secureClass == null){
if (baseSettingsClass != null){
secureClass = baseSettingsClass;
}
else{
return false;
}
}
try {
// Retrieve the getInt method
Method getIntMethod = secureClass.getDeclaredMethod("getInt", ContentResolver.class, String.class);
// Execute getInt(context.getContentResolver(), Settings.Secure.DATA_ROAMING)
int result = (Integer) (getIntMethod.invoke(null, context.getContentResolver(), (String)baseSettingsClass.getField("DATA_ROAMING").get(null)));
return result == 1;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}

How to find out whether android device has cellular radio module?

How can I find out for sure that device really has gsm, cdma or other cellular network equipment (not just WiFi)?
I don't want to check current connected network state, because device can be offline in the moment.
And I don't want to check device id via ((TelephonyManager) act.getSystemService(Context.TELEPHONY_SERVICE)).getDeviceId() because some devices would just give you polymorphic or dummy device ID.
Actualy, I need to check cell equipment exactly for skipping TelephonyManager.getDeviceId and performing Settings.Secure.ANDROID_ID check on those devices that don't have cellular radio. I have at least one tablet (Storage Options Scroll Excel 7") which returns different IMEIs every time you ask it, although it should return null as it has no cell radio (the same situation here: Android: getDeviceId() returns an IMEI, adb shell dumpsys iphonesubinfo returns Device ID=NULL). But I need to have reliable device id that is the same every time I ask.
I'd be glad to hear your thoughts!
If you're publishing in the store, and you want to limit your application only being visible to actual phones, you could add a <uses-feature> into your manifest that asks for android.hardware.telephony. Check out if that works for you from the documentation.
Just in case somebody needs complete solution for this:
Reflection is used because some things may not exist on some firmware versions.
MainContext - main activity context.
static public int getSDKVersion()
{
Class<?> build_versionClass = null;
try
{
build_versionClass = android.os.Build.VERSION.class;
}
catch (Exception e)
{
}
int retval = -1;
try
{
retval = (Integer) build_versionClass.getField("SDK_INT").get(build_versionClass);
}
catch (Exception e)
{
}
if (retval == -1)
retval = 3; //default 1.5
return retval;
}
static public boolean hasTelephony()
{
TelephonyManager tm = (TelephonyManager) Hub.MainContext.getSystemService(Context.TELEPHONY_SERVICE);
if (tm == null)
return false;
//devices below are phones only
if (Utils.getSDKVersion() < 5)
return true;
PackageManager pm = MainContext.getPackageManager();
if (pm == null)
return false;
boolean retval = false;
try
{
Class<?> [] parameters = new Class[1];
parameters[0] = String.class;
Method method = pm.getClass().getMethod("hasSystemFeature", parameters);
Object [] parm = new Object[1];
parm[0] = "android.hardware.telephony";
Object retValue = method.invoke(pm, parm);
if (retValue instanceof Boolean)
retval = ((Boolean) retValue).booleanValue();
else
retval = false;
}
catch (Exception e)
{
retval = false;
}
return retval;
}

Categories

Resources