diff --git a/README.md b/README.md index f0ed79c..72a8cd2 100644 --- a/README.md +++ b/README.md @@ -1,44 +1,442 @@ -AndroidShell (Mac Os Commands) -============ +# AndroidShell (Mac Os Commands) -

MAPS

+#### Table of Contents -__Debug KeyStore__ +- __SHA-1__ + - __Debug Keystore__ + - __Release Keystore__ +- __ADB__ + - [__Select a device when multiple devices are connected__](#select-a-device-when-multiple-devices-are-connected) + - __Server actions__ + - [__Show launcher activity cold start time__](#show-launcher-activity-cold-start-time) + - __Database__ + - __Watching StrictMode__ + - __View connected devices__ + - __List of running services__ + - __Install an application__ + - __Uninstall an application__ + - __Start an Activity__ + - __Open a deep linking intent__ + - __Take an screenshot__ + - __Power button__ + - __Unlock screen__ + - __Print all installed packages__ + - __Get the path of an installed application__ + - __Simulate application being killed__ + - __Screen recording using Android 4.4__ + - __Check battery stats__ + - __Auto Backup Data (only in Android M)__ + - __Simulate fingerprint inputs (only in Android M)__ + - __Filter by tagname in Logcat__ + - __Filter by priority in Logcat__ + - __Filter using grep in Logcat__ + - __See the executed SQL statements in plain text in Logcat__ + - __Testing - Execute Monkey to test user interaction__ + - __Find out processor version on Android Device (check if it's an ARM, for example)__ + - [__Test Alarms__](#test-alarms) + - [__Query a Content Provider__](#query-a-content-provider) + - __Find out Application Binary Interface (ABI) in different devices__ + - __Retrieve application's private data and databases for non debug application without root access__ + - __Indentify Frame Rate Issues (Dumpsys)__ + - __Use ADB over Wi-Fi without extra application or software__ + - __Test new Marshmallow permissions__ + - __Testing your app with App Standby__ + - __Testing your app with Doze__ + - __Enabling Night Mode on Android Nougat__ + - [__Copy files from/to a device/emulator__](#copy-files-emulator) + - [__Trigger a notification without GCM__](#trigger-a-notification-without-gcm) +- __AAPT__ + - __Check Permissions in order to avoid Play Store app filtering__ + +
+ +### SHA-1 + +In order to get SHA1 to use it in many services, like Google+ Sign In, Maps, In app purchases, we should generate keys for every keystore (certificate): + + +#### Debug KeyStore +```sh +$ keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android +``` +or + +```sh +$ keytool -list -v -keystore {path_to_keystore}/debug.keystore -alias androiddebugkey -storepass android -keypass android +``` + + +#### Release KeyStore +```sh +$ keytool -list -v -keystore {path_to_keystore}/my-release.keystore -alias {alias_name} -storepass {store_pass} -keypass {keypass} +``` + +
+ +
+### ADB + +#### Select a device when multiple devices are connected + +You can use `adb devices -l` to check information related to them, in order to select the one you want. Then: +``` +adb -s +``` +where `` is the number listed when you use `adb devices` and `` are the instructions you want to execute over the device. + + +#### Server actions + +The following command kills the adb server: +```sh +adb kill-server +``` + +This starts the adb server: +```sh +adb start-server +``` + +
+ +#### Show launcher activity cold start time + +[__Source__](https://www.youtube.com/watch?v=oJAS7T-qurk) + +``` +$ adb logcat | grep "ActivityManager" +``` + +The output would be something similar to: + +``` +ActivityManager: Displayed com.example.launchtime/: +666ms +``` + +If we also use want to show the content ready time, we should use the API method `reportFullyDrawn`: + +``` +ActivityCompatAdditions.reportFullyDrawn(this); +``` +Then the time output will be the actual time that takes to Activity to be ready: +``` +ActivityManager: Displayed com.example.launchtime/.LaunchTimeActivity: +666ms +ActivityManager: Fully drawn com.example.launchtime/.LaunchTimeActivity: +1s440ms +``` + +Amount of time that takes to draw the first frame + the content. + +We can also use the `Activity` start command from ADB, with the `W` flag: + +``` +adb shell am start -W com.package.name/.LauncherScreenActivity +``` + +We will see 3 times related to starting times. + +
+ +
+#### Database + +[__This__](https://gist.github.com/ignasi) is a Database getter script, developed by [__Ignasi__](https://github.com/ignasi) +```sh +#!/bin/bash + +# android 4.3+ changes app's internal directory permissions and you can not just pull your +# databases to your computer, so this is a workaround to extract your databases. +# I only use it for debug, use it under YOUR responsability. IT REQUIRES ROOT + +package=$1 +db_name=$2 +path="/data/data/$package/" + +rm $db_name +adb shell "su -c 'cd $path; chmod -R 777 databases; exit'; exit" +adb pull $path/databases/$db_name +open $db_name +``` + + +#### Watching StrictMode + +If you’re using `penaltyLog()`, the default, just run +```sh +$ adb logcat +``` +and watch the terminal output. Any violations will be logged to your console, slightly rate-limited for duplicate elimination. + +If you want to get fancier, turn on `penaltyDropbox()` and they’ll be written to the DropBoxManager, where you can extract them later with +```sh +$ adb shell dumpsys dropbox data_app_strictmode --print +``` + + +#### View connected device + +```sh +$ adb devices +``` + +If multiple devices are attached, use `adb -s DEVICE_ID` to target a specific device + + +#### List of running services + +```sh +$ adb shell dumpsys activity services +``` + + +#### Install an application + +```sh +$ adb install -r file.apk // (or com.package.name) +# optional -r argument reinstalls and keeps any data if the application is already installed on the device. +# optional -s argument installs the app on the SD card instead of the internal storage. +``` + + +#### Uninstall an application + +```sh +$ adb uninstall com.package.name +``` + +To uninstall the application using uninstall dialog: +```sh +$ adb shell am start -a android.intent.action.DELETE -d package:com.package.name +``` + +To keep the data in the cache directory, add `-k` + +```sh +$ adb uninstall -k com.package.name +``` + + +#### Start an Activity + +```sh +$ adb shell am start -n com.package.name/.ActivityName +$ adb shell am start -n com.package.name/com.package.name.ActivityName +``` + + +#### Open a deep linking intent + +```sh +$ adb shell am start -n android.intent.action.VIEW -d "scheme://app/deep/linking" +``` +or +```sh +$ adb shell am start -n android.intent.action.VIEW -d "https://name.app/user-settings/324" com.packaging.app ``` -keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android + + + +#### Take an screenshot + +```sh +$ adb shell screencap -p | perl -pe 's/\x0D\x0A/\x0A/g' > screen_name.png +``` + +Explanation of this command, [__here__](http://blog.shvetsov.com/2013/02/grab-android-screenshot-to-computer-via.html) + + +#### Power button + +This command sends the power button event to turn the device ON/OFF. +```sh +$ adb shell input keyevent 26 +$ adb shell inout text "KEYCODE_POWER" +``` + + +#### Unlock screen + +This command sends the event that unlocks the lockscreen on the device. It can be combined with the power button command above to turn on and unlock the device + +```sh +$ adb shell input keyevent 82 +$ adb shell inout text "KEYCODE_MENU" + +$ adb shell input keyevent 26 82 +$ adb shell inout text "KEYCODE_POWER" "KEYCODE_MENU" +``` + + +#### Print all installed packages + +```sh +$ adb shell pm list packages -f ``` -

ADB

+
+#### Get the path of an installed application -

Simulate Application Being Killed

+```sh +$ adb shell pm path app.package.application-name ``` -// 1 - Exit your app using home button -// 2 - After that -adb shell ps // Find the process id -adb shell ps | grep your.app.package // Then find the line with app name package -adb shell kill -9 21997 // Kill the app by PID -// 3 - Now return to the app using the task switcher + +
+#### Simulate application being killed + +```sh +# exit your app using home button +# After that. +$ adb shell ps // Find the process id +$ adb shell ps | grep your.app.package // Then find the line with app name package +$ adb shell kill -9 21997 // Kill the app by PID +# Now return to the app using the task switcher. ``` -

Screen Recording using Android 4.4

+
+#### Screen recording using Android 4.4 + +```sh +$ adb shell screenrecord --verbose /sdcard/nexus5.mp4 // Basic recording from shell +# Press Ctrl-C to stop. +$ screenrecord --verbose --time-limit 30 /sdcard/nexus5.mp4 // Recording for 30 seconds +$ screenrecord --verbose --bit-rate 8000000 --time-limit 30 /sdcard/nexus5.mp4 // Recording for 30 seconds with 8Mbps bitrate +$ screenrecord --verbose --rotate /sdcard/nexus5.mp4 // Record in portrait view / horizontal ``` -adb shell screenrecord --verbose /sdcard/nexus5.mp4 // Basic recording from shell -// Press Ctrl-C to stop -screenrecord --verbose --time-limit 30 /sdcard/nexus5.mp4 // Recording for 30 seconds -screenrecord --verbose --bit-rate 8000000 --time-limit 30 /sdcard/nexus5.mp4 // Recording for 30 seconds with 8Mbps bitrate -screenrecord --verbose --rotate /sdcard/nexus5.mp4 // Record in portrait view / horizontal + + +#### Check battery stats + +```sh +$ adb shell dumpsys batterystats +# Global and per-UID statistics. +# Options: --help. ``` -

Retrieve application's private data and databases for non debug application without root access

+
+#### Auto Backup Data (only in Android M) + +```sh +$ adb shell bmgr + +$ adb shell bmgr run +# Do some work in the app. +$ adb shell bmgr fullbackup com.domain.android.app_name +# Uninstall and reinstall the app. +$ adb shell bmgr restore com.domain.android.app_name +``` + + +#### Simulate fingerprint inputs (only in Android M) + +```sh +$ adb -e emu finger touch 1 ``` -// Get a backup of your application data -adb backup --apk -// Change the .ab in .tar -dd if=backup.ab bs=24 skip=1 | openssl zlib -d > backup.tar -// Untar backup.tar + + +#### Filter by tagname in Logcat + +```sh +$ adb logcat -s TAG_NAME +$ adb logcat -s TAG_NAME_1 TAG_NAME_2 +``` + + +#### Filter by priority in Logcat + +```sh +$ adb logcat "*:" +# Where can be V (Verbose), D (Debug), I (Info), W (Warning), E (Error), F (Fatal), S (Silent). +``` + +It can be combined with tagname command, to filter by tagname and priority +```sh +$ adb logcat -s TEST: W +``` + + +#### Filter using grep in Logcat + +```sh +$ adb logcat | grep "term" +$ adb logcat | grep "term1\|term2" +```` + + +#### See the executed SQL statements in plain text in Logcat + +```sh +$ adb shell setprop log.tag.SQLiteLog V +$ adb shell setprop log.tag.SQLiteStatements V +$ adb shell stop +$ adb shell start +``` + +That's it. Whenever any of the installed apps now accesses the database you should see the executed statement in the log output. + + +#### Testing - Execute Monkey to test user interaction + +The Monkey is a program that runs on your emulator or device and generates pseudo-random streams of user events such as clicks, touches, or gestures, as well as a number of system-level events. You can use the Monkey to stress-test applications that you are developing, in a random yet repeatable manner. + +```sh +$ adb shell monkey [options] +# Basic, make 500 random actions. +$ adb shell monkey -p your.package.name -v 500 +``` + +Complete information at http://developer.android.com/tools/help/monkey.html + + +#### Find out processor version on Android Device (check if it's an ARM, for example) + +```sh +$ adb shell cat /proc/cpuinfo +``` + +#### Test Alarms + +[__Source__](http://vitovalov.com/2016/07/18/adb-date-changer.html) + +To check the alarms that are set on the connected device and to know more about them: + +```shell +$ adb shell dumpsys alarm +``` + +To see the alarms from you app you can grep with your package keywords: +```shell +$ adb shell dumpsys alarm | grep -A 3 google +``` + +So now you can see if you have correctly implemented your alarms functionality using AlarmManager API. + +[__More info here__](http://vitovalov.com/2016/07/18/adb-date-changer.html) + +#### Query a Content Provider + +```shell +$ adb shell content query --uri content://your.package.name --projection name +``` + + +#### Find out Application Binary Interface (ABI) in different devices + +__ABI__ (Application Binary Interface) is gonna tell us if an Android device support 64-bit. So using the next command the developer know if the device is __32-bit__ or __64-bit__ based. +```sh +$ adb shell getprop ro.product.cpu.abi\ +``` + + +#### Retrieve application's private data and databases for non debug application without root access + +```sh +# Get a backup of your application data. +$ adb backup --apk com.package.name +# Change the .ab in .tar. +$ dd if=backup.ab bs=24 skip=1 | openssl zlib -d > backup.tar +# Untar backup.tar. tar xfv backup.tar -// Go in you app private dir -cd apps/ +# Go in you app private dir. +$ cd apps/com.package.name ``` > You'll need : > - adb activated @@ -46,71 +444,261 @@ cd apps/ > - works on Nexus 5 at least, might not work with other devices. > __allowBackup=false will break thos method__ -

Use ADB over Wi-Fi without extra application or software

+
+#### Indentify Frame Rate Issues (Dumpsys) + +```sh +$ cd platform-tools/ +# Before executing next command, go to Settings --> Developer Options --> Enable Profile GPU rendering option. +# And make sure to kill your application first or at least to kill the window that you want to profile, and then you run the command: +$ adb shell dumpsys gfxinfo +``` +Purpose of Dumpsys is identifying frame rate issues and fix them. + +What matter is the three columns shown. Copy paste results in a spreadsheet. And you will get a result like this one: + +![Image](./images/dumpsys_sample.png) + +This is the data you can grab. You can create a stack graph, so every bar contains the sum of the three columns on the left in the data we output. Is the time it takes to update the display list on every frame. + +* The middle column is called process display list. It's the time we take to draw the actual display list +* The last column is the time we take to swap the buffers, so to give the buffer back to surface flinger. Scrolling or doing any kind of actions should be below 16 millisecond limit. So this app is running at 60FPS, we're vsync'd, everything is going great. You can see that most of the time, you should spend most of the time in process display list, so drawing, executing the display list should be where you spend the bulk of the time. +* The blue part is your code. When you write your Java code, your `onDraw()` method, and this is where you can do most of the optimizations + +There is a distinction between the GPU composition with frame buffers and overlays. So you can use a tool called __dumpsys surface flinger__ to see the state of overlays and frame buffers in the system. +```sh +$ adb shell dumpsys SurfaceFlinger +``` + +You're going to get a list with all the windows currently visible on the screen. + +More info about this tool, [__here__](https://www.youtube.com/watch?v=Q8m9sHdyXnE#t=2469) + + +#### Use ADB over Wi-Fi without extra application or software + __Prerequisites__ Android device and computer should be connected in same network. * Connect Android device with USB cable to computer * Use following command in terminal to make sure adb is running in USB mode. -``` -$adb usb -// Restarting in USB mode -// Connect to the device over USB. +```sh +$ adb usb +# Restarting in USB mode. +# Connect to the device over USB. ``` * Execute following command in terminal to make sure adb identify/list gets connected with the device. -``` -$adb devices +```sh +$ adb devices ``` -* Change adb mode from USB to tcpip using following command. -``` -$adb tcpip 5555 -// Restarting in TCP mode port: 5555 +* Change adb mode from USB to tcpip using following command. +```sh +$ adb tcpip 5555 +# Restarting in TCP mode port: 5555. ``` * Now, adb is running over TCP/IP mode, Let’s find IP address of Android device. Go to Settings in Android device -> About -> Status -> IP address. note down the IP address of connected Android Device. * Use following command to connect ADB with IP address -``` -$adb connect #.#.#.# -// Connected to #.#.#.#:5555 +```sh +$ adb connect #.#.#.# +# Connected to #.#.#.#:5555. ``` * Now adb is working over Wi-fi, You can remove USB cable from Android device. * To confirm adb is working over Wi-fi and your device is still connect. you can use following command -``` -$adb devices -#.#.#.#:5555 device +```sh +$ adb devices +*.*.*.*:5555 device ``` You’re now ready to go!, Enjoy ADB over Wi-fi. Use following command to change ADB mode to USB +```sh +$ adb usb ``` -$adb usb + + +#### Test new Marshmallow permissions + +In order to test permissions targeting API 23+, we could use following commands to programatically grant and revoke permissions on the device: +```sh +$adb pm grant +``` +or +```sh +$adb pm revoke +``` + +
+ +
+#### Testing your app with App Standby + +[__Source__](http://developer.android.com/intl/ru/training/monitoring-device-state/doze-standby.html?utm_campaign=android_series_appstandby_012116&utm_source=medium&utm_medium=blog#testing_your_app_with_app_standby) + +To test the App Standby mode with your app: + +- Configure a hardware device or virtual device with an Android 6.0 (API level 23) or higher system image. +- Connect the device to your development machine and install your app. +- Run your app and leave it active. +- Force the app into App Standby mode by running the following commands: +```sh +$ adb shell dumpsys battery unplug +$ adb shell am set-inactive true ``` -

See the executed SQL statements in plain text in logcat

+- Simulate waking your app using the following commands: +```sh +$ adb shell am set-inactive false +$ adb shell am get-inactive ``` -adb shell setprop log.tag.SQLiteLog V -adb shell setprop log.tag.SQLiteStatements V -adb shell stop -adb shell start + +- Observe the behavior of your app after waking it. Make sure the app recovers gracefully from standby mode. In particular, you should check if your app's Notifications and background jobs continue to function as expected. + +
+ +
+#### Testing your app with Doze + +[__Source__](http://developer.android.com/intl/ru/training/monitoring-device-state/doze-standby.html?utm_campaign=android_series_appstandby_012116&utm_source=medium&utm_medium=blog#testing_your_app_with_app_standby) + +You can test Doze mode by following these steps: + +- Configure a hardware device or virtual device with an Android 6.0 (API level 23) or higher system image. +- Connect the device to your development machine and install your app. +- Run your app and leave it active. +- Shut off the device screen. (The app remains active.) +- Force the system to cycle through Doze modes by running the following commands: +```java +$ adb shell dumpsys battery unplug +$ adb shell dumpsys deviceidle step ``` -That's it. Whenever any of the installed apps now accesses the database you should see the executed statement in the log output. +You may need to run the second command more than once. Repeat it until the device state changes to idle. -

Testing

+- Observe the behavior of your app after you reactivate the device. Make sure the app recovers gracefully when the device exits Doze. -

Execute Monkey to test user interaction

+
-The Monkey is a program that runs on your emulator or device and generates pseudo-random streams of user events such as clicks, touches, or gestures, as well as a number of system-level events. You can use the Monkey to stress-test applications that you are developing, in a random yet repeatable manner. +
+#### Enabling Night Mode on Android Nougat +[__Source__](http://michaelevans.org/blog/2016/08/23/enabling-night-mode-on-android-nougat/) ``` -adb shell monkey [options] -// Basic, make 500 random actions -adb shell monkey -p your.package.name -v 500 +$ adb -d shell am start --ez show_night_mode true com.android.systemui/.tuner.TunerActivity ``` -Complete information at http://developer.android.com/tools/help/monkey.html +
+ +
+##### Copy files from/to a device/emulator +[__Source__](http://crushingcode.co/do-you-like-to-adb/) +To push a file/dir to device: +```sh +$ adb push +``` +where `` is file in your local system i.e my_image.png and `` is file location in device/emulator i.e `/sdcard/Downloads/my_image.png` +Sample: +```sh +$ adb push ~/Downloads/my_image.png /sdcard/Downloads/my_image.png +``` +To pull a file/dir from device + +```sh +$ adb pull [] +``` +where `` is file in your local system i.e my_image.png and `` is file location in device/emulator i.e `/sdcard/Downloads/my_image.png`. + +Sample: +```sh +adb pull /sdcard/Downloads/my_image.png my_image.png +``` + +#### Trigger a notification without GCM + +[Source](https://plus.google.com/108612553581259107752/posts/ERVnjUAjsbZ) + +**IMPORTANT**: Remember to remove **temporally** the following attribute from the declaration of the Broadcast Receiver you want to test, in the Manifest: +``` +android:permission="com.google.android.c2dm.permission.SEND" +``` + +It's based on enabling broadcast receivers. +``` +am broadcast -a -n / +``` + +Some examples could be: +``` +adb shell am broadcast -a com.whereismywifeserver.intent.TEST --es sms_body "test from adb" +adb shell am broadcast -a com.google.android.c2dm.intent.REGISTRATION -n de.example/.GCMBroadcastReceiver +--es "registration_id" "1234" +``` +where `--es` define extra as string + +
+ +
+### AAPT + + +#### Check Permissions in order to avoid Play Store app filtering + +[__Source__](https://goo.gl/jpxeLO) + +Certain permissions also imply certain features. Google Play uses these to filter out apps just as it would with explicit requirements. Developers should __NOT__ rely on this implicit behavior, they should always declare explicitly every feature their app needs. + +__aapt__ allows us, among other things, to see the contents of an app’s manifest. This is not as easy as simply unpacking the apk and reading the manifest as you’ll find it’s in a binary format. Here is the result of running the SDK-provided aapt tool in its apk: +```sh +$ aapt dump badging com.your-app.apk +``` +Output +``` +package: name='com.germanwings.android' versionCode='3' versionName='1.0.2' sdkVersion:'10' targetSdkVersion:'17' +uses-permission:'android.permission.WRITE_EXTERNAL_STORAGE' +uses-permission:'android.permission.INTERNET' +uses-permission:'android.permission.ACCESS_FINE_LOCATION' +uses-permission:'android.permission.ACCESS_COARSE_LOCATION' +uses-permission:'com.germanwings.android.permission.C2D_MESSAGE' +uses-permission:'android.permission.ACCESS_LOCATION_EXTRA_COMMANDS' +uses-permission:'android.permission.INTERNET' +uses-permission:'android.permission.GET_ACCOUNTS' +uses-permission:'android.permission.WAKE_LOCK' +uses-permission:'android.permission.READ_PHONE_STATE' +uses-permission:'com.google.android.c2dm.permission.RECEIVE' +uses-permission:'android.permission.ACCESS_LOCATION_EXTRA_COMMANDS' +uses-permission:'android.permission.ACCESS_MOCK_LOCATION' +uses-permission:'android.permission.ACCESS_NETWORK_STATE' +uses-permission:'android.permission.ACCESS_GPS' +uses-permission:'android.permission.ACCESS_LOCATION' +uses-permission:'android.permission.READ_EXTERNAL_STORAGE' +application-label:'Germanwings' +application-icon-120:'res/drawable-ldpi/ic_launcher.png' +application-icon-160:'res/drawable-mdpi/ic_launcher.png' +application-icon-240:'res/drawable-hdpi/ic_launcher.png' +application-icon-320:'res/drawable-xhdpi/ic_launcher.png' +application: label='Germanwings' icon='res/drawable-mdpi/ic_launcher.png' +launchable-activity: name='com.germanwings.android.presentation.activity.DashboardActivity' label='Germanwings' icon='' +uses-feature:'android.hardware.location' +uses-implied-feature:'android.hardware.location','requested a location access permission' +uses-feature:'android.hardware.location.gps' +uses-implied-feature:'android.hardware.location.gps','requested android.permission.ACCESS_FINE_LOCATION permission' +uses-feature:'android.hardware.location.network' +uses-implied-feature:'android.hardware.location.network','requested android.permission.ACCESS_COURSE_LOCATION permission' +uses-feature:'android.hardware.touchscreen' +uses-implied-feature:'android.hardware.touchscreen','assumed you require a touch screen unless explicitly made optional' +uses-feature:'android.hardware.screen.portrait' +uses-implied-feature:'android.hardware.screen.portrait','one or more activities have specified a portrait orientation' +main +other-activities +other-receivers +other-services +supports-screens: 'small' 'normal' 'large' 'xlarge' +supports-any-density: 'true' +locales: '--_--' +densities: '120' '160' '240' '320' +``` diff --git a/images/dumpsys_sample.png b/images/dumpsys_sample.png new file mode 100644 index 0000000..f5a5247 Binary files /dev/null and b/images/dumpsys_sample.png differ