43

As part of my app I'm using the NDK and was wondering if it's worth bundling x86 and mips binaries alongside the standard ARM binaries.

I figured the best way would be to track what my users actually have, is there an API call to grab the processor architecture so I can pass this back to my Google analytics instance?

Thanks

Paul Verest
  • 60,022
  • 51
  • 208
  • 332
Ljdawson
  • 12,091
  • 11
  • 45
  • 60
  • If you just put ARM binaries, will the other architectures be able to download it? http://software.intel.com/en-us/articles/publishing-your-android-application-on-the-android-market/ – Stéphane Aug 16 '12 at 16:48
  • No , it will support only supported binaries based on architecture. – PRATEEK BHARDWAJ Jan 22 '18 at 06:36

9 Answers9

80

Actually, you can get the architecture without the need for reflexion at all:

String arch = System.getProperty("os.arch");

From my tests it returned armv71 and i686.

EDIT:

On MIPS architecture, it either returns 'mips' or 'mips64'

On 64 bit ARM/Intel, it returns 'aarch64' or 'x86_64' respectively.

Vaiden
  • 15,728
  • 7
  • 61
  • 91
3c71
  • 4,313
  • 31
  • 43
  • What does it return for MIPS-based processors? – Nathan Osman May 17 '13 at 17:43
  • I've believe it returns "mips", can't remember if I actually tested in the emulator. But that's what I use. – 3c71 May 18 '13 at 09:36
  • Just to make things right- I'm getting 'armv7l' and not 'arm71' as you said. any reason that you can think of? – shem Jun 16 '13 at 14:28
  • 1
    THat's why I check only on "arm" because it varies from device to device – 3c71 Jun 25 '13 at 17:44
  • Wouldn't it be better to have a compile-time-constant here so any conditionals that depends on it can be optimized away at compile time? Not a big deal if this is in a JIT-compiled language, though. – Peter Cordes Apr 06 '16 at 20:06
  • It's worth pointing out that this returns the **JRE**'s architecture, not the underlying system architecture. However, on Android, these will pretty much always match because of how the system is integrated with Java, and as such all the current answers should return the same architecture. – Joe Dec 02 '17 at 21:23
  • Shouldn't it be `aarch64`, not `arch64`? – Peter Cordes Apr 09 '18 at 22:41
  • *Processor architecture is a runtime information* I think 2 years ago I didn't realize this was a Java question. The OP was talking about making x86 binaries vs. MIPS binaries, so clearly they are making different binaries for different platforms, and thus could make it a compile-time constant if they had different builds of this code for every platform. – Peter Cordes Apr 09 '18 at 22:43
  • in emulator I got i686.how to get all values? It maybe armv71 or others. – aolphn Apr 12 '18 at 11:26
18

You can also use android SDK, take a look on the Build class:

    /** The name of the instruction set (CPU type + ABI convention) of native code. */
    public static final String CPU_ABI = getString("ro.product.cpu.abi");

    /** The name of the second instruction set (CPU type + ABI convention) of native code. */
    public static final String CPU_ABI2 = getString("ro.product.cpu.abi2");
shem
  • 4,686
  • 2
  • 32
  • 43
  • way better than using reflection ! Nice ! – Teovald Sep 18 '14 at 15:59
  • 5
    The CPU_ABI* constants have been deprecated in favor of SUPPORTED_*ABIS but these constants work in pretty much the same way and are still part of the Build object, – Moritz Oct 09 '15 at 09:41
18

You can use the Build class:

import android.os.Build;

and then read:

Build.CPU_ABI

Leigh
  • 28,765
  • 10
  • 55
  • 103
and0421
  • 181
  • 1
  • 3
  • This is a complete answer, but [the same answer](http://stackoverflow.com/a/17134383/104223) was already suggested over a year ago. Please take the time to review the previous answers before posting :) – Leigh Dec 26 '14 at 03:49
  • 1
    @Leigh This answer is different (more efficient and more future-proof) to the one provided by shem. IMO this should be the accepted answer. – rsp1984 Jun 12 '16 at 17:02
12

You can use adb command

adb shell getprop ro.product.cpu.abi adb shell getprop ro.product.cpu.abi2

and refer the [site]: How to know a process of an app is 32-bit or 64-bit programmatically in Android lollipop?

If you're looking for the Lollipop API

import android.os.Build;

Log.i(TAG, "CPU_ABI : " + Build.CPU_ABI);
Log.i(TAG, "CPU_ABI2 : " + Build.CPU_ABI2);
Log.i(TAG, "OS.ARCH : " + System.getProperty("os.arch"));

Log.i(TAG, "SUPPORTED_ABIS : " + Arrays.toString(Build.SUPPORTED_ABIS));
Log.i(TAG, "SUPPORTED_32_BIT_ABIS : " + Arrays.toString(Build.SUPPORTED_32_BIT_ABIS));
Log.i(TAG, "SUPPORTED_64_BIT_ABIS : " + Arrays.toString(Build.SUPPORTED_64_BIT_ABIS));
Community
  • 1
  • 1
tommybee
  • 2,409
  • 1
  • 20
  • 23
  • Use a check like the one below to decide which API you'll use: if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) – Stan Jul 27 '16 at 13:56
11

Try this command:

adb shell getprop ro.product.cpu.abi

It tells whether cpu is ARM or Intel( 64 or 86_64 respectively )

Maher Abuthraa
  • 17,493
  • 11
  • 81
  • 103
  • How is developer able to run `adb` command on users smartphones? – h3wro Apr 11 '20 at 12:21
  • 2
    adb not designed to be called from device .. it's basically debugging tool from PC to device/emulator. what you need to access console through app. I think there are limitation and you may need root .. if you need to get this info from app I recommend you to use other approach – Maher Abuthraa Jul 28 '21 at 05:01
6

The values you are looking for are

ro.product.cpu.abi

and

ro.product.cpu.abi2

These can be got using internal api SystemProperties.get So you will have to use Reflection on SystemProperties.

You could use the function getSystemProperty if you are not too keen on reflection. Check it here

Community
  • 1
  • 1
nandeesh
  • 24,740
  • 6
  • 69
  • 79
5

termux-app uses a different approach and has an explanation:

private static String determineTermuxArchName() {
    // Note that we cannot use System.getProperty("os.arch") since that may give e.g. "aarch64"
    // while a 64-bit runtime may not be installed (like on the Samsung Galaxy S5 Neo).
    // Instead we search through the supported abi:s on the device, see:
    // http://developer.android.com/ndk/guides/abis.html
    // Note that we search for abi:s in preferred order (the ordering of the
    // Build.SUPPORTED_ABIS list) to avoid e.g. installing arm on an x86 system where arm
    // emulation is available.
    for (String androidArch : Build.SUPPORTED_ABIS) {
        switch (androidArch) {
            case "arm64-v8a": return "aarch64";
            case "armeabi-v7a": return "arm";
            case "x86_64": return "x86_64";
            case "x86": return "i686";
        }
    }
    throw new RuntimeException("Unable to determine arch from Build.SUPPORTED_ABIS =  " +
        Arrays.toString(Build.SUPPORTED_ABIS));
}

From: https://github.com/termux/termux-app/blob/master/app/src/main/java/com/termux/app/TermuxInstaller.java

Ljdawson
  • 12,091
  • 11
  • 45
  • 60
Ratata Tata
  • 2,781
  • 1
  • 34
  • 49
2

My Code looks like this

private String cpuinfo()
{
String arch = System.getProperty("os.arch");    
String arc = arch.substring(0, 3).toUpperCase();
String rarc="";
if (arc.equals("ARM")) {
    rarc= "This is ARM";
    }else if (arc.equals("MIP")){
        rarc= "This is MIPS";
    }else if (arc.equals("X86")){
        rarc= "This is X86";
    }
    return rarc;
}
Robs Ned
  • 21
  • 1
  • Can you please tell me armeabi-v7a & armeabi-v7a-neon are same or different cpu arch?? – Ahmad Arslan Sep 30 '15 at 05:20
  • NEON is a specific feature which CPUs can support. If you only want to check if the CPU is ARM, use `System.getProperty("os.arch").toLowerCase().contains("arm")`. – xdevs23 Mar 04 '16 at 17:45
0

see this link : https://developer.android.com/reference/android/os/Build#SUPPORTED_ABIS

Build.SUPPORTED_32_BIT_ABIS;
Mahdi Zareei
  • 1,299
  • 11
  • 18