Difference between revisions of "Android SDK"

From YobiWiki
Jump to navigation Jump to search
m (Created page with "Back to Android ===Getting Android SDK=== Instructions below are for linux, if you're running Windows please check the provided resource links for variants of the instructio…")
 
m
 
(14 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
Back to [[Android]]
 
Back to [[Android]]
   
===Getting Android SDK===
+
==Getting Android SDK==
  +
===Online using Linux/Windows===
 
Instructions below are for linux, if you're running Windows please check the provided resource links for variants of the instructions.
 
Instructions below are for linux, if you're running Windows please check the provided resource links for variants of the instructions.
 
<br>Make sure you've Java Development Kit installed
 
<br>Make sure you've Java Development Kit installed
Line 18: Line 19:
 
* Then restart tools/android
 
* Then restart tools/android
   
====Offline installation under Windows====
+
===Offline installation under Windows===
 
If you are behind a proxy, you can configure SDK Manager (Tools/Options).
 
If you are behind a proxy, you can configure SDK Manager (Tools/Options).
 
<br>If you've no Internet connection at all, you need to download components on another computer.
 
<br>If you've no Internet connection at all, you need to download components on another computer.
Line 35: Line 36:
 
*** Extract content of usb_driver_r04-windows to C:\Program Files (x86)\Android\android-sdk\extras\google\usb_driver
 
*** Extract content of usb_driver_r04-windows to C:\Program Files (x86)\Android\android-sdk\extras\google\usb_driver
   
===Setting environment===
+
==Setting environment==
 
<br>We first define a number of things:
 
<br>We first define a number of things:
 
<source lang=bash>
 
<source lang=bash>
Line 71: Line 72:
 
Note that I needed here to use absolute path for DEV_HOME otherwise I get errors with dx.exe
 
Note that I needed here to use absolute path for DEV_HOME otherwise I get errors with dx.exe
   
===Preparing and using emulator===
+
==Preparing and using emulator==
 
Here is how to create a basic emulator instance:
 
Here is how to create a basic emulator instance:
 
<source lang=bash>
 
<source lang=bash>
Line 92: Line 93:
 
</source>
 
</source>
   
===Android application in command-line===
+
==Android application in command-line==
 
See http://geosoft.no/development/android.html
 
See http://geosoft.no/development/android.html
 
<br>Preparing the working directory (based on the environment variables defined above):
 
<br>Preparing the working directory (based on the environment variables defined above):
Line 260: Line 261:
 
</source>
 
</source>
   
===Simple java code in command-line===
+
==Simple java code in command-line==
 
See https://davanum.wordpress.com/2007/12/04/command-line-java-on-dalvikvm/
 
See https://davanum.wordpress.com/2007/12/04/command-line-java-on-dalvikvm/
  +
  +
Not sure in which case you need it or not but it might be that you need:
  +
* a rooted phone
  +
* be root in shell as default (ro.secure=0 in the boot.img)
  +
 
<br>Preparing the working directory (based on the environment variables defined above):
 
<br>Preparing the working directory (based on the environment variables defined above):
 
<source lang=bash>
 
<source lang=bash>
Line 269: Line 275:
 
mkdir -p $DEV_HOME/lib/
 
mkdir -p $DEV_HOME/lib/
 
mkdir -p $DEV_HOME/bin/
 
mkdir -p $DEV_HOME/bin/
  +
</source>
  +
Under Windows:
  +
<source lang=dos>
  +
rmdir /S /Q %DEV_HOME%
  +
mkdir %DEV_HOME%\src\%PACKAGE_BACKSLASH%\
  +
mkdir %DEV_HOME%\obj\
  +
mkdir %DEV_HOME%\lib\
  +
mkdir %DEV_HOME%\bin\
 
</source>
 
</source>
 
Provide source code of an app, here a simple HelloWorld:
 
Provide source code of an app, here a simple HelloWorld:
Line 282: Line 296:
 
EOF
 
EOF
 
</source>
 
</source>
  +
Under Windows:
  +
<br>No idea how to script it, just copy the java code to a file %DEV_HOME%\src\%PACKAGE_BACKSLASH%\HelloWorld.java
  +
<br><br>
 
Compile Java:
 
Compile Java:
 
<source lang=bash>
 
<source lang=bash>
 
$JAVA_HOME/bin/javac -verbose -d $DEV_HOME/obj \
 
$JAVA_HOME/bin/javac -verbose -d $DEV_HOME/obj \
 
-g $DEV_HOME/src/$PACKAGE_SLASH/*.java || exit 1
 
-g $DEV_HOME/src/$PACKAGE_SLASH/*.java || exit 1
  +
</source>
  +
Under Windows:
  +
<source lang=dos>
  +
%JAVA_HOME%\bin\javac -verbose -d %DEV_HOME%\obj ^
  +
-g %DEV_HOME%\src\%PACKAGE_BACKSLASH%\*.java
 
</source>
 
</source>
 
Create DEX:
 
Create DEX:
Line 292: Line 314:
 
--output=$DEV_HOME/bin/classes.dex \
 
--output=$DEV_HOME/bin/classes.dex \
 
$DEV_HOME/obj $DEV_HOME/lib || exit 1
 
$DEV_HOME/obj $DEV_HOME/lib || exit 1
  +
</source>
  +
Under Windows:
  +
<source lang=dos>
  +
%ANDROID_HOME%\platform-tools\dx --dex --verbose ^
  +
--output=%DEV_HOME%\bin\classes.dex ^
  +
%DEV_HOME%\obj %DEV_HOME%\lib
 
</source>
 
</source>
 
Create JAR:
 
Create JAR:
 
<source lang=bash>
 
<source lang=bash>
  +
pushd $DEV_HOME/bin/
 
$ANDROID_HOME/platform-tools/aapt add $DEV_HOME/CmdLine.jar \
 
$ANDROID_HOME/platform-tools/aapt add $DEV_HOME/CmdLine.jar \
$DEV_HOME/bin/classes.dex || exit 1
+
classes.dex || exit 1
  +
popd
  +
</source>
  +
Under Windows:
  +
<source lang=dos>
  +
pushd %DEV_HOME%\bin\
  +
%ANDROID_HOME%\platform-tools\aapt add %DEV_HOME%\CmdLine.jar ^
  +
classes.dex
  +
popd
 
</source>
 
</source>
 
To install the resulting application in the emulator (see above how to launch the emulator):
 
To install the resulting application in the emulator (see above how to launch the emulator):
Line 302: Line 339:
 
$ANDROID_HOME/platform-tools/adb -e push $DEV_HOME/CmdLine.jar /sdcard/
 
$ANDROID_HOME/platform-tools/adb -e push $DEV_HOME/CmdLine.jar /sdcard/
 
</source>
 
</source>
  +
Under Windows:
To execute it from the PC.
 
  +
<source lang=dos>
  +
%ANDROID_HOME%\platform-tools\adb -e push %DEV_HOME%\CmdLine.jar /sdcard/
  +
</source>
 
To execute it from the PC:
 
<source lang=bash>
 
<source lang=bash>
 
$ANDROID_HOME/platform-tools/adb -e shell \
 
$ANDROID_HOME/platform-tools/adb -e shell \
 
/system/bin/dalvikvm -Xbootclasspath:/system/framework/core.jar -classpath /sdcard/CmdLine.jar $PACKAGE.HelloWorld
 
/system/bin/dalvikvm -Xbootclasspath:/system/framework/core.jar -classpath /sdcard/CmdLine.jar $PACKAGE.HelloWorld
  +
</source>
  +
Under Windows:
  +
<source lang=dos>
  +
%ANDROID_HOME%\platform-tools\adb -e shell ^
  +
/system/bin/dalvikvm -Xbootclasspath:/system/framework/core.jar -classpath /sdcard/CmdLine.jar %PACKAGE%.HelloWorld
 
</source>
 
</source>
 
To do the same on a real device rather than on the emulator, make sure the phone is connected by USB and running in debug mode as explained above, then simple use -d (device) instead of -e (emulator), so previous instructions become:
 
To do the same on a real device rather than on the emulator, make sure the phone is connected by USB and running in debug mode as explained above, then simple use -d (device) instead of -e (emulator), so previous instructions become:
Line 312: Line 358:
 
$ANDROID_HOME/platform-tools/adb -d shell \
 
$ANDROID_HOME/platform-tools/adb -d shell \
 
/system/bin/dalvikvm -Xbootclasspath:/system/framework/core.jar -classpath /sdcard/CmdLine.jar $PACKAGE.HelloWorld
 
/system/bin/dalvikvm -Xbootclasspath:/system/framework/core.jar -classpath /sdcard/CmdLine.jar $PACKAGE.HelloWorld
  +
</source>
  +
Under Windows:
  +
<source lang=dos>
  +
%ANDROID_HOME%\platform-tools\adb -d push %DEV_HOME%\CmdLine.jar /sdcard/
  +
%ANDROID_HOME%\platform-tools\adb -d shell ^
  +
/system/bin/dalvikvm -Xbootclasspath:/system/framework/core.jar -classpath /sdcard/CmdLine.jar %PACKAGE%.HelloWorld
 
</source>
 
</source>
   
===BouncyCastle library===
+
==BouncyCastle library==
 
Depending on the creation of a real Android app or a simple java code and depending on the fact you want to use the internal crippled version or the full fledged version, different approaches are needed.
 
Depending on the creation of a real Android app or a simple java code and depending on the fact you want to use the internal crippled version or the full fledged version, different approaches are needed.
 
<br>Internal library API is explained [https://developer.android.com/reference/javax/crypto/package-summary.html here]
 
<br>Internal library API is explained [https://developer.android.com/reference/javax/crypto/package-summary.html here]
 
<br>Some RSA examples are given [http://www.java2s.com/Tutorial/Java/0490__Security/0740__RSA-algorithm.htm here] and a tuto (fr) [http://nyal.developpez.com/tutoriel/java/bouncycastle/ here]
 
<br>Some RSA examples are given [http://www.java2s.com/Tutorial/Java/0490__Security/0740__RSA-algorithm.htm here] and a tuto (fr) [http://nyal.developpez.com/tutoriel/java/bouncycastle/ here]
 
<br>To get a list of supported algorithms, see [http://www.java2s.com/Code/Java/Security/Listtheavailablealgorithmnamesforcipherskeyagreementmacsmessagedigestsandsignatures.htm here]. This illustrates e.g. the differences between the crippled internal version of the library and the complete one.
 
<br>To get a list of supported algorithms, see [http://www.java2s.com/Code/Java/Security/Listtheavailablealgorithmnamesforcipherskeyagreementmacsmessagedigestsandsignatures.htm here]. This illustrates e.g. the differences between the crippled internal version of the library and the complete one.
====Using internal BouncyCastle library from an Android application====
+
===Using internal BouncyCastle library from an Android application===
 
That's the normal way.
 
That's the normal way.
 
<br>Here is an example, mixing the HelloAndroid shown above with an example from http://www.java2s.com/Tutorial/Java/0490__Security/RSASignatureGeneration.htm
 
<br>Here is an example, mixing the HelloAndroid shown above with an example from http://www.java2s.com/Tutorial/Java/0490__Security/RSASignatureGeneration.htm
Line 390: Line 442:
 
</source>
 
</source>
   
====Using external BouncyCastle library from an Android application====
+
===Using external BouncyCastle library from an Android application===
 
Not tested. The problem is that it's impossible to get an external library with the exact same name as the internal one (see [https://code.google.com/p/android/issues/detail?id=13314 bugreport]), so different approaches are possible:
 
Not tested. The problem is that it's impossible to get an external library with the exact same name as the internal one (see [https://code.google.com/p/android/issues/detail?id=13314 bugreport]), so different approaches are possible:
 
* [https://github.com/rtyley/spongycastle#readme SpongyCastle], BouncyCastle rebranded to avoid the conflict.
 
* [https://github.com/rtyley/spongycastle#readme SpongyCastle], BouncyCastle rebranded to avoid the conflict.
 
* [http://www.unwesen.de/2011/06/12/encryption-on-android-bouncycastle/ Using JarJar] to rebrand it yourself
 
* [http://www.unwesen.de/2011/06/12/encryption-on-android-bouncycastle/ Using JarJar] to rebrand it yourself
   
====Using internal BouncyCastle library from a simple java code====
+
===Using internal BouncyCastle library from a simple java code===
 
<br>Here is an example, mixing the HelloWorld shown above with an example from http://www.java2s.com/Tutorial/Java/0490__Security/RSASignatureGeneration.htm
 
<br>Here is an example, mixing the HelloWorld shown above with an example from http://www.java2s.com/Tutorial/Java/0490__Security/RSASignatureGeneration.htm
 
<source lang=bash>
 
<source lang=bash>
Line 438: Line 490:
 
/system/bin/dalvikvm -Xbootclasspath:/system/framework/core.jar:/system/framework/bouncycastle.jar -classpath /sdcard/CmdLine.jar $PACKAGE.HelloWorld
 
/system/bin/dalvikvm -Xbootclasspath:/system/framework/core.jar:/system/framework/bouncycastle.jar -classpath /sdcard/CmdLine.jar $PACKAGE.HelloWorld
 
</source>
 
</source>
  +
Under Windows:
====Using external BouncyCastle library from a simple java code====
 
  +
<source lang=dos>
  +
%ANDROID_HOME%\platform-tools\adb -d shell ^
  +
/system/bin/dalvikvm -Xbootclasspath:/system/framework/core.jar:/system/framework/bouncycastle.jar -classpath /sdcard/CmdLine.jar %PACKAGE%.HelloWorld
  +
</source>
  +
  +
'''UPDATE''': on Android 4.0.3 (ICS) it doesn't work anymore, I get an error
  +
java.security.NoSuchProviderException: BC
  +
and in the logcat:
  +
I/dalvikvm( 1983): DexOpt: Some deps went away
  +
E/dalvikvm( 1983): /system/framework/bouncycastle.jar odex has stale dependencies
  +
I/dalvikvm( 1983): Zip is good, but no classes.dex inside, and no valid .odex file in the same directory
  +
D/dalvikvm( 1983): Unable to process classpath element '/system/framework/bouncycastle.jar'
  +
This is because there is an extra dependency for bouncycastle, here is how to get the deps in a very hacky way:
  +
$ adb shell strings /system/framework/bouncycastle.odex|grep odex
  +
/system/framework/core.odex
  +
/system/framework/core-junit.odex
  +
So the proper way to call our jar is now:
  +
<source lang=bash>
  +
$ANDROID_HOME/platform-tools/adb -d shell \
  +
/system/bin/dalvikvm -Xbootclasspath:/system/framework/core.jar:/system/framework/core-junit.jar:/system/framework/bouncycastle.jar -classpath /sdcard/CmdLine.jar $PACKAGE.HelloWorld
  +
</source>
  +
 
===Using external BouncyCastle library from a simple java code===
 
<br>You can use the same code as above but you need this time to provide the external library:
 
<br>You can use the same code as above but you need this time to provide the external library:
 
<source lang=bash>
 
<source lang=bash>
Line 449: Line 524:
 
/system/bin/dalvikvm -Xbootclasspath:/system/framework/core.jar -classpath /sdcard/CmdLine.jar $PACKAGE.HelloWorld
 
/system/bin/dalvikvm -Xbootclasspath:/system/framework/core.jar -classpath /sdcard/CmdLine.jar $PACKAGE.HelloWorld
 
</source>
 
</source>
Normally this works as such. In case of error no "BC" provider found, you can uncomment the line
+
Normally this works as such. In case of error no "BC" provider found, you can uncomment the line (which is what I had to do with Android 4.0.3)
 
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider())
 
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider())
  +
==Tips==
  +
adb shell getprop
  +
adb shell setprop ...
  +
Check current clock speed
  +
adb shell "cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq"
  +
Governors:
  +
adb shell "cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors"
  +
interactive conservative ondemand userspace powersave performance
  +
Disable CPU scaling
  +
adb shell "echo performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor"
  +
Change CPU frequency
  +
adb shell "echo userspace > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor"
  +
adb shell "cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies"
  +
300000 422400 652800 729600 883200 960000 1036800 1190400 1267200 1497600 1574400 1728000 1958400 2265600
  +
adb shell "echo 300000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed"
  +
Load activity through ActivityManager
  +
adb shell am start -a android.intent.action.MAIN -n com.android.browser/.BrowserActivity -d "http://$1" &
  +
==Misc==
  +
*Python
  +
** http://kivy.org/planet/2015/04/python-on%C2%A0android/
  +
** https://github.com/kivy/python-for-android

Latest revision as of 19:28, 22 June 2015

Back to Android

Getting Android SDK

Online using Linux/Windows

Instructions below are for linux, if you're running Windows please check the provided resource links for variants of the instructions.
Make sure you've Java Development Kit installed

apt-get install sun-java6-jdk

For Windows get it here e.g. jdk-6u29-windows-x64.exe Warning at the moment JDK7 created some errors in the compilation process, better to use JDK6.

As explained above, get Android SDK from here, following those instructions
Run tools/android (or for Windows run SDK Manager) -> in installed packages make sure to have:

  • "Android SDK Tools", latest revision
  • "Android SDK Platform-tools", latest revision
  • a platform SDK, e.g. "Android 2.3.3"/"SDK Platform"
  • (Windows only) Extras / Google USB Driver (SDK Manager must be run as Admin on Win7) then follow instructions here


As we will develop from the command-line, no need for the Eclipse plugin
If you want to update SDK

  • tools/android update sdk
  • Then restart tools/android

Offline installation under Windows

If you are behind a proxy, you can configure SDK Manager (Tools/Options).
If you've no Internet connection at all, you need to download components on another computer.
To know where are the packages let's spy SDK Manager & its logs (small icon at bottom right)
Here is what I got with the versions of the moment:

Setting environment


We first define a number of things:

JAVA_HOME=/usr/lib/jvm/java-6-sun-1.6.0.26/
ANDROID_HOME=/path/to/your/android-sdk-linux_x86/
PACKAGE=com.foo.mytest1
PACKAGE_SLASH=${PACKAGE//.//}
DEV_HOME=$(pwd)/mytest

We need also to define the target. To know what are the available targets:

$ANDROID_HOME/tools/android list target
Available Android targets:
----------
id: 1 or "android-10"
    Name: Android 2.3.3
    Type: Platform
    API level: 10
    Revision: 2
    Skins: QVGA, WVGA854, HVGA, WQVGA432, WVGA800 (default), WQVGA400
    ABIs : armeabi

So here we'll define:

TARGET=android-10

Under Windows it'll look like

set JAVA_HOME="C:\Program Files\Java\jdk1.6.0_29"
set ANDROID_HOME="C:\Program Files (x86)\Android\android-sdk\"
set PACKAGE=com.foo.mytest1
set PACKAGE_SLASH=com/foo/mytest1
set PACKAGE_BACKSLASH=com\foo\mytest1
set DEV_HOME=C:\path\to\mytest
set TARGET=android-10

Note that I needed here to use absolute path for DEV_HOME otherwise I get errors with dx.exe

Preparing and using emulator

Here is how to create a basic emulator instance:

$ANDROID_HOME/tools/android --verbose create avd --name MyNexusS --target $TARGET --sdcard 1024M

Later, to launch it just do:

$ANDROID_HOME/tools/emulator -wipe-data -avd MyNexusS &

If needed to delete it:

$ANDROID_HOME/tools/android --verbose delete avd --name MyNexusS

Under Windows it'll look like:

%ANDROID_HOME%\tools\android --verbose create avd --name MyNexusS --target %TARGET% --sdcard 1024M
%ANDROID_HOME%\tools\emulator -wipe-data -avd MyNexusS
%ANDROID_HOME%\tools\android --verbose delete avd --name MyNexusS

Android application in command-line

See http://geosoft.no/development/android.html
Preparing the working directory (based on the environment variables defined above):

rm -rf $DEV_HOME
mkdir -p $DEV_HOME/src/$PACKAGE_SLASH/
mkdir -p $DEV_HOME/res/drawable/
mkdir -p $DEV_HOME/res/layout/
mkdir -p $DEV_HOME/res/values/
mkdir -p $DEV_HOME/obj/
mkdir -p $DEV_HOME/lib/
mkdir -p $DEV_HOME/bin/
mkdir -p $DEV_HOME/docs/

Create a dummy keystore:

$JAVA_HOME/bin/keytool -genkeypair \
                -validity 10000 \
                -dname "CN=company name,
                        OU=organisational unit,
                        O=organisation,
                        L=location,
                        S=state,
                        C=country code" \
                -keystore $DEV_HOME/AndroidTest.keystore \
                -storepass password \
                -keypass password \
                -alias AndroidTestKey \
                -keyalg RSA \
                -v

Create a Manifest file, here with some examples of permissions:

cat << EOF > $DEV_HOME/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="$PACKAGE"
      android:versionCode="1"
      android:versionName="1.0">

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

    <uses-sdk android:minSdkVersion="2"/>

    <application android:icon="@drawable/mylogo"
                 android:label="@string/myApplicationName">
        <activity android:name="$PACKAGE.HelloAndroid"
                  android:label="@string/myApplicationName">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
EOF

Provide source code of an app, here a simple HelloWorld, using an icon file some_icon.png:

cat << EOF > $DEV_HOME/src/$PACKAGE_SLASH/HelloAndroid.java
package $PACKAGE;

import android.app.Activity;
import android.content.res.Resources;
import android.os.Bundle;
import android.widget.TextView;

public class HelloAndroid extends Activity {

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    TextView textView = new TextView(this);

    String text = getResources().getString(R.string.helloText);
    textView.setText(text);

    setContentView(textView);
  }
}
EOF

cat << EOF > $DEV_HOME/res/values/strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="myApplicationName">Android Test Program</string>
    <string name="helloText">Hello, world!</string>
</resources>
EOF
cp some_icon.png $DEV_HOME/res/drawable/mylogo.png

Create R.java:

$ANDROID_HOME/platform-tools/aapt package -v -f -m \
    -S $DEV_HOME/res -J $DEV_HOME/src -M $DEV_HOME/AndroidManifest.xml \
    -I $ANDROID_HOME/platforms/$TARGET/android.jar || exit 1

Compile Java:

$JAVA_HOME/bin/javac -verbose -d $DEV_HOME/obj \
    -classpath "$ANDROID_HOME/platforms/$TARGET/android.jar:$DEV_HOME/obj" \
    -sourcepath $DEV_HOME/src \
    $DEV_HOME/src/$PACKAGE_SLASH/*.java || exit 1

Create DEX:

$ANDROID_HOME/platform-tools/dx --dex --verbose \
    --output=$DEV_HOME/bin/classes.dex \
    $DEV_HOME/obj $DEV_HOME/lib || exit 1

Create APK:

$ANDROID_HOME/platform-tools/aapt package -v -f \
    -S $DEV_HOME/res -M $DEV_HOME/AndroidManifest.xml \
    -I $ANDROID_HOME/platforms/$TARGET/android.jar \
    -F $DEV_HOME/bin/AndroidTest.unsigned.apk \
    $DEV_HOME/bin || exit 1

Sign APK:

$JAVA_HOME/bin/jarsigner -verbose \
    -keystore $DEV_HOME/AndroidTest.keystore \
    -storepass password \
    -keypass password \
    -signedjar $DEV_HOME/bin/AndroidTest.signed.apk \
    $DEV_HOME/bin/AndroidTest.unsigned.apk \
    AndroidTestKey || exit 1

Zip-align APK:

$ANDROID_HOME/tools/zipalign -v -f 4 \
    $DEV_HOME/bin/AndroidTest.signed.apk \
    $DEV_HOME/bin/AndroidTest.apk || exit 1

Generate documentation, if you wish:

$JAVA_HOME/bin/javadoc -verbose -d $DEV_HOME/docs -sourcepath $DEV_HOME/src \
    -classpath "$ANDROID_HOME/platforms/$TARGET/android.jar:$DEV_HOME/obj" \
    -author -package -use -splitIndex -version \
    -windowtitle 'AndroidTest' -doctitle 'AndroidTest' \
    $DEV_HOME/src/$PACKAGE_SLASH/*.java

To install the resulting application in the emulator (see above how to launch the emulator):

$ANDROID_HOME/platform-tools/adb -e install $DEV_HOME/bin/AndroidTest.apk

It's even possible to launch & control application from the PC.
See http://learnandroid.blogspot.com/2008/01/run-android-application-from-command.html

$ANDROID_HOME/platform-tools/adb -e shell am start -a android.intent.action.MAIN \
    -n $PACKAGE/$PACKAGE.HelloAndroid

To remove it:

$ANDROID_HOME/platform-tools/adb -e uninstall $PACKAGE

To do the same on a real device rather than on the emulator, make sure the phone is connected by USB and running in debug mode as explained above, then simple use -d (device) instead of -e (emulator), so previous instructions become:

$ANDROID_HOME/platform-tools/adb -d install $DEV_HOME/bin/AndroidTest.apk
$ANDROID_HOME/platform-tools/adb -d shell am start -a android.intent.action.MAIN \
    -n $PACKAGE/$PACKAGE.HelloAndroid
$ANDROID_HOME/platform-tools/adb -d uninstall $PACKAGE

Simple java code in command-line

See https://davanum.wordpress.com/2007/12/04/command-line-java-on-dalvikvm/

Not sure in which case you need it or not but it might be that you need:

  • a rooted phone
  • be root in shell as default (ro.secure=0 in the boot.img)


Preparing the working directory (based on the environment variables defined above):

rm -rf $DEV_HOME
mkdir -p $DEV_HOME/src/$PACKAGE_SLASH/
mkdir -p $DEV_HOME/obj/
mkdir -p $DEV_HOME/lib/
mkdir -p $DEV_HOME/bin/

Under Windows:

rmdir /S /Q %DEV_HOME%
mkdir %DEV_HOME%\src\%PACKAGE_BACKSLASH%\
mkdir %DEV_HOME%\obj\
mkdir %DEV_HOME%\lib\
mkdir %DEV_HOME%\bin\

Provide source code of an app, here a simple HelloWorld:

cat << EOF > $DEV_HOME/src/$PACKAGE_SLASH/HelloWorld.java
package $PACKAGE;

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}
EOF

Under Windows:
No idea how to script it, just copy the java code to a file %DEV_HOME%\src\%PACKAGE_BACKSLASH%\HelloWorld.java

Compile Java:

$JAVA_HOME/bin/javac -verbose -d $DEV_HOME/obj \
    -g $DEV_HOME/src/$PACKAGE_SLASH/*.java || exit 1

Under Windows:

%JAVA_HOME%\bin\javac -verbose -d %DEV_HOME%\obj ^
    -g %DEV_HOME%\src\%PACKAGE_BACKSLASH%\*.java

Create DEX:

$ANDROID_HOME/platform-tools/dx --dex --verbose \
    --output=$DEV_HOME/bin/classes.dex \
    $DEV_HOME/obj $DEV_HOME/lib || exit 1

Under Windows:

%ANDROID_HOME%\platform-tools\dx --dex --verbose ^
    --output=%DEV_HOME%\bin\classes.dex ^
    %DEV_HOME%\obj %DEV_HOME%\lib

Create JAR:

pushd $DEV_HOME/bin/
$ANDROID_HOME/platform-tools/aapt add $DEV_HOME/CmdLine.jar \
    classes.dex || exit 1
popd

Under Windows:

pushd %DEV_HOME%\bin\
%ANDROID_HOME%\platform-tools\aapt add %DEV_HOME%\CmdLine.jar ^
    classes.dex
popd

To install the resulting application in the emulator (see above how to launch the emulator):

$ANDROID_HOME/platform-tools/adb -e push $DEV_HOME/CmdLine.jar /sdcard/

Under Windows:

%ANDROID_HOME%\platform-tools\adb -e push %DEV_HOME%\CmdLine.jar /sdcard/

To execute it from the PC:

$ANDROID_HOME/platform-tools/adb -e shell \
    /system/bin/dalvikvm -Xbootclasspath:/system/framework/core.jar -classpath /sdcard/CmdLine.jar $PACKAGE.HelloWorld

Under Windows:

%ANDROID_HOME%\platform-tools\adb -e shell ^
    /system/bin/dalvikvm -Xbootclasspath:/system/framework/core.jar -classpath /sdcard/CmdLine.jar %PACKAGE%.HelloWorld

To do the same on a real device rather than on the emulator, make sure the phone is connected by USB and running in debug mode as explained above, then simple use -d (device) instead of -e (emulator), so previous instructions become:

$ANDROID_HOME/platform-tools/adb -d push $DEV_HOME/CmdLine.jar /sdcard/
$ANDROID_HOME/platform-tools/adb -d shell \
    /system/bin/dalvikvm -Xbootclasspath:/system/framework/core.jar -classpath /sdcard/CmdLine.jar $PACKAGE.HelloWorld

Under Windows:

%ANDROID_HOME%\platform-tools\adb -d push %DEV_HOME%\CmdLine.jar /sdcard/
%ANDROID_HOME%\platform-tools\adb -d shell ^
    /system/bin/dalvikvm -Xbootclasspath:/system/framework/core.jar -classpath /sdcard/CmdLine.jar %PACKAGE%.HelloWorld

BouncyCastle library

Depending on the creation of a real Android app or a simple java code and depending on the fact you want to use the internal crippled version or the full fledged version, different approaches are needed.
Internal library API is explained here
Some RSA examples are given here and a tuto (fr) here
To get a list of supported algorithms, see here. This illustrates e.g. the differences between the crippled internal version of the library and the complete one.

Using internal BouncyCastle library from an Android application

That's the normal way.
Here is an example, mixing the HelloAndroid shown above with an example from http://www.java2s.com/Tutorial/Java/0490__Security/RSASignatureGeneration.htm

cat << EOF > $DEV_HOME/src/$PACKAGE_SLASH/HelloAndroid.java
package $PACKAGE;

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.SecureRandom;
import java.security.Security;
import java.security.Signature;

import android.app.Activity;
import android.content.res.Resources;
import android.os.Bundle;
import android.widget.TextView;

public class HelloAndroid extends Activity {

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    TextView textView = new TextView(this);

//    Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

    try {
      KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA", "BC");
      keyGen.initialize(512, new SecureRandom());

      KeyPair keyPair = keyGen.generateKeyPair();
      Signature signature = Signature.getInstance("SHA1withRSA", "BC");

      signature.initSign(keyPair.getPrivate(), new SecureRandom());

      byte[] message = "abc".getBytes();
      signature.update(message);

      byte[] sigBytes = signature.sign();
      signature.initVerify(keyPair.getPublic());
      signature.update(message);
      if (signature.verify(sigBytes))
        textView.setText("true");
      else
        textView.setText("false");
      setContentView(textView);
    } catch (java.security.NoSuchAlgorithmException e) {
      textView.setText("NoSuchAlgorithmException");
      setContentView(textView);
      return;
    } catch (java.security.NoSuchProviderException e) {
      textView.setText("NoSuchProviderException");
      setContentView(textView);
      return;
    } catch (java.security.InvalidKeyException e) {
      textView.setText("InvalidKeyException");
      setContentView(textView);
      return;
    } catch (java.security.SignatureException e) {
      textView.setText("SignatureException");
      setContentView(textView);
      return;
    }

  }
}
EOF

Using external BouncyCastle library from an Android application

Not tested. The problem is that it's impossible to get an external library with the exact same name as the internal one (see bugreport), so different approaches are possible:

Using internal BouncyCastle library from a simple java code


Here is an example, mixing the HelloWorld shown above with an example from http://www.java2s.com/Tutorial/Java/0490__Security/RSASignatureGeneration.htm

cat << EOF > $DEV_HOME/src/$PACKAGE_SLASH/HelloWorld.java
package $PACKAGE;

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.SecureRandom;
import java.security.Security;
import java.security.Signature;

public class HelloWorld {

  public static void main(String[] args) throws Exception {
    //Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

    KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA", "BC");

    keyGen.initialize(512, new SecureRandom());

    KeyPair keyPair = keyGen.generateKeyPair();
    Signature signature = Signature.getInstance("SHA1withRSA", "BC");

    signature.initSign(keyPair.getPrivate(), new SecureRandom());

    byte[] message = "abc".getBytes();
    signature.update(message);

    byte[] sigBytes = signature.sign();
    signature.initVerify(keyPair.getPublic());
    signature.update(message);
    System.out.println(signature.verify(sigBytes));
  }

}
EOF

There is a little trick when you will run the example on the phone or emulator: you've to provide explicitly the path to internal BouncyCastle:

$ANDROID_HOME/platform-tools/adb -d shell \
    /system/bin/dalvikvm -Xbootclasspath:/system/framework/core.jar:/system/framework/bouncycastle.jar -classpath /sdcard/CmdLine.jar $PACKAGE.HelloWorld

Under Windows:

%ANDROID_HOME%\platform-tools\adb -d shell ^
    /system/bin/dalvikvm -Xbootclasspath:/system/framework/core.jar:/system/framework/bouncycastle.jar -classpath /sdcard/CmdLine.jar %PACKAGE%.HelloWorld

UPDATE: on Android 4.0.3 (ICS) it doesn't work anymore, I get an error

java.security.NoSuchProviderException: BC

and in the logcat:

I/dalvikvm( 1983): DexOpt: Some deps went away
E/dalvikvm( 1983): /system/framework/bouncycastle.jar odex has stale dependencies
I/dalvikvm( 1983): Zip is good, but no classes.dex inside, and no valid .odex file in the same directory
D/dalvikvm( 1983): Unable to process classpath element '/system/framework/bouncycastle.jar'

This is because there is an extra dependency for bouncycastle, here is how to get the deps in a very hacky way:

$ adb shell strings /system/framework/bouncycastle.odex|grep odex
/system/framework/core.odex
/system/framework/core-junit.odex

So the proper way to call our jar is now:

$ANDROID_HOME/platform-tools/adb -d shell \
    /system/bin/dalvikvm -Xbootclasspath:/system/framework/core.jar:/system/framework/core-junit.jar:/system/framework/bouncycastle.jar -classpath /sdcard/CmdLine.jar $PACKAGE.HelloWorld

Using external BouncyCastle library from a simple java code


You can use the same code as above but you need this time to provide the external library:

# From http://www.bouncycastle.org/latest_releases.html
cp -a bcprov-jdk16-146.jar $DEV_HOME/lib

To run the example, don't provide any path to the internal lib of course:

$ANDROID_HOME/platform-tools/adb -d shell \
    /system/bin/dalvikvm -Xbootclasspath:/system/framework/core.jar -classpath /sdcard/CmdLine.jar $PACKAGE.HelloWorld

Normally this works as such. In case of error no "BC" provider found, you can uncomment the line (which is what I had to do with Android 4.0.3)

Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider())

Tips

adb shell getprop
adb shell setprop ...

Check current clock speed

adb shell "cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq"

Governors:

adb shell "cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors"
interactive conservative ondemand userspace powersave performance

Disable CPU scaling

adb shell "echo performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor"

Change CPU frequency

adb shell "echo userspace > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor"
adb shell "cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies"
300000 422400 652800 729600 883200 960000 1036800 1190400 1267200 1497600 1574400 1728000 1958400 2265600
adb shell "echo 300000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed"

Load activity through ActivityManager

adb shell am start -a android.intent.action.MAIN -n com.android.browser/.BrowserActivity -d "http://$1" &

Misc