start ndk SanAngeles from shell#android - android

I have put the SanAngeles demo to run in my phone.
Here are steps I took:
$ android update project -p . --target android-14
$ ndk-build -B V=1 APP_OPTIM=debug NDK_DEBUG=1
$ ant debug install
It install fine. I saw the program was installed from the list of Apps in my smartphone. If I click on the icon DemoActivity, it runs.
But if I try to do it on host console:
$ adb shell
shell#android: $ am start -a android.intent.action.MAIN -n com.example.sanangeles/com.example.sanangeles.demoactivity
Error type 3
Error: Activity class {com.example.sanangeles/com.example.sanangeles.demoactivity}
does not exist.
Any suggestion?

Related

Screen freezes when I run Android program with Valgrind

I am new to Valgrind. I learnt how to use Valgrind on Android from this thread:
Can't run a Java Android program with Valgrind
The scripts on my Desktop are almost the same as the original ones, except that I built the Valgrind using aarch-64 toolchains manually and ran Valgrind on Samsung S6. I have tested the Valgrind on Android using compiled c binary, and it worked. When I tested the HelloJni application, the screen froze and I cannot see the output of the application. I used "adb shell top" to see the running process, and there was a process called:
{main} valgrind --error-limit=no --trace-children=yes --compress-strings=no --compress-pos=no --log-file=/sdcard/valgrind.log.%p --tool=callgrind
When I kill this process, there were some log files on /sdcard/. And the logcat worked OK. So, Valgrind did work on the background, but I could not see the application run on the foreground.
I am really stuck here. Anyone has any ideas?
Also, does anyone know how to run Valgrind on an apk file?
Thanks a lot.
My code:
build_valgrind.sh: (I built my Valgrind somewhere else and pushed it to /data/local/Inst already)
#!/usr/bin/env bash
#set -x
adb root
adb remount
# Ensure Valgrind on the phone is running
adb shell "/data/local/Inst/bin/valgrind --version"
# Add Valgrind executable to PATH (this might fail)
adb shell "export PATH=$PATH:/data/local/Inst/bin/"
export NDK_HOME=$HOME/Downloads/android-ndk-r10e
export SDK_HOME=$HOME/Downloads/android-sdk-linux
export PATH=$SDK_HOME/tools:$PATH
export PATH=$SDK_HOME/platform-tools:$PATH
RUN_HELLO_JNI_THROUGH_VALGRIND=true
cd valgrind-3.11.0
if [ $RUN_HELLO_JNI_THROUGH_VALGRIND = true ]; then
PACKAGE="com.example.hellojni"
# The location of the Hello JNI sample application
HELLO_JNI_PATH="$NDK_HOME/samples/hello-jni"
pushd "$HELLO_JNI_PATH"
# Update build target to the desired Android SDK version
ANDROID_PROJECT_TARGET="android-18"
android update project --target "$ANDROID_PROJECT_TARGET" --path . --name hello-jni --subprojects
# Enable Android NDK build with Ant
echo '<?xml version="1.0" encoding="utf-8"?>
<project name="HelloJni" basedir="." default="debug">
<target name="-pre-build">
<exec executable="${ndk.dir}/ndk-build" failonerror="true"/>
</target>
<target name="clean" depends="android_rules.clean">
<exec executable="${ndk.dir}/ndk-build" failonerror="true">
<arg value="clean"/>
</exec>
</target>
</project>
' > "custom_rules.xml"
# Set NDK HOME for Ant (only if not already set)
if ! grep -P -q "ndk.dir=.+" "local.properties" ; then
echo -e "\nndk.dir=$NDK_HOME" >> "local.properties"
fi
# Fix for Java 8 warning (warning: [options] source value 1.5 is obsolete and will be removed in a future release)
echo "java.compilerargs=-Xlint:-options" >> "ant.properties"
# Workaround INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES error
adb uninstall "$PACKAGE"
# Build Hello JNI project in debug mode and install it on the device
ant clean && ant debug && ant installd
popd
cd ..
# Start HelloJNI app
adb shell am start -a android.intent.action.MAIN -n $PACKAGE/.HelloJni
# Make the script executable
chmod a+x bootstrap_valgrind.sh
# Run application through Valgrind on the phone
/usr/bin/env bash bootstrap_valgrind.sh
adb shell ls -lR "/sdcard/*grind*"
adb shell ls -lR "/storage/sdcard0/*grind*"
adb shell ls -lR "/storage/sdcard1/*grind*"
fi
bootstrap_valgrind.sh:
#!/usr/bin/env bash
PACKAGE="com.example.hellojni"
adb push start_valgrind.sh /data/local/
adb shell su -c "chmod 777 /data/local/start_valgrind.sh"
adb root
adb shell setprop wrap.$PACKAGE "logwrapper /data/local/start_valgrind.sh"
echo "wrap.$PACKAGE: $(adb shell getprop wrap.$PACKAGE)"
adb shell am force-stop $PACKAGE
adb shell am start -a android.intent.action.MAIN -n $PACKAGE/.HelloJni
adb logcat -c
adb logcat
exit 0
start_valgrind.sh:
#!/system/bin/sh
PACKAGE="com.example.hellojni"
# Callgrind tool
VGPARAMS='--error-limit=no --trace-children=yes --compress-strings=no --compress-pos=no --log-file=/sdcard/valgrind.log.%p --tool=callgrind --callgrind-out-file=/sdcard/callgrind.out.%p'
# Memcheck tool
#VGPARAMS='-v --error-limit=no --trace-children=yes --log-file=/sdcard/valgrind.log.%p --tool=memcheck --leak-check=full --show-reachable=yes'
export TMPDIR=/data/data/$PACKAGE
exec /data/local/Inst/bin/valgrind $VGPARAMS $*

How to install an app in system/app while developing from android studio

Is there a way to make an app install directly in the system/app folder while developing on Android Studio (the device is rooted)?
Meaning, when I press on the 'Run app' button, I want the apk to be placed in system/app.
If this is not possible, what is the recommended most convenient way to work on building and testing a system app?
Deploy automatically system app from AS
You can create a script that will do the job, and run it automatically each time you hit run in AS.
1. Create the script
You can adapt this script that I've created from my needs. Place it in: project_directory/installSystem.sh
#!/bin/bash
# CHANGE THESE FOR YOUR APP
app_package="com.example"
dir_app_name="MySysApp"
MAIN_ACTIVITY="SysAppMainActivity"
ADB="adb" # how you execute adb
ADB_SH="$ADB shell" # this script assumes using `adb root`. for `adb su` see `Caveats`
path_sysapp="/system/priv-app" # assuming the app is priviledged
apk_host="./app/build/outputs/apk/app-debug.apk"
apk_name=$dir_app_name".apk"
apk_target_dir="$path_sysapp/$dir_app_name"
apk_target_sys="$apk_target_dir/$apk_name"
# Delete previous APK
rm -f $apk_host
# Compile the APK: you can adapt this for production build, flavors, etc.
./gradlew assembleDebug || exit -1 # exit on failure
# Install APK: using adb root
$ADB root 2> /dev/null
$ADB remount # mount system
$ADB push $apk_host $apk_target_sys
# Give permissions
$ADB_SH "chmod 755 $apk_target_dir"
$ADB_SH "chmod 644 $apk_target_sys"
#Unmount system
$ADB_SH "mount -o remount,ro /"
# Stop the app
$ADB shell "am force-stop $app_package"
# Re execute the app
$ADB shell "am start -n \"$app_package/$app_package.$MAIN_ACTIVITY\" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER"
2. Bind it with AS Run
Go to Run -> Edit Configurations
Do the following changes on General tab (of your module)
Installation Options->Deplay: Nothing
Launch Options->Launch: Nothing
Before launch: press +, then Run External Tool, to select your script.
In the new dialog:
set any name.
On 'Tool Settings'->Program: navigate to the project's dir, and select your script
Caveats :
First installation
The device needs to be restarted (adb reboot) only once, on the very first installation of your app. Afterwards, you can simply press Run and everything will happen automatically.
This is because the host compiler (dex2oat) is not invoked automatically. Somehow the OS is not yet informed for this new system app. Calling dex2oat manually should solve this, but I had no luck. If anyone solves it please share.
adb root issues
Sometimes (usually the initial execution after the restart) the call to adb root does not find the device. You can simply re-play from AStudio, or sleep for a second after a successful adb root.
using su instead of adb root
adb push won't be working despite mounting system and giving permissions. To make it work replace the ADB_SH variable and the install section of the script with the following:
..
ADB_SH="$ADB shell su -c"
..
# Install APK: using adb su
$ADB_SH "mount -o rw,remount /system"
$ADB_SH "chmod 777 /system/lib/"
$ADB_SH "mkdir -p /sdcard/tmp" 2> /dev/null
$ADB_SH "mkdir -p $apk_target_dir" 2> /dev/null
$ADB push $apk_host /sdcard/tmp/$apk_name 2> /dev/null
$ADB_SH "mv /sdcard/tmp/$apk_name $apk_target_sys"
$ADB_SH "rmdir /sdcard/tmp" 2> /dev/null
Windows script for those interested:
Store this file the same way: in the root of your project directory (installSysPrivApp.bat)
::WIN BATCH SCRIPT
:: CHANGE THESE
set app_package=com.example.package
set dir_app_name=app
set MAIN_ACTIVITY=MainActivity
set ADB="adb"
::ADB_SH="%ADB% shell" # this script assumes using `adb root`. for `adb su`
see `Caveats`
set path_sysapp=/system/priv-app
set apk_host=.\Application\build\outputs\apk\Application-debug.apk
set apk_name=%dir_app_name%.apk
set apk_target_dir=%path_sysapp%/%dir_app_name%
set apk_target_sys=%apk_target_dir%/%apk_name%
:: Delete previous APK
del %apk_host%
:: Compile the APK: you can adapt this for production build, flavors, etc.
call gradlew assembleDebug
set ADB_SH=%ADB% shell su -c
:: Install APK: using adb su
%ADB_SH% mount -o rw,remount /system
%ADB_SH% chmod 777 /system/lib/
%ADB_SH% mkdir -p /sdcard/tmp
%ADB_SH% mkdir -p %apk_target_dir%
%ADB% push %apk_host% /sdcard/tmp/%apk_name%
%ADB_SH% mv /sdcard/tmp/%apk_name% %apk_target_sys%
%ADB_SH% rmdir /sdcard/tmp
:: Give permissions
%ADB_SH% chmod 755 %apk_target_dir%
%ADB_SH% chmod 644 %apk_target_sys%
::Unmount system
%ADB_SH% mount -o remount,ro /
:: Stop the app
%ADB% shell am force-stop %app_package%
:: Re execute the app
%ADB% shell am start -n \"%app_package%/%app_package%.%MAIN_ACTIVITY%\" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER
To bypass reboot issue from the #paschalis answer reinstall application with a help of package manager before remounting system to read only:
# Reinstall app
$ADB_SH "pm install -r $apk_target_sys"
# Unmount system
$ADB_SH "mount -o remount,ro /"
Package manager will invoke dex2oat by itself.
(Android Q >> Windows)
::WIN BATCH SCRIPT
::setup emulator https://stackoverflow.com/a/64397712/13361987
:: CHANGE THESE
set app_package=com.project.package
set dir_app_name=NewApkName
set MAIN_ACTIVITY=Package.MainActivity
set ADB="adb"
set path_sysapp=/system/priv-app
set apk_host=.\app\build\outputs\apk\debug\app-debug.apk
set apk_name=%dir_app_name%.apk
set apk_target_dir=%path_sysapp%/%dir_app_name%
set apk_target_sys=%apk_target_dir%/%apk_name%
:: Delete previous APK
del %apk_host%
:: Compile the APK: you can adapt this for production build, flavors, etc.
call gradlew assembleDebug
set ADB_SH=%ADB% shell su 0
:: Install APK: using adb su
%ADB_SH% mount -o remount,rw /system
%ADB_SH% chmod 777 /system/lib/
%ADB_SH% mkdir -p /sdcard/tmp
%ADB_SH% mkdir -p %apk_target_dir%
%ADB% push %apk_host% /sdcard/tmp/%apk_name%
%ADB_SH% mv /sdcard/tmp/%apk_name% %apk_target_sys%
%ADB_SH% rm -r /sdcard/tmp
:: Give permissions
%ADB_SH% chmod 755 %apk_target_dir%
%ADB_SH% chmod 644 %apk_target_sys%
:: Unmount system
%ADB_SH% mount -o remount,ro /
:: Stop the app
%ADB% shell am force-stop %app_package%
:: Re execute the app
%ADB% shell am start -n \"%app_package%/%app_package%.%MAIN_ACTIVITY%\" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER
:: from >> https://stackoverflow.com/questions/28302833/how-to-install-an-app-in-system-app-while-developing-from-android-studio
For mac
By using the script of #Paschalis I got 3 problems first I couldn't mount the system from adb so I did it with "terminal emulator for android" from jack palevich only (needed once) https://play.google.com/store/apps/details?id=jackpal.androidterm
mount -o rw,remount /system
the second problem was the JRE that was not the same as Android studio.
so I added
export JAVA_HOME=/Applications/Android\ Studio.app/Contents/jre/jdk/Contents/Home/
to have the same version of java that android studio was using ("ctrl + ;" in android studio to get this path)
And the last problem because of adb root that can not run in production build so I flashed this zip with magisk
https://github.com/evdenis/adb_root
Android: adbd cannot run as root in production builds
but then my phone was not detected anymore so I removed adb root and this time all works well.
Also try to run the script manually line by line in a terminal to debug this script android studio does not give all the error.
I think adb push *.apk /system/app/*.apk should do just fine.
I don't know about Android Studio, but if you are on Linux you can get try to create an alias for
adb install
that points to that command, It should work!

Python script unable to run "android" command

I am trying to create "avd" from python script using command :
android create avd -n avd1 -t android-19 -s QVGA -b x86
Everytime i run this command through Terminal i get avd created but if i am running same command from python script i a getting error which says that "android" command was not found.
Python script:
#!/usr/bin/env python
import sys, os
def main():
cmd = "android create avd -n avd1 -t android-19 -s QVGA -b x86"
print cmd
os.system(cmd)
main()
What could be the possible error.
Environment : Ubuntu 13.04
Path variable set to: export PATH=$PATH:~/android-sdks/tools/:~/android-sdks/build-tools/:~/android-sdks/platform-tools/:~/android-sdks/
From Python's documentation:
Changes to sys.stdin, etc. are not reflected in the environment of the
executed command.
os.system has limitations. The subprocess module is preferable.
Try:
import subprocess
cmd = "android create avd -n avd1 -t android-19 -s QVGA -b x86"
subprocess.call(cmd.split())

How to run (not only install) an android application using .apk file?

Is there any command on cmd.exe that would allow me to start the main activity of a particular android application using the .apk file of that application. Please note that I know this command which only installs an android application:
adb install myapp.apk
This command will only install myapp onto the emulator and I have to manually run this application from the emulator (by performing single click on its icon).
What I want to do is use a command which not only installs the application but also starts its main activity (please note that I have only its .apk file so I don't know what the package name or any activity name is).
You can't install and run in one go - but you can certainly use adb to start your already installed application. Use adb shell am start to fire an intent - you will need to use the correct intent for your application though. A couple of examples:
adb shell am start -a android.intent.action.MAIN -n com.android.settings/.Settings
will launch Settings, and
adb shell am start -a android.intent.action.MAIN -n com.android.browser/.BrowserActivity
will launch the Browser.
If you want to point the Browser at a particular page, do this
adb shell am start -a android.intent.action.VIEW -n com.android.browser/.BrowserActivity http://www.google.co.uk
If you don't know the name of the activities in the APK, then do this
aapt d xmltree <path to apk> AndroidManifest.xml
the output content will includes a section like this:
E: activity (line=32)
A: android:theme(0x01010000)=#0x7f080000
A: android:label(0x01010001)=#0x7f070000
A: android:name(0x01010003)="com.anonymous.MainWindow"
A: android:launchMode(0x0101001d)=(type 0x10)0x3
A: android:screenOrientation(0x0101001e)=(type 0x10)0x1
A: android:configChanges(0x0101001f)=(type 0x11)0x80
E: intent-filter (line=33)
E: action (line=34)
A: android:name(0x01010003)="android.intent.action.MAIN"
XE: (line=34)
That tells you the name of the main activity (MainWindow), and you can now run
adb shell am start -a android.intent.action.MAIN -n com.anonymous/.MainWindow
if you're looking for the equivalent of "adb run myapp.apk"
you can use the script shown in this answer
(linux and mac only - maybe with cygwin on windows)
linux/mac users can also create a script to run an apk with something like the following:
create a file named "adb-run.sh" with these 3 lines:
pkg=$(aapt dump badging $1|awk -F" " '/package/ {print $2}'|awk -F"'" '/name=/ {print $2}')
act=$(aapt dump badging $1|awk -F" " '/launchable-activity/ {print $2}'|awk -F"'" '/name=/ {print $2}')
adb shell am start -n $pkg/$act
then "chmod +x adb-run.sh" to make it executable.
now you can simply:
adb-run.sh myapp.apk
The benefit here is that you don't need to know the package name or launchable activity name. Similarly, you can create "adb-uninstall.sh myapp.apk"
Note: This requires that you have aapt in your path. You can find it under the new build tools folder in the SDK
This is a solution in shell script:
apk="$apk_path"
1. Install apk
adb install "$apk"
sleep 1
2. Get package name
pkg_info=`aapt dump badging "$apk" | head -1 | awk -F " " '{print $2}'`
eval $pkg_info > /dev/null
3. Start app
pkg_name=$name
adb shell monkey -p "${pkg_name}" -c android.intent.category.LAUNCHER 1
When you start the app from the GUI, adb logcat might show you the corresponding action/category/component:
$ adb logcat
[...]
I/ActivityManager( 1607): START {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.android.browser/.BrowserActivity} from pid 1792
[...]
I put this in my makefile, right the next line after adb install ...
adb shell monkey -p `cat .identifier` -c android.intent.category.LAUNCHER 1
For this to work there must be a .identifier file with the app's bundle identifier in it, like com.company.ourfirstapp
No need to hunt activity name.
First to install your app:
adb install -r path\ProjectName.apk
The great thing about the -r is it works even if it wasn’t already installed.
To launch MainActivity, so you can launch it like:
adb shell am start -n com.other.ProjectName/.MainActivity
I created terminal aliases to install and run an apk using a single command.
// I use ZSH, here is what I added to my .zshrc file (config file)
// at ~/.zshrc
// If you use bash shell, append it to ~/.bashrc
# Have the adb accessible, by including it in the PATH
export PATH="/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:path/to/android_sdk/platform-tools/"
# Setup your Android SDK path in ANDROID_HOME variable
export ANDROID_HOME=~/sdks/android_sdk
# Setup aapt tool so it accessible using a single command
alias aapt="$ANDROID_HOME/build-tools/27.0.3/aapt"
# Install APK to device
# Use as: apkinstall app-debug.apk
alias apkinstall="adb devices | tail -n +2 | cut -sf 1 | xargs -I X adb -s X install -r $1"
# As an alternative to apkinstall, you can also do just ./gradlew installDebug
# Alias for building and installing the apk to connected device
# Run at the root of your project
# $ buildAndInstallApk
alias buildAndInstallApk='./gradlew assembleDebug && apkinstall ./app/build/outputs/apk/debug/app-debug.apk'
# Launch your debug apk on your connected device
# Execute at the root of your android project
# Usage: launchDebugApk
alias launchDebugApk="adb shell monkey -p `aapt dump badging ./app/build/outputs/apk/debug/app-debug.apk | grep -e 'package: name' | cut -d \' -f 2` 1"
# ------------- Single command to build+install+launch apk------------#
# Execute at the root of your android project
# Use as: buildInstallLaunchDebugApk
alias buildInstallLaunchDebugApk="buildAndInstallApk && launchDebugApk"
Note: Here I am building, installing and launching the debug apk which is usually in the path: ./app/build/outputs/apk/debug/app-debug.apk, when this command is executed from the root of the project
If you would like to install and run any other apk, simply replace the path for debug apk with path of your own apk
Here is the gist for the same.
I created this because I was having trouble working with Android Studio build reaching around 28 minutes, so I switched over to terminal builds which were around 3 minutes. You can read more about this here
Explanation:
The one alias that I think needs explanation is the launchDebugApk alias.
Here is how it is broken down:
The part aapt dump badging ./app/build/outputs/apk/debug/app-debug.apk | grep -e 'package: name basically uses the aapt tool to extract the package name from the apk.
Next, is the command: adb shell monkey -p com.package.name 1, which basically uses the monkey tool to open up the default launcher activity of the installed app on the connected device. The part of com.package.name is replaced by our previous command which takes care of getting the package name from the apk.

How do you push Android Instrumentation Tests to Emulator/Device?

I'm trying to run the Webkit Layout Tests on the Android emulator using the command line shell in Ubuntu 9.04.
adb -s emulator-5554 shell am instrument -w \
com.android.dumprendertree/com.android.dumprendertree.LayoutTestsAutoRunner
I get this error:
INSTRUMENTATION_STATUS: Error=Unable to find instrumentation info for: ComponentInfo{com.android.dumprendertree/com.android.dumprendertree.LayoutTestsAutoRunner}
I found that you need to use development/testrunner/runtest.py to push tests in android/frameworks/base/tests.
I've tried this to push the AndroidTests:
. ./build/envsetup.sh
emulator&
./development/testrunner/runtest.py android
But it gives me this error:
Error: ANDROID_PRODUCT_OUT not defined. Please run envsetup.sh
I did run envsetup.sh! Anyone know how to do this?
I've found an answer at Android - Instrumentation Testing
. build/envsetup.sh
(cd frameworks/base/tests/DumpRenderTree/ && mm) && \
adb install out/target/product/generic/data/app/DumpRenderTree.apk
Then you can run the instrumentation tests:
adb -s emulator-5554 shell am instrument -w \
com.android.dumprendertree/com.android.dumprendertree.LayoutTestsAutoRunner
once you launch adb shell in command line:
go with a command stating the package(com.ni.Keyboard) say of Keyboard application..
am instrument -w com.ni.Keyboard.test/android.test.InstrumentationTestRunner

Categories

Resources