Аналогично startService (Intent), но с неявным обещанием, что Служба вызовет startForeground (int, android.app.Notification) после ее запуска. Для этого службе предоставляется количество времени, сопоставимое с интервалом ANR, в противном случае система автоматически остановит службу и объявит ANR приложения.
В отличие от обычного startService (Intent), этот метод может быть используется в любое время независимо от того, находится ли приложение, обслуживающее службу, в переднем плане.
убедитесь, что вы вызываете
Service.startForeground(int, android.app.Notification)
в onCreate (), чтобы убедиться, что он будет вызван Если у вас есть какие-либо условия, которые могут помешать вам это сделать, вам лучше использовать обычныйContext.startService(Intent)
и вызыватьService.startForeground(int, android.app.Notification)
самостоятельно.Кажется, что
Context.startForegroundService()
добавляет сторожевой таймер, чтобы убедиться, что вы вызвалиService.startForeground(int, android.app.Notification)
, прежде чем он был уничтожен ...
Это происходит потому, что команда, переданная в Runtime.exec(String)
, не выполняется в оболочке. Оболочка выполняет множество общих служб поддержки для программ, и когда оболочка не собирается их выполнять, команда будет терпеть неудачу.
Команда будет если это зависит от свойств оболочки. Оболочка имеет много общих и полезных вещей, о которых мы обычно не думаем:
"My File.txt"
остается единственным аргументом. Runtime.exec(String)
наивно разбивается на пробелы и передает это как два отдельных имени файла. Это явно не получается. ls *.doc
, оболочка перезаписывает ее в ls letter.doc notes.doc
. Runtime.exec(String)
нет, он просто передает их в качестве аргументов. ls
не знает, что *
, поэтому команда не работает. ls mydir > output.txt
, оболочка открывает «output.txt» для вывода команды и удаляет ее из командной строки, предоставляя ls mydir
. Runtime.exec(String)
нет. Он просто передает их в качестве аргументов. ls
не знает, что означает >
, поэтому команда не работает. ls "$HOME"
или ls "$(pwd)"
, оболочка перезаписывает его на ls /home/myuser
. Runtime.exec(String)
нет, он просто передает их в качестве аргументов. ls
не знает, что означает $
, поэтому команда не работает. Существует два способа выполнения произвольно сложных команд :
Простая и неаккуратная: делегировать оболочку.
Вы можете просто использовать Runtime.exec(String[])
(обратите внимание на параметр массива) и передать команду непосредственно оболочке, которая может выполнять весь тяжелый подъем:
// Simple, sloppy fix. May have security and robustness implications
String myFile = "some filename.txt";
String myCommand = "cp -R '" + myFile + "' $HOME 2> errorlog";
Runtime.getRuntime().exec(new String[] { "bash", "-c", myCommand });
Безопасный и надежный: возьмите на себя ответственность оболочки.
Это не исправление, которое можно механически применить, но требует понимания модели исполнения Unix, каких оболочек и как вы можете сделать то же самое. Тем не менее, вы можете получить надежное, надежное и надежное решение, сняв оболочку с рисунка. Этому способствует ProcessBuilder
.
Команда из предыдущего примера, которая требует, чтобы кто-то обрабатывал 1. кавычки, 2. переменные и 3. перенаправления, может быть записан как:
String myFile = "some filename.txt";
ProcessBuilder builder = new ProcessBuilder(
"cp", "-R", myFile, // We handle word splitting
System.getenv("HOME")); // We handle variables
builder.redirectError( // We set up redirections
ProcessBuilder.Redirect.to(new File("errorlog")));
builder.start();