I'm able to clear a single package name's data through this snippet. However, i want it to handle more than one package names. in other words, it should clear two more package names' data
private void clearData() {
//"com.uc.browser.en"
//"pm clear com.sec.android.app.sbrowser"
String cmd = "pm clear com.sec.android.app.sbrowser" ;
ProcessBuilder pb = new ProcessBuilder().redirectErrorStream(true)
.command("su");
Process p = null;
try {
p = pb.start();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// We must handle the result stream in another Thread first
StreamReader stdoutReader = new StreamReader(p.getInputStream(),
CHARSET_NAME);
stdoutReader.start();
out = p.getOutputStream();
try {
out.write((cmd + "\n").getBytes(CHARSET_NAME));
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
out.write(("exit" + "\n").getBytes(CHARSET_NAME));
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
out.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
p.waitFor();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String result = stdoutReader.getResult();
}
}
The ProcessCommandsSU
class starts an su
process in which to run a list of commands, and provides an interface to deliver the output to an Activity
asynchronously. Unlike the example you're following, this class will not block the UI thread. The Activity
must implement the OnCommandsReturnListener
interface.
public class ProcessCommandsSU extends Thread {
public interface OnCommandsReturnListener {
public void onCommandsReturn(String output);
}
private final Activity activity;
private final String[] cmds;
public ProcessCommandsSU(Activity activity, String[] cmds) {
if(!(activity instanceof OnCommandsReturnListener)) {
throw new IllegalArgumentException(
"Activity must implement OnCommandsReturnListener interface");
}
this.activity = activity;
this.cmds = cmds;
}
public void run() {
try {
final Process process = new ProcessBuilder()
.redirectErrorStream(true)
.command("su")
.start();
final OutputStream os = process.getOutputStream();
final CountDownLatch latch = new CountDownLatch(1);
final OutputReader or = new OutputReader(process.getInputStream(), latch);
or.start();
for (int i = 0; i < cmds.length; i++) {
os.write((cmds[i] + "\n").getBytes());
}
os.write(("exit\n").getBytes());
os.flush();
process.waitFor();
latch.await();
process.destroy();
final String output = or.getOutput();
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
((OnCommandsReturnListener) activity).onCommandsReturn(output);
}
}
);
}
catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
private class OutputReader extends Thread {
private final InputStream is;
private final StringBuilder sb = new StringBuilder();
private final CountDownLatch latch;
public OutputReader(InputStream is, CountDownLatch latch) {
this.is = is;
this.latch = latch;
}
public String getOutput() {
return sb.toString();
}
public void run() {
try {
final BufferedReader reader = new BufferedReader(
new InputStreamReader(is));
String line = "";
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
}
catch (IOException e) {
e.printStackTrace();
}
latch.countDown();
}
}
}
Using the class is quite simple. We first ensure that our Activity
implements the interface. We then create an instance, passing the Activity
and our array of commands in the constructor, and call its start()
method. In the following example, it's assumed that the Activity
has a TextView
named textOutput
to display the returned output:
public class MainActivity extends Activity
implements ProcessCommandsSU.OnCommandsReturnListener {
...
@Override
public void onCommandsReturn(String output) {
textOutput.append(output + "\n");
}
private void runCommands() {
final String[] cmds = {
"ping -c 5 www.google.com",
"pm list packages android",
"chdir " + Environment.getExternalStorageDirectory(),
"ls"
};
new ProcessCommandsSU(MainActivity.this, cmds).start();
}
}
My device is not rooted, so this was tested with the commands you see in the code above. Simply replace those commands with your pm clear
commands.