Run native executable in Android error - java

I was trying to use this code below to run a native and i get a classnotfoundexception for android.os.exec in Class execClass = Class.forName("android.os.Exec")..any idea y?
try {
// android.os.Exec is not included in android.jar so we need to use reflection.
Class<?> execClass = Class.forName("android.os.Exec");
Method createSubprocess = execClass.getMethod("createSubprocess",
String.class, String.class, String.class, int[].class);
Method waitFor = execClass.getMethod("waitFor", int.class);
// Executes the command.
// NOTE: createSubprocess() is asynchronous.
int[] pid = new int[1];
FileDescriptor fd = (FileDescriptor)createSubprocess.invoke(
null, "/system/bin/ls", "/sdcard", null, pid);
// Reads stdout.
// NOTE: You can write to stdin of the command using new FileOutputStream(fd).
FileInputStream in = new FileInputStream(fd);
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String output = "";
try {
String line;
while ((line = reader.readLine()) != null) {
output += line + "\n";
}
} catch (IOException e) {
// It seems IOException is thrown when it reaches EOF.
}
// Waits for the command to finish.
waitFor.invoke(null, pid[0]);
return output;
} catch (ClassNotFoundException e) {
throw new RuntimeException(e.getMessage());
} catch (SecurityException e) {
throw new RuntimeException(e.getMessage());
} catch (NoSuchMethodException e) {
throw new RuntimeException(e.getMessage());
} catch (IllegalArgumentException e) {
throw new RuntimeException(e.getMessage());
} catch (IllegalAccessException e) {
throw new RuntimeException(e.getMessage());
} catch (InvocationTargetException e) {
throw new RuntimeException(e.getMessage());
}
Link: http://gimite.net/en/index.php?Run%20native%20executable%20in%20Android%20App

android.os.Exec is not part of the public API, and should not be used. The fact that it hasn't been part of the product since 1.6 should be further incentive. :-)
You should use the standard Java-language facilities instead, like Runtime.exec() or ProcessBuilder.start().

Related

Why I can't test for FileNotFoundException in java JUnit 4.13

I am facing some difficulties with testing constructor of my class using JUnit 4.13. What I am trying to do is to test that constructor is throwing FileNotFoundExeption when I pass wrong file name.
This is my constructor (parameter 'file' is name of file where I store languages):
public LanguageManager(String file) {
this.languages = new ArrayList<Language>();
try {
BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(file), "utf-8"));
String line;
while((line = in.readLine()) != null) {
line = line.trim();
if (line.equals("") || line.startsWith("#"))
continue;
Language j = new Language(line);
this.languages.add(j);
}
in.close();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
This is my function for testing this constructor:
#Test(expected=FileNotFoundException.class)
public void testLanguageManager() {
LanguageManager ajm = new LanguageManager("non_existing_file.txt");
}
I suspect that there is problem with try catch block in constructor but can't figure out what I am doing wrong. Any help is appreciated.

Avoid same try catch blocks in Java

I am developing a project which involves JSON manipulation in Java using JSON API. There are many places where I need to read values from JSON file. The API provides checked exceptions for the same. Everytime I use the API to read JSON values, I am forced to write try catch block. As a result, there is a large number of try catch blocks. It makes the code look messy.
String Content = "";
try {
read = new BufferedReader(new FileReader("Data.json"));
}
catch(Exception e) {
System.out.println("File Not found");
}
try {
while((line = read.readLine() ) != null) {
Content = Content+line;
}
} catch (IOException e) {
e.printStackTrace();
}
try {
ResponseArr = new JSONArray( Content );
} catch (JSONException e) {
e.printStackTrace();
}
try {
ResponseObj = ResponseArr.getJSONObject(1).getJSONArray("childrens");
} catch (JSONException e) {
e.printStackTrace();
}
try {
StoreResponse = ResponseArr.getJSONObject(0).getJSONArray("childrens");
} catch (JSONException e) {
e.printStackTrace();
}
Is there any way to avoid this ?A single try catch block would not suffice and the statements are not dependent. Each read statement requires a separate try catch block as I have to log the details of places while catching the exception. Can I invoke a common method whenever I have a code to read JSON data, like sending the code as a paramater to a method which would take care of the exception handling or some other way round ?
Since (all?) the subsequent statements are dependent on the previous it makes no sense having that many try/catch blocks. I would rather put the code inside one try/catch and handle the exceptions by type
Pseudo-code:
String Content = "";
try {
read = new BufferedReader(new FileReader("Data.json"));
while((line = read.readLine() ) != null) {
Content = Content+line;
}
ResponseArr = new JSONArray( Content );
ResponseObj = ResponseArr.getJSONObject(1).getJSONArray("childrens");
} catch (JSONException e) {
e.printStackTrace();
} catch(FileNotFoundException)
System.out.println("File Not found");
}
// and so on
As some are suggesting, you might want to let all these exceptions bubble up (not catching them) since you're not doing anything meaningful when catching them. However, I think that depends on the calling context.
If you are handling all exceptions in the same way, why not combine them in one try/ catch clause
for example like this :
try {
while((line = read.readLine() ) != null) {
Content = Content+line;
}
ResponseArr = new JSONArray( Content );
ResponseObj = ResponseArr.getJSONObject(1).getJSONArray("childrens");
} catch (Exception e) {
e.printStackTrace();
}
Try like this
String Content = "";
try {
read = new BufferedReader(new FileReader("Data.json"));
while((line = read.readLine() ) != null) {
Content = Content+line;
}
ResponseArr = new JSONArray( Content );
ResponseObj = ResponseArr.getJSONObject(1).getJSONArray("childrens");
}
catch (IOException e) {
e.printStackTrace();
}
catch (JSONException e) {
e.printStackTrace();
}
catch(Exception e) {
System.out.println("File Not found");
}

How to handle IOException when closing bufferedReader

Hi I am learning about Exceptions in Java and I encountered a problem with this situation.
public static void main(String[] args){
String path = "t.txt";
BufferedReader br = null;
try{
br = new BufferedReader(new FileReader(path));
StringBuilder sbd = new StringBuilder();
String line = br.readLine();
while(line != null){
sbd.append(line);
sbd.append(System.lineSeparator());
line = br.readLine();
}
String result = sbd.toString();
System.out.print(result);
}catch(IOException e){
System.out.println(e.getMessage());
}finally{
if (br != null)
br.close(); //Here it says unreported exception IOException; must be caught or declared to be thrown
}
}
when I call method close() to close the bufferedReader, it says unreported exception IOException; must be caught or declared to be thrown.
I know that JAVA 7 provides a pretty easy way to do the clean-up with
try(br = new BufferedReader(new FileReader(path))){
//....
}
but prior to JAVA 7, what can I do with this situation? adding "throws IOException" right next to the main function declaration is a way to fix that but is it a little bit complicated since I have had a catch section to catch IOExceptions
You wrapped it into another try-catch
}finally{
if (br != null)
try {
br.close(); //Here it says unreported exception IOException; must be caught or declared to be thrown
} catch (Exception exp) {
}
}
Now, if you care or not is another question. To my mind, your intention here is to make all best effort to close the resource. If you want, you could use flag and set it to true in the parent catch block (indicating that any following errors should be ignored) and if it's false in the close catch block, display an error message, for example...
boolean hasErrored = false;
try {
//...
}catch(IOException e){
e.printStackTrace();
hasErrored = true;
}finally{
if (br != null)
try {
br.close(); //Here it says unreported exception IOException; must be caught or declared to be thrown
} catch (Exception exp) {
if (!hasErrored) {
// Display error message...
}
}
}
prior to JAVA 7, what can I do with this situation?
You can add a try-catch in the finally block like,
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
// Handle the IOException on close by doing nothing.
}
}
}
add another try catch block
...
if(br != null)
try{
br.close();
} catch (IOException io){
}
I generally code it thus:
} finally {
if (br != null) {
try {
br.close();
} catch(IOException ioe) {
// do nothing
}
}
}
In fact, I once wrote a util class containing methods such as closeStream(final InputStream stream), closeStream(final OutputStream stream), closeReader(final Reader reader), etc that hides all this stuff, since you end up using it all the time.
This is approximately how try-with-resources closes resources
BufferedReader br = new BufferedReader(new FileReader(path));
IOException ex = null;
try {
br.read();
// ...
} catch(IOException e) {
ex = e;
} finally {
try {
br.close(); // close quietly
} catch (IOException e) {
if (ex != null) {
ex.addSuppressed(e);
} else {
ex = e;
}
}
}
if (ex != null) {
throw ex;
}

execute shell command from android

I'm trying to execute this command from the application emulator terminal (you can find it in google play) in this app i write su and press enter, so write:
screenrecord --time-limit 10 /sdcard/MyVideo.mp4
and press again enter and start the recording of the screen using the new function of android kitkat.
so, i try to execute the same code from java using this:
Process su = Runtime.getRuntime().exec("su");
Process execute = Runtime.getRuntime().exec("screenrecord --time-limit 10 /sdcard/MyVideo.mp4");
But don't work because the file is not created. obviously i'm running on a rooted device with android kitkat installed. where is the problem? how can i solve? because from terminal emulator works and in Java not?
You should grab the standard input of the su process just launched and write down the command there, otherwise you are running the commands with the current UID.
Try something like this:
try{
Process su = Runtime.getRuntime().exec("su");
DataOutputStream outputStream = new DataOutputStream(su.getOutputStream());
outputStream.writeBytes("screenrecord --time-limit 10 /sdcard/MyVideo.mp4\n");
outputStream.flush();
outputStream.writeBytes("exit\n");
outputStream.flush();
su.waitFor();
}catch(IOException e){
throw new Exception(e);
}catch(InterruptedException e){
throw new Exception(e);
}
A modification of the code by #CarloCannas:
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();
}
}
(You are welcome to find a better place for outputStream.close())
Usage example:
private static void suMkdirs(String path) {
if (!new File(path).isDirectory()) {
sudo("mkdir -p "+path);
}
}
Update:
To get the result (the output to stdout), use:
public static String sudoForResult(String...strings) {
String res = "";
DataOutputStream outputStream = null;
InputStream response = null;
try{
Process su = Runtime.getRuntime().exec("su");
outputStream = new DataOutputStream(su.getOutputStream());
response = su.getInputStream();
for (String s : strings) {
outputStream.writeBytes(s+"\n");
outputStream.flush();
}
outputStream.writeBytes("exit\n");
outputStream.flush();
try {
su.waitFor();
} catch (InterruptedException e) {
e.printStackTrace();
}
res = readFully(response);
} catch (IOException e){
e.printStackTrace();
} finally {
Closer.closeSilently(outputStream, response);
}
return res;
}
public static String readFully(InputStream is) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int length = 0;
while ((length = is.read(buffer)) != -1) {
baos.write(buffer, 0, length);
}
return baos.toString("UTF-8");
}
The utility to silently close a number of Closeables (Soсket may be no Closeable) is:
public class Closer {
// closeAll()
public static void closeSilently(Object... xs) {
// Note: on Android API levels prior to 19 Socket does not implement Closeable
for (Object x : xs) {
if (x != null) {
try {
Log.d("closing: "+x);
if (x instanceof Closeable) {
((Closeable)x).close();
} else if (x instanceof Socket) {
((Socket)x).close();
} else if (x instanceof DatagramSocket) {
((DatagramSocket)x).close();
} else {
Log.d("cannot close: "+x);
throw new RuntimeException("cannot close "+x);
}
} catch (Throwable e) {
Log.x(e);
}
}
}
}
}
Process p;
StringBuffer output = new StringBuffer();
try {
p = Runtime.getRuntime().exec(params[0]);
BufferedReader reader = new BufferedReader(
new InputStreamReader(p.getInputStream()));
String line = "";
while ((line = reader.readLine()) != null) {
output.append(line + "\n");
p.waitFor();
}
}
catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
String response = output.toString();
return response;
Late reply, but it will benefit someone. You can use the sh command in the exec() method.
Here is my example:
try {
File workingDirectory = new File(getApplicationContext().getFilesDir().getPath());
Process shProcess = Runtime.getRuntime().exec("sh", null, workingDirectory);
try{
PrintWriter outputExec = new PrintWriter(new OutputStreamWriter(shProcess.getOutputStream()));
outputExec.println("PATH=$PATH:/data/data/com.bokili.server.nginx/files;export LD_LIBRARY_PATH=/data/data/com.bokili.server.nginx/files;nginx;exit;");
outputExec.flush();
} catch(Exception ignored){ }
shProcess.waitFor();
} catch (IOException ignored) {
} catch (InterruptedException e) {
try{ Thread.currentThread().interrupt(); }catch(Exception ignored){}
} catch (Exception ignored) { }
What have I done with this?
First I call the shell, then I change (set) the necessary environments in it, and finally I start my nginx with it.
This works on unrooted devices too.
Greetings.

Convert byte[] to ArrayList<String>

I found a question here on SO: Convert ArrayList<String> to byte []
It is about converting ArrayList<String> to byte[].
Now is it possible to convert byte[] to ArrayList<String> ?
Looks like nobody read the original question :)
If you used the method from the first answer to serialize each string separately, doing exactly the opposite will yield the required result:
ByteArrayInputStream bais = new ByteArrayInputStream(byte[] yourData);
ObjectInputStream ois = new ObjectInputStream(bais);
ArrayList<String> al = new ArrayList<String>();
try {
Object obj = null;
while ((obj = ois.readObject()) != null) {
al.add((String) obj);
}
} catch (EOFException ex) { //This exception will be caught when EOF is reached
System.out.println("End of file reached.");
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
} catch (FileNotFoundException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
} finally {
//Close the ObjectInputStream
try {
if (ois != null) {
ois.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
If your byte[] contains the ArrayList itself, you can do:
ByteArrayInputStream bais = new ByteArrayInputStream(byte[] yourData);
ObjectInputStream ois = new ObjectInputStream(bais);
try {
ArrayList<String> arrayList = ( ArrayList<String>) ois.readObject();
ois.close();
} catch (EOFException ex) { //This exception will be caught when EOF is reached
System.out.println("End of file reached.");
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
} catch (FileNotFoundException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
} finally {
//Close the ObjectInputStream
try {
if (ois!= null) {
ois.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
Something like this should suffice, forgive any compile typos I've just rattled it out here:
for(int i = 0; i < allbytes.length; i++)
{
String str = new String(allbytes[i]);
myarraylist.add(str);
}
yeah its possible, take each item from byte array and convert to string, then add to arraylist
String str = new String(byte[i]);
arraylist.add(str);
it depends very much on the semantics you expect from such a method. The easiest way would be, new String(bytes, "US-ASCII")—and then split it into the details you want.
There are obviously some problems:
How can we be sure it's "US-ASCII" and not "UTF8" or, say, "Cp1251"?
What is the string delimiter?
What if we want one of the strings to contain a delimiter?
And so on and so forth. But the easiest way is indeed to call String constructor—it'll be enough to get you started.

Categories