Trying to develop android LPA system app for eSIM with the new Pie API.
The doc says to extend the abstract EuiccService class. But this class is not in the official SDK, and the link in the docs just leads to corresponding file in the android source repo.
I tried using this file/class as a dependency, but it references other internal android classes/annotations and causes build/IDE errors.
Does anyone have an idea how to use this?
Do I really have to pull android src code and somehow reference required class from it?
EDIT: I think I've solved it, found couple of potential solutions, but they were a bit cumbersome. Used the android.jar from here: https://github.com/anggrayudi/android-hidden-api (contains modified android.jar with hidden APIs and internal resources). It didn't work when i replaced the whole file and resulted strange build errors, but i manually transferred the android\service\euicc\ folder to original android.jar of android-28 sdk and it works perfectly (class is available and apk builds without issues). And no need to waste time pulling and building AOSP.
EDIT #2: apparently not fully fixable atm. There's issue with android gradle plugins (at least 3.2.x-3.3.x) where during full sync some build task generates mock classes from android.jar and process fails if it's modified (discussion is here: https://github.com/anggrayudi/android-hidden-api/issues/46). Error looks like this:
Failed to transform file 'android.jar' to match attributes {artifactType=android-mockable-jar, returnDefaultValues=false} using transform MockableJarTransform
There's a workaround for that, though inconvenient:
when you need a full sync for the project, replace the android.jar with original, run sync, restore modified android.jar, the IDE now will run indexing and classes will be available again with build working until next full sync.
Will update this post if/when it's fixed or new solution is found.
EDIT#3: here's probably a final solution for EuiccService case (turned out pretty obvious):
Instead of adding 'android/service/euicc' folder to android.jar, just put it in a separate library and add it as a compileOnly dependency. Since the classes were not in the SDK, the lib should not cause conflict (would be the case if you need to use modified framework or access hidden APIs in already existing classes).
If you are going to create a System APP, you will do it in several ways:
You could call a part of the SystemAPI (a method for example) by reference.
You could make the aplication as a part of the AOSP Project (Downloading the AOSP code, and introducing your app as part of packages/apps/)
You will be able to access system APIs on a rooted device or if you have system permissions (this happens when you flash your app into the device as part of the system image).
However, if you want to be able to call the EuiccService class from Android Studio (for coding purposes), you'll need to add the Android framework jar to your project.
The steps are provided below:
First, you will have to download and build AOSP and generate a framework jar for your target Android version. Check the documentation here to get an idea of how to download and build AOSP.
After a successful build all framework classes are compiled into a jar called classes.jar which can be found at the location out/target/common/obj/JAVA_LIBRARIES/framework_intermediates.
Get this classes.jar and add it to your Android project as a jar file.
Gradle sync the project and start coding.
Please beware that you WILL NOT BE ABLE TO run this app on an Adnroid device where you do not have system permission for this app.
Related
I need your help, (I searched the questions, but I do not understand though the answers are positive) What should insert code? (The answer comes that I send the code of appcompatactivity. But I do not understand)
I'm working with android NDK but send me the error .. This is my code
C:\Users\Eduu\AndroidStudioProjects\NDKSample2\app\src\main>javah -d jni classpath C:\Users\Eduu\AppData\Local\Android\sdk\platforms\android-19\android.jar;..\..\build\intermediates\classes\debug com.example.eduu.ndksample2.MainActivity
work: Android Studio
When you create a new app, Eclipse gives you a copy of the compatibility library. (One can only guess if you are using Eclipse, but I do.) The purpose of this library is to implement fragments and other post-3.0 stuff on 2.x devices. You are given this library only if you specify a 2.x target when you create the project. In one of my workspaces, I have 24 copies of the library, ranging from appcompat_v7 to appcompat_v7_24. Each one is located on the same directory level as the corresponding project, that is, in the same parent folder. It is easy to guess which copy corresponds to the latest project, but if you don't know for sure that the project is the latest one, you have to search the config files.
If you put your project under version control and forget about this dependency, you get an error in the copy retrieved from the version control. Fixing it is a tedious task, Eclipse is no lucid coding. You will have to manually specify the dependency in several places. One possible approach is to create a new project and move the source to it (note that you can move the version control directory, like .hg or .git, and restore the source, if that does not sound too untrivial for you), another one is to create a new project and use its compatibility library.
Background
I'm working on an app that has become very popular, so much that a part of it is supposed to become an SDK (which would be available for developers), and the app will split to 2 apps (both use the SDK).
According to what I know, there are multiple ways to create an SDK module (previously called "project" on Eclipse) :
Completely open sourced (Android library) - all sources and resources are open sourced and can be modified. An example might be Facebook's SDK and a lot of Github repos.
a single Jar file, which can be closed sourced.
The problem
Sadly, I can't make the SDK open sourced, and it should relatively be protected vs prying eyes (obfuscated etc...).
The issue here is, the SDK needs to use some resources of its own (drawables, strings,...), and so far (because I didn't have a lot of experience with creating SDKs) I've found 2 ways to handle resources for SDKs :
use reflection and/or "context.getResources().getIdentifier" . This is quite messy, as I lose the whole "R" usage of the code. Also, it has issues with "styleable" , as I've written here. It also makes it hard to find unused resources.
even worse ways: put resources in assets folder, put files in a wacky way inside the jar file, ...
Note that a part of the SDK includes custom views (for example, classes that extend from TextView), so even if I do split the SDk into 2 modules- resources and java files, both might have issues of dependencies (each uses the other one).
The question
Is it possible to somehow solve this issue?
Is it possible for the code part of the SDK to remain closed sourced, reach the "R" file as usual, and make it easy for both me and whoever use the SDK ?
How would I then generate the jar file as being obfuscated via Android Studio? and is it possible to prepare it to to be used via gradle afterwards?
Can I maybe make the Android-library of the SDK into an obfuscated jar file and not worry about the "R" file ? I ask this because this way I could enjoy both worlds: for our apps, it would remain open sourced, and for third party apps it would be closed sourced.
EDIT: seeing that this is supposed to be easy, I've tried it myself. I've created a totally new POC project which has an Android library module called "sdkmodule", and added this class to it:
public class SdkClass
{
public String doIt(Context context)
{
return context.getResources().getString(R.string.app_name);
}
}
Then, I've made the app's module to use this one, and I wrote this code in it:
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SdkClass sdkClass=new SdkClass();
Log.d("AppLog","string from SDK:"+sdkClass.doIt(this));
Log.d("AppLog","string with same ID name from app:"+getResources().getString(R.string.app_name));
}
What I expected is that the first log would print the string that's in the SDK module, and the second to show the string of the current project, but instead I got an exception:
java.lang.NoClassDefFoundError: Failed resolution of: Lcom/example/user/sdkmodule/R$string;
On another try, I've got the same string that's used on the app itself (the one that uses the SDK module). And, on another run, the SDK produced the needed string as I've wanted.
How could it be? What should I do ?
In addition, I've tried to make a second activity in the SDK itself, and I've created a resource there that has the same resource name (used for a textView in its layout) as of the app itself, yet with a different value, yet when I've reached this activity, I've seen the one used by the app.
Here's the project, zipped (ignore the name of the folder, I wanted to try flavors too) :
https://drive.google.com/file/d/0B-PZZGk2vPohX25WUDNKTmotUTg/view?usp=sharing
The answer to your problem is to package and distribute your library as an AAR bundle
This format allows you to provide an obfuscated SDK jar and with its resources and the R mapping file.
This format is a standard and fully supported by maven-android-plugin (actually it's the replacement of the old APKLib format which supports only the distribution of source files).
Of course it's also supported by Gradle and Android Studio.
The Android Archive (AAR) format does what you want. It's like an Android-specific JAR file and contains compiled code, but includes its own resources and manifest. You can also include obfuscation as part of the build process. By default, the current version of Android Studio (1.2) and Gradle automatically build .AAR files for all library modules you create in your project.
You can change an app module into a library project that will publish an AAR file just by changing apply plugin: 'com.android.application' into apply plugin: 'com.android.library' in your module's Gradle file. The .AAR file will be placed in your MODULENAME/build/outputs/aar folder after each build. Some more information is available here.
Edit 1, after question updated:
The resources in your AAR get consolidated with the app module when the final APK gets compiled. The app resources will override the library's. This is probably by design, to allow people using a 3rd party library to customize its resources when creating their app, without having to rebuild the library. I think the easiest way to solve your resource conflict issue would just be to name your sdkmodule resources something more unique. Why not make the string key R.string.com_example_sdk_name or something?
No, the AAR libraries don't get obfuscated by default, but you can set up ProGuard in the Gradle build file for your AAR library to take care of this. Other tools are also available.
I'm attempting to write an application which uses a few classes and constants that were added to cyanogenmod and do not exist within the standard andriod api.
My question is, using the android SDK, eclipse and ADT, is it possible to get and build against a cyanogenmod version of the andriod.jar file?
In case anyone else ends up in this situation.
Since the andriod.jar file which is used during compilation is basically a set of stubs, I created a separate jar file of my own, with stubbed out versions of the necessary classes & constants, and included that class at compile time for my app (using maven scopes in my case).
First of all, i'm new on ProGuard, but i read some tutorials and i know that the best way to use it on android is the one described on android.developer guide.
im trying to obfuscate the code of my new Android app with ProGuard. For that i enter this website: http://developer.android.com/tools/help/proguard.html#enabling
But it tells: "hen you create an Android project, a proguard.cfg file is automatically generated in the root directory of the project."
That file does not exist on my project root directory, so i dont know how to continue. My Android app is for api level 4, 1.6, so, is it possible that this is a problem for using ProGuard?
How can i use proguard with an app for api 4 (android 1.6)
Thanks a lot
You need a proguard.cfg File. You can either create it by hand or use the proguard-GUI (> java -jar proguardgui.jar). Using the GUI makes some things easier, but a basic understandig of proguard and obfuscating is still required. It isn't very comfortable to use the gui for obfuscating your release apk, so proviging the config-file and using the SDKs Build tools is still the best way to go.
The ACRA Documentation features an Example for a proguard.cfg http://code.google.com/p/acra/wiki/ACRAProGuardHowTo most of the stuff is ACRA related and can be ommited if you don't use ACRA in your project.
I Don't know if the SDK is supposed to create an proguard.cfg. If never seen one which was created automaticaly, so i suggest you go with the file as supplied by the acra-guys for a starting point.
Make sure that you are using the latest Android SDK. You can check this with the standard android application from the SDK.
Then make sure that your project directory is up-to-date too, by typing
adb update project -p MyProjectDirectory
(from the command-line, with the proper path to the directory of your project). This should create a ProGuard configuration file, which is called proguard-project.txt in recent releases of the SDK.
You can then enable ProGuard by uncommenting the proper line in project.properties.
I have seen this question, and have some more doubts regarding creating a jar file which I can distribute and can be used in any android applications.
What my requirement is
As I said, I want to build and distribute a closed source library. I
don't want the source code to be visible.
In that library I don't want to use any assets, layouts, resources
etc. But I want to use some android specific codes, like getting
android device id.
The most popular answer in the above linked SO question tells to create a regular java project and import android.jar in it. I tried to do that, but I don't know how to add android.jar to any java project. I would like to get some clarification on that too.
Moreover I would like to know if there are any other methods using android sdk itself (without using java project) create a closed source library jar file.
I think what I want is possible, since google analytics for android native apps seems to have done it. I am sure in the .jar file they distribute they are using android specific codes, since there seems no other way for them to get the device information to display in the analytics viewer.
EDIT : CAN SOMEONE CLARIFY THIS??
I think I have made some progress. This is what I have done
Created a regular android project (not library project, the "is
Library" checkmark is unchecked)
In the project I have coded out my logic. It uses some android
specific classes like SharedPreference, UUID, PackageManager. But
nothing related with assets, layouts also no class extending
Activity. Just a java class extending java.lang.object
Exported the project using Project->rightclick->export->Java->JAR
file. In the next screen I unchecked the checkbox near
AndroidManifest.xml. Set a destination directory to export and
clicked next thrice with keeping the default settings. Then I clicked
Finish, and got a lovely libMyLibraryName.jar at my desktop.
Then I created another android project, added this libMyLibraryName.jar to new project using project->rightclick->properties->java build path -> libraries->add external jar.
And I tried to use my class in the library, in my new project
MyLibraryClass objClass = new MyLibraryClass(this);
And I was able to compile and run successfully. I even sent the library to one of my co worker who was able to use the library in his on machine (Just making sure library project in my workspace wont influence the project using it).
Now I have 2 questions.
1) My first question is , what they meant by the term "true library" in the below given documentation ? Is it any non android java project which can be exported to a JAR file?
However, a library project differs from an standard Android
application project in that you cannot compile it directly to its own
.apk and run it on an Android device. Similarly, you cannot export
the library project to a self-contained JAR file, as you would do
for a true library. Instead, you must compile the library indirectly,
by referencing the library in the dependent application and building
that application.
Well this portion is taken from documentation under title "Library Projects".
2) My second question is, anything wrong with the way I have created the JAR file? Any possible pitfalls which might bite me back later? I would like to make sure I am not doing something terribly wrong, before using it in my important projects.
I might add that I didn't try the method of creating a JAVA project and importing android.jar. I am ready to try that one, if what I have done currently is wrong.
The android.jar will be located where you installed your Android SDK. Under the platforms directory there should be a number of other directories named android-<version>. The android.jar will be there. Choose the one specific to the minimum android version you are targeting.
Once you have that, copy it into your project. If you're using eclipse I think you can just cut and paste jars straight into your project, right click and add it to build path. If you're not using eclipse or any other IDE, you just need to ensure that the android.jar is on the classpath when building your jar file.
After that your newly built android library can be dropped into any Android project.
In answer to your additional questions:
What they mean by a true library is a jar file as opposed to an Android library project.
I don't think there's anything wrong with the way you created the jar file. I would have made it using the android.jar as I mentioned above but your way should also work. To verify this I would examine the jar contents and make sure all you have in there is .class files.