The method that I'm going to describe below will let you to programmatically take screen shots of whatever app it's in the foreground from a background process.
I am assuming that you have a rooted device.
I this case you can use the uiautomator framework to get the job done.
This framework has a been created to automate black box testing of apps on android, but it will suite this purpose as well.
We are going to use the method
takeScreenshot(File storePath, float scale, int quality)
This goes in the service class:
File f = new File(context.getApplicationInfo().dataDir, "test.jar");
//this command will start uiautomator
String cmd = String.format("uiautomator runtest %s -c com.mypacket.Test", f.getAbsoluteFile());
Process p = doCmds(cmd);
if(null != p)
{
p.waitFor();
}
else
{
Log.e(TAG, "starting the test FAILED");
}
private Process doCmds(String cmds)
{
try
{
Process su = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(su.getOutputStream());
os.writeBytes(cmds + "\n");
os.writeBytes("exit\n");
os.flush();
os.close();
return su;
}
catch(Exception e)
{
e.printStackTrace();
Log.e(TAG, "doCmds FAILED");
return null;
}
}
This is the class for uiautomator:
public class Test extends UiAutomatorTestCase
{
public void testDemo()
{
UiDevice dev = UiDevice.getInstance();
File f = new File(Environment.getExternalStorageDirectory().getAbsolutePath());
dev.takeScreenshot(f, 1.0, 100);
}
}
It's best if you create a background thread in which uiautomator will run, that way it will not run onto the ui thread. (the Service runs on the ui thread).
uiatuomator doesn't know about or have a android context.
Once uiautomator gets the control you will be able to call inside it android methods that do not take a context parameter or belong to the context class.
If you need to communicate between uiautomator and the service (or other android components) you can use LocalSocket.
This will allow communication in both ways.