Rickard Andersson
Rickard Andersson

Reputation: 579

How do I develop an app for a specific build of AOSP from Android Studio?

My current phone (Pixel 2 XL) is running the build PQ1A.181105.017.A1. According to source.android.com, that means it was build from branch android-9.0.0_r16. Looking at a source file from that particular branch, for example SignalStrength.java, there is a public method called getWcdmaRscp(). However, it appears this method was added after SDK version 28 was released, so if I try to call it from my app in Android Studio when targeting 28, it doesn't build.

I'm guessing my phone will gladly allow me to call the method in question, so how do I setup my Android Studio to be able to build against that version of the framework?

It appears I would need a new framework.jar, but where can I find that? Please don't tell me I need to download and build the entire AOSP thing locally.

Upvotes: 1

Views: 367

Answers (2)

Lev M.
Lev M.

Reputation: 6269

You don't need the whole framework.jar

While one way would be to use reflection as TheWanderer suggested, another option is to add the single source file you linked to, SignlaStrength.java, to your project.

You just need to make sure you add it under the original package path /android/telephony

The studio will use it for compilation to resolve method signatures, but when running on the phone the calls will go through to the original framework class. I didn't see any non public imports in the file, but if it does not compile, you may need to turn it in to a stub, by removing some function internals.

Upvotes: 1

TheWanderer
TheWanderer

Reputation: 17854

I doubt it was added after API 28 was released. It's annotated with @hide which means, when the SDK was built, it wasn't built in. It's still in the framework itself, but Android Studio doesn't know that.

To get around this, you'll have to use reflection. Something like:

try {
    Method getWcdmaRscp = SignalStrength.class.getMethod("getWcdmaRscp");
    int rscp = Integer.parseInt(getWcdmaRscp.invoke(signalStrength).toString()); //signalStrength is the instance you have
} catch (Exception ignored) {}

However, that probably won't work. Android Pie introduced restrictions on accessing hidden methods and classes. In Oreo, you could just use reflection. In Pie, most of the classes you try to access will throw a ClassNotFound or NoSuchMethodError exception, because the system prevents third-party apps from accessing them. Certain hidden APIs are still accessible, but there's no definitive list.

Upvotes: 2

Related Questions