dex
dex

Reputation: 5230

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.

Upvotes: 28

Views: 8441

Answers (4)

fattire
fattire

Reputation: 8843

2023 Note-- Jump to the bottom of this answer to read the latest way Android identifies a Chromebook/Desktop/PC device, including a new test from within the Android emulator. Or, keep reading below for the full, exciting history of the ARC check and how Google has changed their own method several times.

Older:

A 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.

June 30, 2023 - hasAnySystemFeature() doesn't seem to work in recent ChromeOS/Desktop emulator images (such as the Sv2 - Android 12L API 34 (desktop) image). However, it looks like you can detect this in the Android Emulator by checking for the device model info found in ro.product.model From the adb shell, use $ getprop | grep ro.product.model to see a line like:

 [ro.product.model]: [sdk_gpc_x86_64]

The "gpc" sugggests Google PC (There exists also a sdk_gphone64_x86_64 as a matter of comparison), and hints in code elsewhere suggest this may be a new convention. So in Kotlin, if you're looking for ChromeOS in the emulator, try adding this to the hasAnySystemFeature() check above:

// is the emulator running a desktop/ChromeOS image?
if (Build.MODEL != null && Build.MODEL.startsWith("sdk_gpc_")) {
   // it probably is (?)
}

Upvotes: 10

Blue Ocean
Blue Ocean

Reputation: 443

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

Upvotes: 2

Gabor
Gabor

Reputation: 7572

PackageManager pm = context.getPackageManager();
if (pm.hasSystemFeature(PackageManager.FEATURE_PC)) 
   // it's a chromebook

Upvotes: 2

dex
dex

Reputation: 5230

Finally I figure out a way to know if app in running in ARC:

context.getPackageManager().hasSystemFeature("org.chromium.arc.device_management");

Upvotes: 30

Related Questions