I have a an app that has 2 modules base and restaurant. I have a module output that is used for normal app release and another one for instant app. When I run the build using android studio it is working fine but when I run
./gradlew assembleRelease only the output module seems to be built. Is it possible to create the instant app apk from terminal? My instant app gradle file is only like:
apply plugin: 'com.android.instantapp'
dependencies {
implementation project(':base')
implementation project(':restaurant')
}
without any signing configs inside.
Gradle build only one module gives you a clue.
You can point gradle to the com.android.instantapp module. The instant app module basically instructs which modules to assemble, those defined by implementation project(), and zip them up for the instant app.
This base cmd worked for me:
./gradlew instantapp:assemble
Then the ia zip files will be contained in the instantapp /build/output/apk/ directory.
But even if you run ./gradlew assemble, you should still find your instant app apks.zip in that same directory.
You should open the Gradle window.
View -> Tool Windows -> Gradle.
You can synchronise and run any task you want to execute (independently).
if you need absolutely to do in the terminal or in a script.
I m sure that after seen the name of the task. You ll be able to write your command line.
It doesn't look like this question was ever answered, so in case anyone else is searching for it, here you go:
The new recommended way to produce an Instant App is via Instant Enabled App Bundles. (See Google Developer Documents for details)
Basically, you need to first build an app "bundle". To do so, there are a number of steps, but basically you need to get your application within the recommended size limitations (10 MB) and ensure that you are not using any unsupported permissions. If you are working with a larger application, the best way to do this is to modularize your features and only include those features that you want to be "instant". This "instant" version of your application will be a separate Flavor, and from there, you can add in the following to the Manifest that corresponds to the Instant app version of your application.
<manifest ... xmlns:dist="http://schemas.android.com/apk/distribution">
<dist:module dist:instant="true" />
...
</manifest>
When you've done that, if you want to build using CLI/Terminal, you will need to build using the new bundle version of your application. You can run ./gradlew tasks to see what options you have available, or just run ./gradlew bundle which will run them all.
Next, to test to ensure that your app bundle was done correctly, you will need a couple more tools. The bundletool (provided by Google here), and the ia tool, located in your $ANDROID_HOME/extras/google/instantapps/ directory. (Just slap that on your path or have an alias point to it).
With both of these tools in hand, you will need access to a signing key for the instant app. I haven't tried it, but you could probably use the debug signing key for testing purposes. Just to quickly demonstrate how to build a key using CLI, here you go:
apksigner sign --ks my-instant-app-key.jks --out my-app-release.apk my-app-unsigned-aligned.apk
Note: Don't use this for production, this is just demonstration.
Now, we can build the APK's for our app bundle and sign them.
$ java -jar bundletool-all-*.jar build-apks \
//1
--bundle=app.aab \
//2
--output=app.apks \
//3
--connected-device \
//4
--ks=your-keystore-path \
//5
--ks-pass=pass:your-keystore-password \
//6
--ks-key-alias=your-key-alias \
//7
--key-pass=pass:your-key-password
Note: The above was taken from the following tutorial.
Next, check to see if your instant app was done correctly by running the following:
ia check instant-app.apks
The s at the end of apks is not a typo. If all checks out, you can run the app using:
ia run instant-app.apks
Hope this helps!
Related
I have been trying to make devops build of android apk and my pipeline fails in Signing and aligning Apk Stage.
I am getting the following error
##[error]Error: No matching files were found with search pattern: D:\a\1\s***.apk
PIPELINE Definition Snapshot_2
[error]Error: No matching files were found with search pattern: D:\a\1\s***.apk
This error indicates that you don't have a xx.apk file generated in default working directory. You can follow steps below to locate the root cause of the issue and resolve that:
Leave gradlew build task's working directory blank and make sure this task succeeds to generate the xx.apk file.
In Android signing task, use the **\*.apk pattern.
Make sure the gradlew build and Signing and aligning APK tasks are in same Job. If you're using hosted agent to run those tasks, they must be in same job within same pipeline/stage so that the Signing and aligning APK task can directly access the outputs of gradlew build task.
Please make sure these two tasks are in same job. If you have specific reason that you have to make them in separate jobs/stages/pipelines, consider using Artifacts-related tasks to share the files between jobs/stages/pipelines.
Since a job is a series of steps that run sequentially as a unit, different jobs will run in different machines though those agents are called hosted windows/linux. So it's recommended to put the two tasks in same job.
If the tasks are in same job while the issue persists, set the system.debug variable to true and run the pipeline again, then you can check the details about the gradlew build task.
Then you can find the output path where the xx.apk files are generated. After that copy those files to Default working directory ($(System.DefaultWorkingDirectory)) and the signing task can find the file.
It looks like .apk file is not found under working directory of the build agent. Please check code checkout step of the build pipeline and make sure the .apk file is being checked out as part of the build step. You can view the log as well to confirm this.
I have an Android project using two firebase instances per build variant (e.g. staging -> Firebase Project 1 and release -> Firebase Project 2). I'd like to be able to upload the mapping.txt whenever I invoke assemble so the crashes would be deobfuscated. Is there a way to dynamically set FirebaseServiceAccountFilePath property for each build variant? Thanks
Currently, you will have to invoke two different builds on the command line with the two different paths for your service account. So, something like this, if you have variants foo and bar:
./gradlew -PFirebaseServiceAccountFilePath=/path/to/foo.json firebaseUploadFooReleaseProguardMapping
./gradlew -PFirebaseServiceAccountFilePath=/path/to/bar.json firebaseUploadBarReleaseProguardMapping
There isn't currently a way to specify a different service account for both builds in a single invocation. However, if both variants use the same mapping, you can upload them both in the same invocation.
I faced this problem too today. After spending some time on this I simply wrote .sh file copied both the ./gradlew statements.
It is simply running both the statements one by one and I am able build apk and upload mapping file programmatically for both the firebase projects in single invocation.
I wrote an Android app that uses no dependencies or modules, has a single activity, and has a single layout file.
How can I build an apk file of my app on the command line without using Gradle (or other "build systems" or "dependency management" software)?
Use the following steps to build your apk manually, if you don't want use ant/gralde to build. But you must have Android SDK installed at least.
create R.java from aapt
use javac to compile all java source to *.class
use dx to convert all *.class to dex file, e.g output is classes.dex
create initial version of APK from assets, resources and AndroidManfiest.mk, e.g output is MyApplication.apk.unaligned
use aapt to add classes.dex generated in step 3 to MyApplication.apk.unaligned
use jarsigner to sign MyApplication.apk.unaligned with debug or release key
use zipalign to align the final APK, e.g output is MyApplication-debug.apk or MyApplication-release.apk if signing with release key
Done
I have created a sample script to do all the stuffs above, see here
Actually, Some articles have discussed this topic, see the following links.
https://www.apriorit.com/dev-blog/233-how-to-build-apk-file-from-command-line
https://spin.atomicobject.com/2011/08/22/building-android-application-bundles-apks-by-hand/
Try this for building apps with support libraries from command line. https://github.com/HemanthJabalpuri/AndroidExplorer
alijandro gave a perfect answer. I managed to write simple ANT script that builds production APK with AdMob and without gradle usage. A couple useful comments:
If you want to obfuscate classes you have to jar the compiled classes (between javac and dx steps) and run proguard on it
For AdMob you have to extract the following jars from zip archives (like
C:\Users\<User>\AppData\Local\Android\sdk\extras\google\m2repository\com\google\android\gms\play-services-ads\10.2.6\play-services-ads-10.2.6.aar):
play-services-ads-10.2.6.jar
play-services-ads-lite-10.2.6.jar
play-services-base-10.2.6.jar
play-services-basement-10.2.6.jar
play-services-clearcut-10.2.6.jar
play-services-gass-10.2.6.jar
play-services-tasks-10.2.6.jar
These archives should be passed in javac and dx
For AdMob there are several additional simple config steps as well
Gradle does a lot of mess with android projects, so own script looks like a singular solution for projects that are going to go into production
A while back I stumbled across this thread after getting frustrated with both Android Studio and Gradle. Inspired by the answer from alijandro and this template from authmane512, I wrote a series of scripts to compile an Android app (including with dependencies/packages) in Java or Kotlin without any external build system.
Link: https://github.com/jbendtsen/tiny-android-template
There is a little bit of DIY involved here, but given that it's the sort of stuff that something like Gradle would do for you, I would argue that it's useful to know. Besides, it's like wayyyy less slow, and you have a lot more control how your app gets assembled.
I'm trying to customize the behavior of my Gradle build to be Android-Wear friendly.
I am bundling manually my wear apk in my handled apk (because i didnt managed to do it automagically).
This means that if I want to build a new version of the handled apk, i have to manually build my wear apk, copy/past the generated wear-apk insinde my res/raw of the handled project then build the new handled apk.
I want all this to be automatized.
So, what I need to do is :
Launch app:assembleRelease from cmd line
Gradle first do a wear:assembleRelease
At the end, Gradle take the apk from wear/output/apk/wear-apk.apk and copy it in app/src/main/res/raw
Then Gradle can procede to do app:assembleRelease
I dont find how to launch a task (wear:assembleRelease) from another task.
Any help is welcome !
I found a solution that may not be optimal but it is working for what I need.
In my handled app, i first have to say that the assembleRelease depends on my wear:assembleRelease:
app/build.gradle
project.afterEvaluate {
preReleaseBuild.dependsOn(':wear:assembleRelease')
}
preReleaseBuildis one of the very first task of the build but this task is created dynamically, that's why you have to wrap it after the project is evaluated.
Then, in my wear build.gradle, I have to specify the copy at the end of the build:
wear/build.gradle
assembleRelease << {
println "Copying the Wear APK"
copy {
from 'build/outputs/apk'
into '../app/src/main/assets'
include '**/wear-release.apk'
}
}
With only theses modifications, i managed to have the workflow explained in the question.
This could be enhanced because it is only working for the release build but it's a good first step.
Feel free to comment this solution.
I have an Android project and JUnit tests in my code.
I wanted to know if there is an ant task to run some tests.
In fact, I have several classic tests which are run using JUnit to test several methods, and some tests that need an android emulator or at least need to be run on an android device.
As I didn't find any documentation, I wanted to know if it's possible to do that kind of thing.
Like
junit-android dir="."...
Thanks a lot for your help and time.
Just to be clear because I've search on the web and didn't find many things, so hope you can help.
I have an Android project that contains NO activities.
Actual build.xml file:
I compile java source code
It generates me a .jar file.
I need to run some tests defined in my project/tests/ folder, using
the previous generated library. Thoses tests need to be runned on an
emulator device using ANT build file, whithout being dependent of
Eclipse.
Project:
src (java source code)
gen
bin
res
tests (Android test project)
AndroidManifest.xml
build.xml
...
The test project generated is containing a build.xml that has been automatically generated using android update command. Sadly, there is no task "run-tests". And how do I specify that I would like to use my library for those tests?
Everything you need to create and run android test projects from the command line, provided by Google itself ;-)
http://developer.android.com/tools/testing/testing_otheride.html
The command line you need is something like:
adb shell am instrument -w <test_package_name>/<runner_class>
To call that from Ant, use the <run-tests/> task, described here.
Create a target in your build.xml like this
<target name="run-tests">
<test-junit includedTests="pathToPackageContainingTests}/*.class" />
</target>
Then you can simply do this
ant clean release run-tests