In my bash script I can build my Android Studio project like this:
#!/bin/bash
./gradlew assembleRelease
That creates .apk file in project's build folder but I don't know the path to that folder inside my script.Is there any way to get it?
You could add a line 'finding' it-
path=`find ./ -name "*.apk"`
echo "$path"
If you want the absolute path-
path=`find ./ \`pwd\` . -name "*.apk"`
echo "$path"
Since there's counting views for the question I post the final version of the solution suggested by #Chem-man17
# ---------------- Copy .apk file to output folder -----------------------
mkdir -p "$OUTPUT_DIR"
APK_FILE=`find ${PWD}/app/build/apk -type f -name "*.apk" -printf '%T# %p\n' \
| sort -k 1nr \
| head -n1 \
| sed 's/^[^ ]* //'`
APK_NAME=`echo $APK_FILE | xargs -I{} basename {}`
mv $APK_FILE $OUTPUT_DIR
echo "--- Created file: $OUTPUT_DIR/$APK_NAME"
Basically it sorts .apks in build folder by date and grabs the most recent
Related
Android Studio is too slow for my computer so I took it upon myself to learn how to build android apps manually. I finished with this script:
#!/usr/bin/env bash
##################################################################
# PREPARE ENVIRONMENT
##################################################################
path=$(pwd)
rm -rf bin
rm -rf gen
mkdir bin
mkdir gen
##################################################################
# SET VARS
##################################################################
# Set your application name
APP_NAME="mygame"
# Define minimal Android revision
ANDROID_REV="27.0.3"
ANDROID_PLATFORM_REV="android-27"
# Define Java compiler command
JAVAC="${JAVA_BIN}/javac -classpath ${ANDROID_SDK}/platforms/${ANDROID_PLATFORM_REV}/android.jar"
JAVAC_BUILD="${JAVAC} -sourcepath src -sourcepath gen -d bin"
##################################################################
# PROCESS
##################################################################
# Generate R class and pack resources and assets into resources.ap_ file
${ANDROID_SDK}/build-tools/${ANDROID_REV}/aapt package -v -f -I ${ANDROID_SDK}/platforms/${ANDROID_PLATFORM_REV}/android.jar -M AndroidManifest.xml -A "assets" -S "res" -m -J "gen" -F bin/resources.ap_
# Compile sources. All *.class files will be put into the bin folder
${JAVAC_BUILD} src/com/mycompany/mygame/*.java
# Generate dex files with compiled Java classes
${ANDROID_SDK}/build-tools/${ANDROID_REV}/dx --dex --output=${path}/bin/classes.dex ${path}/bin
# Recources file need to be copied. This is needed for signing.
mv "${path}/bin/resources.ap_" "${path}/bin/${APP_NAME}.ap_"
# Add generated classes.dex file into application package
${ANDROID_SDK}/build-tools/${ANDROID_REV}/aapt add ${path}/bin/${APP_NAME}.ap_ ${path}/bin/classes.dex
${ANDROID_SDK}/build-tools/${ANDROID_REV}/zipalign -f -v 4 ${path}/bin/${APP_NAME}.ap_ ${path}/bin/${APP_NAME}_unsigned.ap_
# Create signed Android application from *.ap_ file.
${ANDROID_SDK}/build-tools/${ANDROID_REV}/apksigner sign --ks ${path}/keystore/etamagotchi-release-key.keystore --ks-key-alias "mykeystore-alias" ${path}/bin/${APP_NAME}_unsigned.ap_
#
cp ${path}/bin/${APP_NAME}_unsigned.ap_ ${path}/bin/${APP_NAME}.apk
# Delete temp file
rm bin/*.ap_
rm bin/*.dex
It builds successfully. If I try to run adb install mygame.apk it says:
[INSTALL_FAILED_INVALID_APK: Package couldn't be installed in /data/app/com.mycompany.mygame-1: Package /data/app/com.mycompany.mygame-1/base.apk code is missing]
If I manually try to install it says "The package appears to be corrupted". What's wrong with my build script?
I added -source 1.7 -target 1.7 -bootclasspath "${JAVA_HOME}/jre/lib/rt.jar" to my $JAVAC build rule
I am curling the latest Android Studio dmg file, mounting the image and copying the .app directory into the Applications directory. When I attempt to open the directory I receive this warning, and when I query the application state, I also receive the code below. Any idea how I can generically install Android Studio from the cli?
Warning:
"Android Studio" is damaged and can't be opened. You should move it to the Trash. Google Chrome.app downloaded this file on
...
| => spctl -a /Applications/Android\ Studio.app/
/Applications/Android Studio.app/: a sealed resource is missing or invalid
...
| => codesign --display --verbose=4 /Applications/Android\ Studio.app/
Executable=/Applications/Android Studio.app/Contents/MacOS/studio
Identifier=com.google.android.studio
Format=app bundle with Mach-O universal (i386 x86_64)
CodeDirectory v=20200 size=537 flags=0x0(none) hashes=11+3 location=embedded
OSPlatform=36
OSSDKVersion=657664
OSVersionMin=657408
Hash type=sha256 size=32
CandidateCDHash sha1=4456b3e77035b4318af16276667c88f7b7d4f9ac
CandidateCDHash sha256=6d95335c6815111d93abd1e87b9fd4648d991bdd
Hash choices=sha1,sha256
Page size=4096
CDHash=6d95335c6815111d93abd1e87b9fd4648d991bdd
Signature size=8948
Authority=Developer ID Application: Google, Inc. (EQHXZ8M8AV)
Authority=Developer ID Certification Authority
Authority=Apple Root CA
Timestamp=Dec 1, 2016, 4:57:25 PM
Info.plist entries=22
TeamIdentifier=EQHXZ8M8AV
Sealed Resources version=2 rules=12 files=11250
Internal requirements count=1 size=188
Android Install Script
#!/usr/bin/env bash
echo "Installing Android Studio"
ANDROID_STUDIO_DMG=$(curl -0 https://developer.android.com/studio/index.html | grep -o --regexp='https://dl.google.com/dl/android/studio/install/[a-zA-Z0-9./?=_-]*/android-studio-ide-[a-zA-Z0-9./?=_-]*-mac.dmg')
./dmginstall.sh $ANDROID_STUDIO_DMG
DMG Install Script - (Modified:https://gist.github.com/rahulgautam/6695872)
#!/usr/bin/env bash
# Downloads and install a .dmg from a URL
#
# Usage
# $ dmginstall [url]
#
# For example, for installing android-studio-ide
# $ dmginstall https://dl.google.com/dl/android/studio/install/2.2.3.0/android-studio-ide-145.3537739-mac.dmg
#
# TODO
# - currently only handles .dmg with .app folders, not .pkg files
# - handle .zip files as well
if [[ $# -lt 1 ]]; then
echo "Usage: dmginstall [url]"
exit 1
fi
url=$*
# Generate a random file name
tmp_file=/tmp/`openssl rand -base64 10 | tr -dc '[:alnum:]'`.dmg
# Download file
echo "Downloading $url..."
curl -# -L -o $tmp_file $url
echo "Please copy and paste the Volumes directory you would like to use"
echo "-----------------------------------------------------------------"
hdiutil mount $tmp_file
IFS= read -r -p "Enter volume: " volume
echo "$volume"
# Locate .app folder and move to /Applications
app=`find "$volume" -name *.app -maxdepth 1 -type d -print0`
echo "Copying `echo $app | awk -F/ '{print $NF}'` into /Applications..."
cp -rv "$app" '/Applications'
# Unmount volume, delete temporal file
echo "Cleaning up..."
hdiutil unmount "$volume"
rm "$tmp_file"
echo "Done!"
I am trying to load two shared libraries in my Android application through the loadLibrary call:
System.loadLibrary("mywrapper");
System.loadLibrary("crypto");
I keep running catching the `UnsatisfiedLinkError. Here is a more detailed version of the error.
Caused by: java.lang.UnsatisfiedLinkError: Cannot load library: link_image[1969]:
130 could not load needed library 'libcrypto.so.1.0.0' for
'libmywrapper.so' (load_library[1111]: Library 'libcrypto.so.1.0.0' not found)
Any ideas?
After spending some time I found out that Android doesn't support versioned libraries. Has any one faced the same issue?
I had the same problem on building libwebsockets for Android, which needs to link with OpenSSL. I use libssl.so as example. You should do the same for related .so files.
Before:
huiying#huiying-PORTEGE-R835:~$ objdump -p libssl.so | grep so
libssl.so: file format elf32-little
NEEDED libcrypto.so.1.0.0
NEEDED libdl.so
NEEDED libc.so
SONAME libssl.so.1.0.0
After
huiying#huiying-PORTEGE-R835:~$ rpl -R -e .so.1.0.0 "_1_0_0.so" libssl.so
Replacing ".so.1.0.0" with "_1_0_0.so" (case sensitive) (partial words matched)
.
A Total of 2 matches replaced in 1 file searched.
huiying#huiying-PORTEGE-R835:~$ objdump -p libssl.so | grep so
libssl.so: file format elf32-little
NEEDED libcrypto_1_0_0.so
NEEDED libdl.so
NEEDED libc.so
SONAME libssl_1_0_0.so
And don't forget to change file name "libssl.so" to "libssl_1_0_0.so".
The hack works. I have running Android app to prove it. See my rant at http://computervisionandjava.blogspot.com/2015/05/trouble-with-versioned-shared-libraries.html.
It seems android has an issue with loading versioned libraries.The issue at hand was because of library so-name in my case libcrypto.so.1.0.0. Even if you rename the library and try to load it as a prebuilt shared library in an android make file it fails.( It has to be because the library name is somehow embedded in the file. And any library that links with it expects to be linked with a library of with the same name )
I hope there are other ways out there when it comes to handling libraries with version names in android.
For now I am evading the problem all together by using static libraries of openssl and linking them with my own shared library.
Year 2014 and still no support for versioned shared libs. So I made a script to patch SONAME. Just point the script to input dir where all versioned libs placed. Then check output dir "unver".
#!/bin/bash
DIR="$1"
if [ "$DIR" == "" ]; then
echo "Usage: fix-soname.sh <target dir>"
exit
fi
if [ ! -d $DIR ]; then
echo "Not found: $DIR"
exit
fi
OUT="$DIR/unver"
echo "Input=$DIR"
echo "Output=$OUT"
CWD=$(pwd)
cd $DIR
# prep dirs
mkdir -p $OUT
rm -f -R $OUT/*
# rename libs and copy to out dir
find "$DIR" -type f -name '*.so*' | while read FILE; do
NAME=$(basename "$FILE")
SONAME=$NAME
while read SYMLINK; do
X=$(basename "$SYMLINK")
#echo "$X (${#X}) -> $NAME (${#NAME})"
if [ "${#X}" -lt "${#SONAME}" ]; then
SONAME=$X
fi
done<<EOT
`find -L $DIR -samefile $FILE`
EOT
#echo $SONAME
cp -f $SONAME $OUT/
done
# patch libs in out dir
find "$OUT" -type f -name '*.so*' | while read FILE; do
# get file name without path
NAME=$(basename "$FILE")
# extract SONAME from shared lib
SONAME=`readelf -d $FILE | grep '(SONAME)' | grep -P '(?<=\[)(lib.*?)(?=\])' -o`
#echo "$NAME [$SONAME]"
# patch SONAME if required
if [ "$NAME" != "$SONAME" ]; then
L1=${#NAME}
L2=${#SONAME}
LDIFF=$((L2-L1))
#echo "$NAME [$SONAME] ($LDIFF)"
if [ "$LDIFF" -gt "0" ]; then
SONEW=$NAME
for (( c=1; c<=$LDIFF; c++ )); do
SONEW+="\x00"
done
echo "$NAME [$SONAME] -> $SONEW ($LDIFF)"
rpl -R -e "$SONAME" "$SONEW" $OUT
fi
fi
done
cd $CWD
i'm looking to write (or find :D) a script to convert an exisisting Android Project Source to a copy with another package name, that i provide.
Source have package like it.pinco.pallino.source and Copy will be like it.pinco.pallino.test1 etc etc...where test1 is a parameter.
I'm looking to use ANT or this script https://github.com/lijunjieone/RenameAndroidPackage, but there's no README and i don't know python..
Any suggestion?
Thanks
This is what I have written to change the package name without having to duplicate any code (for maintainability reasons, I use the same code for the free and pro version of my app).
Here's the script that converts Free version to Pro. It should be pretty easy to adapt it to your needs (provided you work under Linux, or use Cygwin or a linux virtual machine)
# 1- rename src folder
mv src/com/lulo/scrabble/dico src/com/lulo/scrabble/dicopro
# 2- replace references to package in Java, XML and CFG (proguard) files
find . \( -name "*xml" -o -name "*.java" -o -name "*.cfg" \) -print0 | xargs -0 sed -ri 's/scrabble.dico/scrabble.dicopro/g'
# 3- change the application name
find . -name "*.xml" -print0 | xargs -0 sed -ri 's/\(Free\)/Pro/g'
# 4- change the icon
cp ../IMAGES/LOGODICO_V2_2012_96px.png res/drawable-xhdpi/icon.png
cp ../IMAGES/LOGODICO_V2_2012_72px.png res/drawable-hdpi/icon.png
cp ../IMAGES/LOGODICO_V2_2012_48px.png res/drawable-mdpi/icon.png
cp ../IMAGES/LOGODICO_V2_2012_36px.png res/drawable-ldpi/icon.png
After this I just need to Refresh, Build and Export using Eclipse.
I'm experimenting with android terminal emulator(Terminal IDE) and trying to compile an Android project. I use the following script to compile.
#Build script
#cd into the home dir - this way it works when run from inside vim or any other folder
cd ~/projects/simple_search/
#Clean up
rm -rf build
rm -rf dist
#create the needed directories
mkdir -m 770 -p dist
mkdir -m 770 -p build/classes
#Rmove the R.java file as will be created by aapt
rm src/com/simple/search/R.java
#Now use aapt
echo Create the R.java file
aapt p -f -v -M AndroidManifest.xml -F ./build/resources.res -I ~/system/classes/android.jar -S res/ -J src/com/simple/search
#cd into the src dir
cd src
#Now compile - note the use of a seperate lib (in non-dex format!)
echo Compile the java code
javac -verbose -cp ../libs/demolib.jar -d ../build/classes \
com/simple/search/AboutDialog.java \
com/simple/search/CustomWindow.java \
com/simple/search/DatabaseHelper.java \
com/simple/search/SearchResults.java \
com/simple/search/SimpleSearch.java \
com/simple/search/SuggestionProvider.java \
com/simple/search/Tag.java \
com/simple/search/TestAction.java \
com/simple/search/TestDetails.java
#Back out
cd ..
#Now into build dir
cd build/classes/
#Now convert to dex format (need --no-strict) (Notice demolib.jar at the end - non-dex format)
echo Now convert to dex format
dx --dex --verbose --no-strict --output=../simple_search.dex org ../../libs/demolib.jar
#Back out
cd ../..
#And finally - create the .apk
apkbuilder ./dist/simple_search.apk -v -u -z ./build/resources.res -f ./build/simple_search.dex
#And now sign it
cd dist
signer simple_search.apk simple_search_signed.apk
cd ..
The script executes fine till cd build/classes/. But at dx --dex --verbose --no-strict --output=../simple_search.dex org ../../libs/demolib.jar I'm encountering the following error.
Now convert to dex format
UNEXPECTED TOP-LEVEL EXCEPTION:
java.lang.RuntimeException: org: file not found
at com.android.dx.util.FileUtils.readFile(FileUtils.java:55)
at com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:139)
at com.android.dx.cf.direct.ClassPathOpener.process(ClassPathOpener.java:113)
at com.android.dx.command.dexer.Main.processOne(Main.java:247)
at com.android.dx.command.dexer.Main.processAllFiles(Main.java:183)
at com.android.dx.command.dexer.Main.run(Main.java:139)
at com.android.dx.command.dexer.Main.main(Main.java:120)
at com.android.dx.command.Main.main(Main.java:89)
at com.spartacusrex.spartacuside.external.dx.main(dx.java:14)
at dalvik.system.NativeStart.main(Native Method)
processing archive ../../libs/demolib.jar...
ignored resource META-INF/MANIFEST.MF
processing org/library/libfunc.class...
1 error; aborting
What is wrong with the script? Can you point me in the right direction? Any smallest help is appreciated.
Remove 'org', as it doesn't seem to be a file for your build.
The line should read.
dx --dex --verbose --no-strict --output=../simple_search.dex ../../libs/demolib.jar