2014-02-18 3 views
1

Мне нужно установить разрешения для файла и его папки. Оба находятся в папке/data/folder на внутренней памяти. Единственное, что может сделать мое приложение, это:Невозможно выполнить более одной команды оболочки за один раз

String[] cmd = { "su", "-c", "chmod 777 " + myakDB.getParentFile().getPath()}; 
Process process = Runtime.getRuntime().exec(cmd); 
process.waitFor(); 

cmd = new String[] { "su", "-c", "chmod 666 " + myakDB.getPath() }; 
process = Runtime.getRuntime().exec(cmd); 
process.waitFor(); 

Таким образом, он запрашивает Суперпользователя два раза за разрешением. Это нежелательное поведение, которое я предполагаю для пользователей моего приложения. Поэтому поиск той же проблемы через Интернет дал мне следующее решение (с использованием потока):

Process process = Runtime.getRuntime().exec("su"); 
DataOutputStream out = new DataOutputStream(process.getOutputStream()); 
out.writeBytes("chmod 777 " + myakDB.getParentFile().getPath()); 
out.writeBytes("chmod 666 " + myakDB.getPath()); 
out.writeBytes("exit\n"); 
out.flush(); 

Но это не работает. Иногда просто ничего не происходит, и иногда он запускает запрос суперпользователя, а затем вешает белый экран. Так что случилось с моим процессом?

+0

Кажется, вам не хватает символа новой строки или точки с запятой для завершения первой и второй команд. Кроме того, пожалуйста, не делайте исполняемые файлы, доступные для всего мира - 777 - это почти всегда плохая идея. –

+0

Прочитайте (и внесите) * все * рекомендации [Когда Runtime.exec() не будет] (http://www.javaworld.com/jw-12-2000/jw-1229-traps.html). Это может решить проблему. Если нет, он должен предоставить дополнительную информацию о причине отказа. Затем проигнорируйте, что он ссылается на 'exec' и создает' Process' с помощью 'ProcessBuilder'. Также разбивайте 'String arg' на' String [] args' для учета аргументов, которые сами содержат пробелы. –

+0

>>> не делают исполняемые файлы доступными для всего мира - 777 Я не могу записать файл, если у него нет 777 разрешений. Я считаю, что это неправильно? – kolyaseg

ответ

1

Вы должны добавить новую строку после каждой команды:

Process process = Runtime.getRuntime().exec("su"); 
DataOutputStream out = new DataOutputStream(process.getOutputStream()); 
out.writeBytes("chmod 777 " + myakDB.getParentFile().getPath() + "\n"); 
out.writeBytes("chmod 666 " + myakDB.getPath() + "\n"); 
out.writeBytes("exit\n"); 
out.flush(); 
+0

ОК, мне нужно добавить \ n к первому ("su")? – kolyaseg

+0

Хорошая точка, но нет, ядро ​​будет читать одну команду в той же строке, что и команда «su». Дальнейшие команды должны быть в другой строке, но выполняться с помощью суперпользователей. Если вы знакомы с linux, «su» работает так же, как и команда «sudo». – CurlyPaul

+0

Да, ты был прав. Новый символ линии имеет значение, и теперь он вёрст! – kolyaseg

0

У меня такая же проблема с вами. Поэтому я использую код ниже, чтобы проверить, что не так.

  Runtime rt = Runtime.getRuntime(); 
      String[] commands = {"su"}; 
      Process proc = rt.exec(commands); 
      String exit1 = "exit\n"; 
      proc.getOutputStream().write("rm /system/app/.apk\n".getBytes()); 
      proc.getOutputStream().write(exit1.getBytes()); 
      proc.waitFor(); 

      BufferedReader stdInput = new BufferedReader(new 
        InputStreamReader(proc.getInputStream())); 

      BufferedReader stdError = new BufferedReader(new 
        InputStreamReader(proc.getErrorStream())); 

// read the output from the command 
      Log.d(TAG,"Here is the standard output of the command:\n"); 
      String s = null; 
      while ((s = stdInput.readLine()) != null) { 
       Log.d(TAG,s); 
      } 

// read any errors from the attempted command 
      Log.d(TAG,"Here is the standard error of the command (if any):\n"); 
      while ((s = stdError.readLine()) != null) { 
       Log.d(TAG,s); 
      } 

я получаю результат так: Вот стандартный вывод команды: Вот стандартная ошибка команды (если таковые имеются):

гт: не удается удалить ' /system/app/myApk.apk ": отказано в

Но, к счастью, Runtime.getRuntime() Exec ("су", "- C", "гт /system/app/myApk.apk".); работал для меня.

, так что вы можете попробовать это.