I need to start app before running tests in order to initialize some folders in /data/data/appName/files/ and then I want to use adb command to push some files there.
If I use start_test_server_in_background, it will start tests also...
#I can't do this, bcs it will run my tests before I have data in there
start_test_server_in_background
shutdown_test_server
#I tried something like this, I am not sure how it should be written
http("/ready")
http("/kill")
#Pushing files to created folders afterwards
system("#{default_device.adb_command} push /someFolder/someFiles /data/data/appName/files")
I was able to start app like this:
pn = package_name(ENV['APP_PATH'])
cmd = "#{default_device.adb_command} shell monkey -p \"#{pn}\" -c android.intent.category.LAUNCHER 1"
result = `#{cmd}`
But in the end it was not the problem I got, so my question was misleading
Related
on my android phone I want to control osmand using the osmand api. To send the intents I want to use the am command available in adb shell or termux.
I am able to start osmand with am start net.osmand.plus/net.osmand.plus.activities.MapActivity
In my first test I just want to stop the navigation (command: STOP_NAVIGATION).
First I tried am start -a stop_navigation -n net.osmand.plus/net.osmand.plus.activities.MapActivity. The result was Starting: Intent { act=stop_navigation cmp=net.osmand.plus/.activities.MapActivity } Warning: Activity not started, its current task has been brought to the front, which makes sense.
Then I tested some broadcast commands, e.g.:
am broadcast -a stop_navigation -n net.osmand.plus/net.osmand.plus.activities.MapActivity
am broadcast osmand.api://stop_navigation
I also tested it with capital letters. But no command was successful.
Is there someone which has more experiences with android intents and / or osmand api and can help me how to create a working command?
Thanks in advance!
I already found the solution, it was simpler than expected. Maybe I can help someone with the solution:
The command am start osmand.api://pause_navigation is enough.
BTW:
termux-open osmand.api://pause_navigation does also work.
I would like to run a bunch of tests in my Android App.
The thing is: I want to define first a number of tests N, and make my App run that number of times, one after another.
It's a little tricky in Android, because of the Activities lifecycle, but the goal is to start a test (execute the app again) right after when the last one stoped.
Is that possible? I tried reading the Android Developers Testing section, but I'm having some doubts about if what I want is possible with that technique.
Plus, I want to make each test execute with different values for the variables (different inputs), but that's probably even more tricky, so... let's focus in the first problem :)
Any help?? Thanks
It sounds to me what you want is a mechanism to restart your Android application programatically (and gracefully). Many people may say it is impossible, but you can implement the mechanism.
The basic flow is:
(1) finish() your root activity.
(2) In onDestroy() of your root activity, call startActivity(createMainLauncherIntent()).
(3) And the implementation of createMainLauncherIntent() should look like the following.
private Intent createMainLauncherIntent()
{
Intent intent = new Intent();
// To launch this activity as if it started from the launcher.
intent.setClass(this, getClass());
intent.setAction(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
return intent;
}
(4) Of course, the onDestroy() should have a mechanism to avoid infinite loop of 'restart'.
A sample of base root Activity class:
https://github.com/TakahikoKawasaki/nv-android-base/blob/master/src/main/java/com/neovisionaries/android/app/BaseRootActivity.java
A sample Android application that implements 'restart' mechanism:
https://github.com/TakahikoKawasaki/nv-android-base-sample
You can run any number of test for your app, you just need to specify the valid test runner. By default, the SDK provides a AndroidTestRunner that allows you to run tests for your app inside an emulator.
After that, you can also use another test runner like Robolectric that allows to run tests directly from your IDE.
You can run as may tests as you want with both solutions, there is no need to kill and restart the app between each test. Even though, it would very inefficient and time consuming to do so.
im not sure, but what about a script witch kills your app and start it again with new inputs, which could be stored in preinitialized db?
here a link to how to kill your aplication: Android ADB stop application command like "force-stop" for non rooted device
You can launch app with params using shell command start and parameter -e:
$ adb shell am start -n com.some.package/com.some.package.MainActivity -e key param
Params will come to the onCreate method:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Bundle extras = this.getIntent().getExtras();
if(extras != null){
String key = extras.getString("key");
}
}
To kill app on android you need to have rooted device. Next command will kill app:
$ adb shell ps | grep com.some.package | awk '{print $2}' | xargs adb shell kill
But I'm sure that standard testing methods will works better. So I recommend you carefully read all Android documentation about testing.
I have a question about using ADB.
I know that this command:
adb shell dumpsys activity
can show me all the activities that are currently running on the device.
But I notice that sometimes, the intents appear like this:
Intent { ...some_intent/activity_name.... (has extras) }
I know that extras mean that the activity has been started with some sort of parameters passed to it (I may be wrong here, please correct me if I am).
So my question is, how can I get the extras of the intent/activity through ADB ?
The reason I need this is because I'm trying to launch an apk (that is installed on the phone) through ADB command, something like:
adb shell "su -c 'am start -n com.package.name/.ActivityName'"
That works and bring up the application. The application has a start screen (say we call it HomeActivity) and you have to click a button and make some selections (say SelectionActivity) and it will go to another screen (say ActionActivity). I want to be able to launch the apk and make it go straight to ActionActivity.
The application will crash if I try to launch the ActionActivity with am start command, I'm assuming this is because it requires parameters from the SelectionActivity screen.
This is why I'm trying to see what are the "extras" or parameters that the ActionActivity screen actually gets, so that I can do something like:
adb shell "su -c 'am start -n com.package.name/.ActionActivity -e param1 val1 -e param2 val2'"
Hope my question is clear.
Please correct me if I'm making a mistake somewhere.
Thanks in advance!
If I am understanding correctly, your target is to start the 'action' activity with correct intent but you don't know what kind of parameter information should be included, right?
The dumpsys command won't dump everything you want, so to simply achieve your target, you have 2 options (you should find one device which you can burn your own firmware into it):
Modify the dump method in AMS to print out more information
Modify the ActivityThread class source code to print out the detailed intent information
I'm building a monitor app, which runs in background and logs the system calls executed by currently running application using the strace command.
String cmd="strace -p "+processID+" -o /mnt/sdcard/traceFile_"+processID+".txt";
Runtime.getRuntime().exec(cmd);
Here processID is the PID of currently running process which is got from some other method implemented. It logs the system calls of the first app it monitors properly with all executed system call information. But when a new app is started(second one onwards), the processID is updated correctly, but the file traceFile_processID is written as an empty file.
I'm not able to figure out why its happening. Is it because the strace execution of first app monitored still there?? If so how I can execute a ^C to terminate that session and start a new one as in adb shell command prompt?? Plz help me.....
If you want to "^C" as you say, what you're really asking for is how to raise the signal called SIGINT to the given processID. You can do that simply by kill(processID, SIGINT); - this is equivalent to pressing Ctrl-C on the keyboard for the target process.
I'm learning Android programming, and I want to make an application which has to run as root. The logical thing would be to add a root permission in the Android Manifest.
I saw this link in the documentation, and especially noted the FACTORY_TEST permission:
public static final String FACTORY_TEST
Since: API Level 1
Run as a manufacturer test
application, running as the root user.
Only available when the device is
running in manufacturer test mode.
Constant Value:
"android.permission.FACTORY_TEST"
Is that the best way?
If it's not possible using the SDK, how can I make a "root" application work?
What you need to do is something like:
Process root = Runtime.getRuntime().exec("su");
That causes SuperUser to show, which lets you either Allow or Block it from root access. This approach might not work if the user is not rooted. Here is a way you can test it.
First lets us get the basics right. Android run Linux kernel underneath. Now if you have to run your process on it with super user privileges(run it as root) the only way is to execute your process is via command line because it is the only way you can directly interact with the kernel. Also you need to use su before running any command. Also as Chris has mentioned in his comment on the 1st answer
Process process = Runtime.getRuntime().exec("su");
will accomplish nearly nothing. It will just ask for super use privilege using dialog. What you can do is instead of just executing su you can execute your process with su as following
Process process = Runtime.getRuntime().exec(new String[] { "su", "-c", yourCommand});
The -c Option
Among the most commonly used of su's few options is -c, which tells su to execute the command that directly follows it on the same line. Such command is executed as the new user, and then the terminal window or console from which su was run immediately returns to the account of the former user after the command has completed execution or after any program that it has launched has been closed.(More details)
Alternate Option
Alternative to above method one another way that might work is to use command line to copy you app to /system/app/ directory. Then your application will run automatically with root privileges(same as System apps)
The SDK does not offer a way to run an app as root.