How to check "Automatic date and time" is enabled or not? - android

I need to check whether "Automatic date and time" in the android device is enabled or not. If it is not enabled I need to display the popup that it is not enabled.
Is it possible to achieve. If possible, how to check enabled or not ?

Link for API 17 and above
android.provider.Settings.Global.getInt(getContentResolver(), android.provider.Settings.Global.AUTO_TIME, 0);
Link for API 16 and below
android.provider.Settings.System.getInt(getContentResolver(), android.provider.Settings.System.AUTO_TIME, 0);

public static boolean isTimeAutomatic(Context c) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
return Settings.Global.getInt(c.getContentResolver(), Settings.Global.AUTO_TIME, 0) == 1;
} else {
return android.provider.Settings.System.getInt(c.getContentResolver(), android.provider.Settings.System.AUTO_TIME, 0) == 1;
}
}

I would just like to point out that it is possible to cheat (I just did it on a Samsung Galaxy S4, Android 5.0.1):
Disable auto time
Disconnect from the internets (airplane mode, no wifi etc...)
reboot phone (otherwise the real time is retrieved)
set auto time on
Done today:
Unix time: 1129294173
Date: 14102005024933
is automatic? 1 (using android.provider.Settings.Global.getInt(getActivity().getContentResolver(), android.provider.Settings.Global.AUTO_TIME, 0))
And today definitely isn't Oct 14, 2005

if(Settings.Global.getInt(getContentResolver(), Global.AUTO_TIME) == 1)
{
// Enabled
}
else
{
// Disabed
}

Check is Auto Time or Zone is Enabled ? (Kotlin)
fun isAutoTimeEnabled(activity: Activity) =
Settings.Global.getInt(activity.contentResolver, Settings.Global.AUTO_TIME) == 1
fun isAutoTimeZoneEnabled(activity: Activity) =
Settings.Global.getInt(activity.contentResolver, Settings.Global.AUTO_TIME_ZONE) == 1

in kotlin you can use
fun isTimeAutomatic(c: Context): Boolean {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
Settings.Global.getInt(c.contentResolver, Settings.Global.AUTO_TIME, 0) == 1
} else {
Settings.System.getInt(c.contentResolver, Settings.System.AUTO_TIME, 0) == 1
}}

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

How to know if user has disabled Picture in Picture feature permission?

and here is another example:
from the screenshot above we see user is able to disable picture in picture mode. you can find it in the "special app access" screen on the emulator api 27 . How can i detect if user has disabled this feature ?
i tried checking the following but it does not work:
packageManager.hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE)
compiler states that AppOpsManager cannot be found. any ideas ?
just like AlexTa said. but i wanted to actually write the code to save someone some time:
private fun hasPermission(): Boolean {
val appOps = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
getSystemService(Context.APP_OPS_SERVICE) as AppOpsManager
} else {
return false
}
return appOps.checkOpNoThrow(AppOpsManager.OPSTR_PICTURE_IN_PICTURE, android.os.Process.myUid(), packageName) == AppOpsManager.MODE_ALLOWED
}
Try AppOpsManager.checkOp (String op, int uid, String packageName), where op is OPSTR_PICTURE_IN_PICTURE operation. That method should return MODE_ALLOWED constant if supports Picture in Picture operation.
For more info, check this link.
I might be late but here's the answer
private fun hasPermission(): Boolean {
val appOps = getSystemService(Context.APP_OPS_SERVICE) as AppOpsManager?
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
appOps?.unsafeCheckOpNoThrow(AppOpsManager.OPSTR_PICTURE_IN_PICTURE, android.os.Process.myUid(), packageName) == AppOpsManager.MODE_ALLOWED
} else {
appOps?.checkOpNoThrow(AppOpsManager.OPSTR_PICTURE_IN_PICTURE, android.os.Process.myUid(), packageName) == AppOpsManager.MODE_ALLOWED
}
} else {
false
}
}

Roaming detection on OnePlus One/Two/Three

I'm willing to detect if roaming switch on a telephone is turned off.
if (Build.VERSION.SDK_INT < 17) {
isDataRoamingDisabled =
(Settings.System.getInt(context.getContentResolver(), Settings.Secure.DATA_ROAMING, 0)
== 0);
} else {
isDataRoamingDisabled =
(Settings.Global.getInt(context.getContentResolver(), Settings.Global.DATA_ROAMING, 0)
== 0);
}
Unfortunately only for OnePlus One/Two/Three the setting is always false (0).
On rest devices that i tested - Nexus 6P, LG G5, Samsung S5 all is working fine...
telephonyManager.isNetworkRoaming(), is not really the solution here since it detects if a user in roaming and not switch in settings.
Thanks for help! :)
I found some solution regarding this issue..
It seems like it caused by the using of Dual SIM on these devices, which adopted the newer API for this functionality. (I found it on the source code of Oxygen)
This solution requires READ_PHONE_STATE permission
Accessing the roaming of each subscription:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
List<SubscriptionInfo> subscriptions = SubscriptionManager.from(context).getActiveSubscriptionInfoList();
for (SubscriptionInfo subscriptionInfo:subscriptions) {
if (subscriptionInfo.getDataRoaming() == SubscriptionManager.DATA_ROAMING_ENABLE) {
return true;
}
}
return false;
}
For the rest of the devices you may use the solution you specified above.

How we can check our App is running in real device or bluestack? [duplicate]

I would like to have my code run slightly differently when running on the emulator than when running on a device. (For example, using 10.0.2.2 instead of a public URL to run against a development server automatically.) What is the best way to detect when an Android application is running in the emulator?
How about this solution (class implementation of SystemProperties is available here):
val isProbablyRunningOnEmulator: Boolean by lazy {
// Android SDK emulator
return#lazy ((Build.MANUFACTURER == "Google" && Build.BRAND == "google" &&
((Build.FINGERPRINT.startsWith("google/sdk_gphone_")
&& Build.FINGERPRINT.endsWith(":user/release-keys")
&& Build.PRODUCT.startsWith("sdk_gphone_")
&& Build.MODEL.startsWith("sdk_gphone_"))
//alternative
|| (Build.FINGERPRINT.startsWith("google/sdk_gphone64_")
&& (Build.FINGERPRINT.endsWith(":userdebug/dev-keys") || Build.FINGERPRINT.endsWith(":user/release-keys"))
&& Build.PRODUCT.startsWith("sdk_gphone64_")
&& Build.MODEL.startsWith("sdk_gphone64_"))))
//
|| 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")
//bluestacks
|| "QC_Reference_Phone" == Build.BOARD && !"Xiaomi".equals(Build.MANUFACTURER, ignoreCase = true)
//bluestacks
|| Build.MANUFACTURER.contains("Genymotion")
|| Build.HOST.startsWith("Build")
//MSI App Player
|| Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic")
|| Build.PRODUCT == "google_sdk"
// another Android SDK emulator check
|| SystemProperties.getProp("ro.kernel.qemu") == "1")
}
Note that some emulators fake exact specs of real devices, so it might be impossible to detect it. I've added what I could, but I don't think there is a 100% way to detect if it's really an emulator or not.
Here a tiny snippet you can make in the APK to show various things about it, so you could add your own rules:
textView.text = "FINGERPRINT:${Build.FINGERPRINT}\n" +
"MODEL:${Build.MODEL}\n" +
"MANUFACTURER:${Build.MANUFACTURER}\n" +
"BRAND:${Build.BRAND}\n" +
"DEVICE:${Build.DEVICE}\n" +
"BOARD:${Build.BOARD}\n" +
"HOST:${Build.HOST}\n" +
"PRODUCT:${Build.PRODUCT}\n"
One common one sems to be Build.FINGERPRINT.contains("generic")
Google uses this code in the device-info plugin from Flutter to determine if the device is an emulator:
private boolean isEmulator() {
return (Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic"))
|| Build.FINGERPRINT.startsWith("generic")
|| Build.FINGERPRINT.startsWith("unknown")
|| Build.HARDWARE.contains("goldfish")
|| Build.HARDWARE.contains("ranchu")
|| Build.MODEL.contains("google_sdk")
|| Build.MODEL.contains("Emulator")
|| Build.MODEL.contains("Android SDK built for x86")
|| Build.MANUFACTURER.contains("Genymotion")
|| Build.PRODUCT.contains("sdk_google")
|| Build.PRODUCT.contains("google_sdk")
|| Build.PRODUCT.contains("sdk")
|| Build.PRODUCT.contains("sdk_x86")
|| Build.PRODUCT.contains("sdk_gphone64_arm64")
|| Build.PRODUCT.contains("vbox86p")
|| Build.PRODUCT.contains("emulator")
|| Build.PRODUCT.contains("simulator");
}
Well Android id does not work for me, I'm currently using:
"google_sdk".equals( Build.PRODUCT );
Based on hints from other answers, this is probably the most robust way:
isEmulator = "goldfish".equals(Build.HARDWARE)
How about something like the code below to tell if your app was signed with the debug key? it's not detecting the emulator but it might work for your purpose?
public void onCreate Bundle b ) {
super.onCreate(savedInstanceState);
if ( signedWithDebugKey(this,this.getClass()) ) {
blah blah blah
}
blah
blah
blah
}
static final String DEBUGKEY =
"get the debug key from logcat after calling the function below once from the emulator";
public static boolean signedWithDebugKey(Context context, Class<?> cls)
{
boolean result = false;
try {
ComponentName comp = new ComponentName(context, cls);
PackageInfo pinfo = context.getPackageManager().getPackageInfo(comp.getPackageName(),PackageManager.GET_SIGNATURES);
Signature sigs[] = pinfo.signatures;
for ( int i = 0; i < sigs.length;i++)
Log.d(TAG,sigs[i].toCharsString());
if (DEBUGKEY.equals(sigs[0].toCharsString())) {
result = true;
Log.d(TAG,"package has been signed with the debug key");
} else {
Log.d(TAG,"package signed with a key other than the debug key");
}
} catch (android.content.pm.PackageManager.NameNotFoundException e) {
return false;
}
return result;
}
This code works for me
TelephonyManager tm = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
String networkOperator = tm.getNetworkOperatorName();
if("Android".equals(networkOperator)) {
// Emulator
}
else {
// Device
}
In case that device does not have sim card, It retuns empty string:""
Since Android emulator always retuns "Android" as network operator, I use above code.
I tried several techniques, but settled on a slightly revised version of checking the Build.PRODUCT as below. This seems to vary quite a bit from emulator to emulator, that's why I have the 3 checks I currently have. I guess I could have just checked if product.contains("sdk") but thought the check below was a bit safer.
public static boolean isAndroidEmulator() {
String model = Build.MODEL;
Log.d(TAG, "model=" + model);
String product = Build.PRODUCT;
Log.d(TAG, "product=" + product);
boolean isEmulator = false;
if (product != null) {
isEmulator = product.equals("sdk") || product.contains("_sdk") || product.contains("sdk_");
}
Log.d(TAG, "isEmulator=" + isEmulator);
return isEmulator;
}
FYI - I found that my Kindle Fire had Build.BRAND = "generic", and some of the emulators didn't have "Android" for the network operator.
Both the following are set to "google_sdk":
Build.PRODUCT
Build.MODEL
So it should be enough to use either one of the following lines.
"google_sdk".equals(Build.MODEL)
or
"google_sdk".equals(Build.PRODUCT)
I never found a good way to tell if you're in the emulator.
but if you just need to detecet if you're in a development environment you can do this :
if(Debug.isDebuggerConnected() ) {
// Things to do in debug environment...
}
Hope this help....
I just look for _sdk, _sdk_ or sdk_, or even just sdk part in Build.PRODUCT:
if(Build.PRODUCT.matches(".*_?sdk_?.*")){
//-- emulator --
}else{
//-- other device --
}
use this function :
public static final boolean isEmulator() {
int rating = 0;
if ((Build.PRODUCT.equals("sdk")) || (Build.PRODUCT.equals("google_sdk"))
|| (Build.PRODUCT.equals("sdk_x86")) || (Build.PRODUCT.equals("vbox86p"))) {
rating++;
}
if ((Build.MANUFACTURER.equals("unknown")) || (Build.MANUFACTURER.equals("Genymotion"))) {
rating++;
}
if ((Build.BRAND.equals("generic")) || (Build.BRAND.equals("generic_x86"))) {
rating++;
}
if ((Build.DEVICE.equals("generic")) || (Build.DEVICE.equals("generic_x86")) || (Build.DEVICE.equals("vbox86p"))) {
rating++;
}
if ((Build.MODEL.equals("sdk")) || (Build.MODEL.equals("google_sdk"))
|| (Build.MODEL.equals("Android SDK built for x86"))) {
rating++;
}
if ((Build.HARDWARE.equals("goldfish")) || (Build.HARDWARE.equals("vbox86"))) {
rating++;
}
if ((Build.FINGERPRINT.contains("generic/sdk/generic"))
|| (Build.FINGERPRINT.contains("generic_x86/sdk_x86/generic_x86"))
|| (Build.FINGERPRINT.contains("generic/google_sdk/generic"))
|| (Build.FINGERPRINT.contains("generic/vbox86p/vbox86p"))) {
rating++;
}
return rating > 4;
}
Don't know if there are better ways to detect the emu, but the emulator will have the file init.goldfish.rc in the root-directory.
It's the emulator specific startup-script, and it shouldn't be there on a non-emulator build.
Here is my solution (it works only if you run a web server on your debug machine):
I have created a background task that starts when the application starts. It looks for http://10.0.2.2 and if it exists it changes a global parameter (IsDebug) to true. It is a silent way to find out where you are running.
public class CheckDebugModeTask extends AsyncTask<String, Void, String> {
public static boolean IsDebug = false;
public CheckDebugModeTask()
{
}
#Override
protected String doInBackground(String... params) {
try {
HttpParams httpParameters = new BasicHttpParams();
int timeoutConnection = 1000;
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
int timeoutSocket = 2000;
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
String url2 = "http://10.0.2.2";
HttpGet httpGet = new HttpGet(url2);
DefaultHttpClient client = new DefaultHttpClient(httpParameters);
HttpResponse response2 = client.execute(httpGet);
if (response2 == null || response2.getEntity() == null || response2.getEntity().getContent() == null)
return "";
return "Debug";
} catch (Exception e) {
return "";
}
}
#Override
protected void onPostExecute (String result)
{
if (result == "Debug")
{
CheckDebugModeTask.IsDebug = true;
}
}
from the main activity onCreate:
CheckDebugModeTask checkDebugMode = new CheckDebugModeTask();
checkDebugMode.execute("");
From Battery, the emulator:
Power source is always AC Charger.
Temperature is always 0.
And you can use Build.HOST to record host value, different emulator has different host value.
Another option would be to look at the ro.hardware property and see if its set to goldfish. Unfortunately there doesn't seem to be an easy way to do this from Java but its trivial from C using property_get().
I found the new emulator Build.HARDWARE = "ranchu".
Reference:https://groups.google.com/forum/#!topic/android-emulator-dev/dltBnUW_HzU
And also I found the Android official way to check whether emulator or not.I think it's good reference for us.
Since Android API Level 23 [Android 6.0]
package com.android.internal.util;
/**
* #hide
*/
public class ScreenShapeHelper {
private static final boolean IS_EMULATOR = Build.HARDWARE.contains("goldfish");
}
We have ScreenShapeHelper.IS_EMULATOR to check whether emulator.
Since Android API Level 24 [Android 7.0]
package android.os;
/**
* Information about the current build, extracted from system properties.
*/
public class Build {
/**
* Whether this build was for an emulator device.
* #hide
*/
public static final boolean IS_EMULATOR = getString("ro.kernel.qemu").equals("1");
}
We have Build.IS_EMULATOR to check whether emulator.
The way the official to check whether emulator is not new,and also maybe not enough,the answers above also mentioned.
But this maybe show us that the official will provide the way of official to check whether emulator or not.
As using the above all ways mentioned,right now we can also use the two ways about to check whether emulator.
How to access the com.android.internal package and #hide
and wait for the official open SDK.
This is how Firebase Crashlytics approaches it:
private static final String GOLDFISH = "goldfish";
private static final String RANCHU = "ranchu";
private static final String SDK = "sdk";
public static boolean isEmulator() {
return Build.PRODUCT.contains(SDK)
|| Build.HARDWARE.contains(GOLDFISH)
|| Build.HARDWARE.contains(RANCHU);
}
The above suggested solution to check for the ANDROID_ID worked for me until I updated today to the latest SDK tools released with Android 2.2.
Therefore I currently switched to the following solution which works so far with the disadvantage however that you need to put the PHONE_STATE read permission (<uses-permission android:name="android.permission.READ_PHONE_STATE"/>)
private void checkForDebugMode() {
ISDEBUGMODE = false; //(Secure.getString(getApplicationContext().getContentResolver(), Secure.ANDROID_ID) == null);
TelephonyManager man = (TelephonyManager) getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE);
if(man != null){
String devId = man.getDeviceSoftwareVersion();
ISDEBUGMODE = (devId == null);
}
}
Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic")
This should return true if the app is running on an emulator.
What we should be careful about is not detecting all the emulators because there are only several different emulators. It is easy to check.
We have to make sure that actual devices are not detected as an emulator.
I used the app called "Android Device Info Share" to check this.
On this app, you can see various kinds of information of many devices (probably most devices in the world; if the device you are using is missing from the list, it will be added automatically).
All answers in one method
static boolean checkEmulator()
{
try
{
String buildDetails = (Build.FINGERPRINT + Build.DEVICE + Build.MODEL + Build.BRAND + Build.PRODUCT + Build.MANUFACTURER + Build.HARDWARE).toLowerCase();
if (buildDetails.contains("generic")
|| buildDetails.contains("unknown")
|| buildDetails.contains("emulator")
|| buildDetails.contains("sdk")
|| buildDetails.contains("genymotion")
|| buildDetails.contains("x86") // this includes vbox86
|| buildDetails.contains("goldfish")
|| buildDetails.contains("test-keys"))
return true;
}
catch (Throwable t) {Logger.catchedError(t);}
try
{
TelephonyManager tm = (TelephonyManager) App.context.getSystemService(Context.TELEPHONY_SERVICE);
String non = tm.getNetworkOperatorName().toLowerCase();
if (non.equals("android"))
return true;
}
catch (Throwable t) {Logger.catchedError(t);}
try
{
if (new File ("/init.goldfish.rc").exists())
return true;
}
catch (Throwable t) {Logger.catchedError(t);}
return false;
}
Checking the answers, none of them worked when using LeapDroid, Droid4x or Andy emulators,
What does work for all cases is the following:
private static String getSystemProperty(String name) throws Exception {
Class systemPropertyClazz = Class.forName("android.os.SystemProperties");
return (String) systemPropertyClazz.getMethod("get", new Class[]{String.class}).invoke(systemPropertyClazz, new Object[]{name});
}
public boolean isEmulator() {
boolean goldfish = getSystemProperty("ro.hardware").contains("goldfish");
boolean emu = getSystemProperty("ro.kernel.qemu").length() > 0;
boolean sdk = getSystemProperty("ro.product.model").equals("sdk");
return goldfish || emu || sdk;
}
My recommendation:
try this from github.
Easy to detect android emulator
Checked on real devices in Device Farm (https://aws.amazon.com/device-farm/)
BlueStacks
Genymotion
Android Emulator
Andy 46.2.207.0
MEmu play
Nox App Player
Koplayer
.....
How to use with an Example:
EmulatorDetector.with(this)
.setCheckTelephony(true)
.addPackageName("com.bluestacks")
.setDebug(true)
.detect(new EmulatorDetector.OnEmulatorDetectorListener() {
#Override
public void onResult(boolean isEmulator) {
if(isEmulator){
// Do your work
}
else{
// Not emulator and do your work
}
}
});
you can check the IMEI #,
http://developer.android.com/reference/android/telephony/TelephonyManager.html#getDeviceId%28%29
if i recall on the emulator this return 0. however, there's no documentation i can find that guarantees that. although the emulator might not always return 0, it seems pretty safe that a registered phone would not return 0. what would happen on a non-phone android device, or one without a SIM card installed or one that isn't currently registered on the network?
seems like that'd be a bad idea, to depend on that.
it also means you'd need to ask for permission to read the phone state, which is bad if you don't already require it for something else.
if not that, then there's always flipping some bit somewhere before you finally generate your signed app.
Actually, ANDROID_ID on 2.2 always equals 9774D56D682E549C (according to this thread + my own experiments).
So, you could check something like this:
String androidID = ...;
if(androidID == null || androidID.equals("9774D56D682E549C"))
do stuff;
Not the prettiest, but it does the job.
This works for me
public boolean isEmulator() {
return Build.MANUFACTURER.equals("unknown");
}
Put a file in the file system of the emulator; since the file won't exist on the real device, this should be stable, reliable and easy to fix when it breaks.
I've collected all the answers on this question and came up with function to detect if Android is running on a vm/emulator:
public boolean isvm(){
StringBuilder deviceInfo = new StringBuilder();
deviceInfo.append("Build.PRODUCT " +Build.PRODUCT +"\n");
deviceInfo.append("Build.FINGERPRINT " +Build.FINGERPRINT+"\n");
deviceInfo.append("Build.MANUFACTURER " +Build.MANUFACTURER+"\n");
deviceInfo.append("Build.MODEL " +Build.MODEL+"\n");
deviceInfo.append("Build.BRAND " +Build.BRAND+"\n");
deviceInfo.append("Build.DEVICE " +Build.DEVICE+"\n");
String info = deviceInfo.toString();
Log.i("LOB", info);
Boolean isvm = false;
if(
"google_sdk".equals(Build.PRODUCT) ||
"sdk_google_phone_x86".equals(Build.PRODUCT) ||
"sdk".equals(Build.PRODUCT) ||
"sdk_x86".equals(Build.PRODUCT) ||
"vbox86p".equals(Build.PRODUCT) ||
Build.FINGERPRINT.contains("generic") ||
Build.MANUFACTURER.contains("Genymotion") ||
Build.MODEL.contains("Emulator") ||
Build.MODEL.contains("Android SDK built for x86")
){
isvm = true;
}
if(Build.BRAND.contains("generic")&&Build.DEVICE.contains("generic")){
isvm = true;
}
return isvm;
}
Tested on Emulator, Genymotion and Bluestacks (1 October 2015).
Whichever code you use to do emulator detection, I'd highly recommend writing unit tests to cover all the Build.FINGERPRINT, Build.HARDWARE and Build.MANUFACTURER values that you are depending on. Here are some example tests:
#Test
public void testIsEmulatorGenymotion() throws Exception {
assertThat(
DeviceUtils.isRunningOnEmulator(
"generic/vbox86p/vbox86p:4.1.1/JRO03S/eng.buildbot.20150217.102902:userdebug/test-keys",
"vbox86", "Genymotion")).isTrue();
assertThat(
DeviceUtils.isRunningOnEmulator(
"generic/vbox86p/vbox86p:5.1/LMY47D/buildbot06092001:userdebug/test-keys", "vbox86",
"Genymotion")).isTrue();
}
#Test
public void testIsEmulatorDefaultAndroidEmulator() throws Exception {
assertThat(
DeviceUtils.isRunningOnEmulator(
"generic_x86/sdk_google_phone_x86/generic_x86:5.0.2/LSY66H/1960483:eng/test-keys", "goldfish",
"unknown")).isTrue();
assertThat(
DeviceUtils.isRunningOnEmulator(
"Android/sdk_google_phone_x86_64/generic_x86_64:6.0/MASTER/2469028:userdebug/test-keys",
"ranchu", "unknown")).isTrue();
}
#Test
public void testIsEmulatorRealNexus5() throws Exception {
assertThat(
DeviceUtils.isRunningOnEmulator("google/hammerhead/hammerhead:6.0.1/MMB29K/2419427:user/release-keys",
"hammerhead", "LGE")).isFalse();
}
...and here's our code (debug logs and comments removed for conciseness):
public static boolean isRunningOnEmulator() {
if (sIsRunningEmulator == null) {
sIsRunningEmulator = isRunningOnEmulator(Build.FINGERPRINT, Build.HARDWARE, Build.MANUFACTURER);
}
return sIsRunningEmulator;
}
static boolean isRunningOnEmulator(String fingerprint, String hardware, String manufacturer) {
boolean isEmulatorFingerprint = fingerprint.endsWith("test-keys");
boolean isEmulatorManufacturer = manufacturer.equals("Genymotion")
|| manufacturer.equals("unknown");
if (isEmulatorFingerprint && isEmulatorManufacturer) {
return true;
} else {
return false;
}
}
Another option is to check if you are in debug mode or production mode:
if (BuildConfig.DEBUG) { Log.i(TAG, "I am in debug mode"); }
simple and reliable.
Not totally the answer of the question but in most cases you may want to distinguish between debugging/test sessions and life sessions of your user base.
In my case I set google analytics to dryRun() when in debug mode so this approach works totally fine for me.
For more advanced users there is another option. gradle build variants:
in your app's gradle file add a new variant:
buildTypes {
release {
// some already existing commands
}
debug {
// some already existing commands
}
// the following is new
test {
}
}
In your code check the build type:
if ("test".equals(BuildConfig.BUILD_TYPE)) { Log.i(TAG, "I am in Test build type"); }
else if ("debug".equals(BuildConfig.BUILD_TYPE)) { Log.i(TAG, "I am in Debug build type"); }
Now you have the opportunity to build 3 different types of your app.

Android Airplane Mode - Different API versions

Can somebody tell me how to handle this situation. I am aware that with API 17, testing for airplane mode has been moved from Setting.System to Settings.Global. Knowing that many of the users will be on phones using the older api, but wanting to handle the deprecation correctly, I've written the following method:
#SuppressWarnings("deprecation")
public static boolean isAirplaneModeOn(Context context) {
try {
return Settings.Global.getInt(context.getContentResolver(),
Settings.Global.AIRPLANE_MODE_ON, 0) != 0;
} catch (Exception e) {
return Settings.System.getInt(context.getContentResolver(),
Settings.System.AIRPLANE_MODE_ON, 0) != 0;
}
}
The problem is that in my manifest, I've set the minSDK value to 9, which is where I want it. The conflict is that then I get this error:
Call requires API level 17 (current min is 9)
What is the correct way to handle this type of situation? Thanks!
check which version the user has
if(Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLYBEAN){
}else{
}
then just suppress the lint error

Categories

Resources