How to take screenshots programmatically in Android? - android

I want to make an app that takes screenshots of the device every 10 seconds, even when app is running in the background.
I don't know how to do this.
Is there any way to do this with a device that's not rooted?

Here is how to capture the screen shot on Android.
Also an example of Handler and Timer
And a very similar post that asks for the same.

In order to capture ScreenShot of your activity you need a View from your activity, and which isn't present in your service so you have to make a TimerTask which will call your activity at every moment to get the current view of the activity and you can capture the ScreenShot from that.
otherwise If you want to take a ScreenShot of your current device screen or any other app then you have to root permission, and read framebuffer for that which will give raw data of current screen then convert it to bitmap or any picture file.
try {
Process sh = Runtime.getRuntime().exec("su", null,null);
OutputStream os = sh.getOutputStream();
os.write(("/system/bin/screencap -p " + "/sdcard/img.png").getBytes("ASCII"));
os.flush();
os.close();
sh.waitFor();
} catch (IOException e) {
e.printStackTrace();
}

First take code to take screen shot programatically in android. It is available is stack overflow. Then use handler to call this method in every 10 seconds.

Related

Hide Notification panel(Tray) for KIOSK mode

I am trying to build an android app in kiosk-mode. What I have achieved till now is to make the application as full screen and also handled the home and back buttons. However, my problem is, I want to remove the status/notification bar. I don't want the user to access any other settings through it.
Can anyone please help me on this?
You can use immersive mode but that will still allow a user to access the status bar by swiping from the top of the screen 2 times.
What you really want is to run a shell: service call activity 42 s16 com.android.systemui as root.
You can use this function to execute it:
public static void sudo(String...strings) {
try{
Process su = Runtime.getRuntime().exec("su");
DataOutputStream outputStream = new DataOutputStream(su.getOutputStream());
for (String s : strings) {
outputStream.writeBytes(s+"\n");
outputStream.flush();
}
outputStream.writeBytes("exit\n");
outputStream.flush();
try {
su.waitFor();
} catch (InterruptedException e) {
e.printStackTrace();
}
outputStream.close();
}catch(IOException e){
e.printStackTrace();
}
}
This was pulled from another S/O question with pages upon pages of answers but it is the only one to work for me on multiple devices. So, just to save you some time.

Use Appium to make a telephone call on Android device

I would appreciate some help with some test automation on Android devices. We use Appium and RemoteWebDriver code to access the Android emulator, open up our application, tap and move around the application UI, and this all seems to work well.
However, as part of my testing, I would like to use Appium to initiate a telephone call on the device, keep the call open for a minute or so, and then hang up. Is there away to do this through the RemoteWebDriver object?
If not, what is the recommended way to make calls on the emulator? I have seen some discussion of using direct telnet calls to the emulator, but hope there is a better way!
You may set these desired capabilities :
capabilities.setCapability("androidPackage", "com.android.dialer");
capabilities.setCapability("appActivity", "DialtactsActivity");
and use this snippet to make call via Appium :
remoteWebDriver.findElement(By.id("com.android.dialer:id/search_view")).sendKeys("NAME_OF_PERSON");
remoteWebDriver.findElements(By.id("com.android.dialer:id/dialer_search_item_view")).get(0).click();
This would make call to the first search item
try {
Thread.sleep(60000); //
} catch (InterruptedException e) {
e.printStackTrace();
}
remoteWebDriver.findElement(By.id("com.android.dialer:id/endButton")).click();
This would disconnect the call after 60 seconds.
You can use a start a phone call using ADB:
public static int makePhoneCall(AppiumDriver driver, Srting deviceId, String phoneNum, int callDuration) throws IOException, InterruptedException {
callDuration *= 1000;
cmd = "adb -s " + deviceId + " shell am start -a android.intent.action.CALL -d tel:" + phoneNum; //open a Dialer and placing a call right away
Process exec = Runtime.getRuntime().exec(cmd); //starting a call and..
Thread.sleep(callDuration);//..waiting for callDuration seconds before hangup
driver.sendKeyEvent(6);// hang up phonecall
return exec.exitValue();
}
It turns out that this is possible, though perhaps a little more painfully than I expected. I had to do two things: specify the correct app to open, and work out the xpath references to the buttons on the dial pad. The activity is com.android.contacts.activities.DialtactsActivity and the xpaths to some of the buttons are:
Number text field: /linear/linear/editText
Number 1 button: /linear/table/row[1]/imageButton[1]
Number 5 button: /linear/table/row[2]/imageButton[2]
Dial button: /linear/frame/imageButton
If anyone has a better way to do this, I'd be very pleased to see it! Martin
press home button
driver.sendKeyEvent(3);
Press call button.
dr.sendKeyEvent(5);
locate dial pad
driver.findElementById("com.android.dialer:id/dialpad_button").click();
type number by send key or by sendKeyEvents.
driver.findElement(By.className("android.widget.EditText")).sendKeys(phoneNumber);
Press call button
driver.findElementById("com.android.dialer:id/dial_button").click();
put some wait and press End call button.
dr.findElementById("com.android.dialer:id/endButton").click();

Android executing SU commands in background?

I'm writing an android app that sets the max frequency, governor etc.. when the screen turns off. To do it i have a service running that receives screen on/off broadcast intents. When the screen off event fires, I read from the shared preferences and set whatever is set by the user with this function
public static void writeFile(String file, String content) {
try {
Process suProcess = Runtime.getRuntime().exec("su");
DataOutputStream out = new DataOutputStream(suProcess.getOutputStream());
out.writeBytes("echo '" + content + "' > '" + file + "'");
out.flush();
out.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
Then when the screen turns back on, i revert the system to its previous state by rewriting the files. Everything is working nicely, working as intended.
The problem is i'm noticing some lag when turning the screen on/off. Also when i turn the screen on, i see the toast message from SuperUser "App was granted su access", and it pops up once for every command. Is there a way to hide that toast message? I haven't found any way to hide a toast message from another activity. I know they can be disabled in the superuser app, but that's not ideal. I read you can write your own superuser binary but that sounds alot more complicated than simple java programming... also sounds like it could lead to security problems.
Basically i'm asking what's the best way to do this, so that it's as non-invasive to the user as possible?
I haven't used su, but I think if you don't close the stream every time it should only display toast once.

Error setting the CPU scaling governor through app

I'm creating a simple Android app that should set the CPU Scaling Governor.
To achieve this I made this function:
public static void setCurrentGovernor(String governor){
Process process;
try{
String cpufreq_path= "/sys/devices/system/cpu/cpu0/cpufreq";
String cmd = "echo `"+governor+"` > "+cpufreq_path+"/scaling_governor ";
process = Runtime.getRuntime().exec(new String[] {"su","-c",cmd});
} catch(IOException e){
e.printStackTrace();
}
}
My problem is that this function won't work, plus superuser always prompts me for permissions, is there a way to give it root permission only at first app boot?
This function is called inside an onitemselectedlistener of a spinner, right after this function there's another one which fetches data from cpufreq files to update the view, but if i do cat scaling_governor i get the old governor, so it is not a faulty update function.
This more solid code solved my problem:
Link

Working with capacitive buttons in Android

I was curious if there is any library to work with the capacitive buttons of Samsung phones??
I mean to light them up when an event occurs, or blink them, stuffs like that...
Thanks,
rohitkg
There is nothing in the Android SDK for this, as there is no assumption that such buttons exist, have backlights, etc. You are welcome to contact device manufacturers to see if they have a documented and supported means of doing this for their specific devices.
Here's a code snippet I grabbed from samsung-moment-notifications.
Process process = null;
DataOutputStream os = null;
try {
// get root
process = Runtime.getRuntime().exec("su");
os = new DataOutputStream(process.getOutputStream());
// write the command
os.writeBytes("echo 100 > /sys/class/leds/button-backlight/brightness\n");
os.writeBytes("exit\n");
// clear the buffer
os.flush();
Toast.makeText(NotificationLights.this, "Lights are on", Toast.LENGTH_SHORT).show();
// wait for complete
process.waitFor();
// won't catch an error with root, but it has to have an exception catcher to execute
} catch (Exception e) {
Toast.makeText(NotificationLights.this, "Couldn't get SU, are you rooted?", Toast.LENGTH_SHORT).show();
return;
}
1- You must have a rooted device.
2- You must know the location of the script which turns the lights on/off for each device.
/sys/class/leds/button-backlight/brightness is specific to the Samsung Moment.
If you were to try it on another device it wouldn't work.

Categories

Resources