Как использовать каналы unix в Android

Мне нужно отправить некоторые данные в программу C из моего приложения в Android, и я думаю об использовании каналов. Я читал, что Java может получить доступ к существующим каналам (и открывать их как если это обычный файл), но я не могу этого сделать в своем приложении. Когда я пытаюсь, приложение просто блокируется до тех пор, пока не появится сообщение, ожидая закрытия, не записывая ничего особенного в logcat.

Я нашел ветку в списках рассылки Android по этой теме, но это было не очень ясно, и это относится к папке, которой нет на моем телефоне.

Кроме того, я знаю, что невозможно создать каналы на SD-карте, но когда я пытаюсь сделать это in/data, я думаю, что у меня проблемы с корнем ... Вы знаете, можно ли получить доступ к этому каналу (я пытаюсь войти и выйти из папку приложения без успеха)?

Я создал канал с mkfifo, и кажется, что разрешения могут быть открыты любым пользователем.

prw-rw-rw- root     root              2010-11-18 04:53 video_pipe

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

# chmod u+x video_pipe 
Bad mode

Блокирующий код - это инициализация камеры (PATH - это просто путь к трубе):

recorder.setOutputFile(PATH);

Вот весь источник: https://github.com/rbochet/Simple-Camera-App/commit/piped (commit 22dba257f6 )


person Rob    schedule 17.05.2011    source источник
comment
Является ли программа на C дочерним по отношению к вашему Java-процессу? Если это так, получить его каналы stdin / stdout / stderr довольно просто. В противном случае должны работать сокеты домена unix (частные, а не пространство имен файлов). Будет ли программа C работать с тем же идентификатором пользователя, что и java? В таком случае вы можете использовать именованный канал в личном каталоге приложения. chmod на android принимает только восьмеричные аргументы, а не буквенные. Самое главное, что именно вам нужно сделать?   -  person Chris Stratton    schedule 17.05.2011
comment
И попробуйте опубликовать код, который блокирует, пока не появится диалоговое окно ANR.   -  person Chris Stratton    schedule 17.05.2011
comment
Программа на C ffmpeg кросс-скомпилирована для Android. Я хочу использовать его для транскодирования видео в прямом эфире через канал. Я думаю, не должно быть слишком сложно сделать его дочерним процессом (ведь он запускается только из Runtime.exec(), не так ли?). Кстати, спасибо за восьмеричное ... Я должен был увидеть это сам.   -  person Rob    schedule 17.05.2011
comment
Попробуйте опубликовать код, который не работает. Или посмотрите любое приложение терминала Android с открытым исходным кодом. Попробуйте протестировать командную строку ffmpeg из оболочки adb. Попробуйте протестировать свой код java exec и pipe с крошечной программой на C, которая просто делает что-то ожидаемое со своим stdin / out (вы можете связать его с библиотекой журнала Android, чтобы она могла дать вам свое видение того, что происходит вне диапазона)   -  person Chris Stratton    schedule 17.05.2011
comment
Под размещением кода я подразумеваю опубликовать его достаточно, чтобы кто-то мог определить, почему он не работает, или даже продублировать проблему.   -  person Chris Stratton    schedule 17.05.2011
comment
Рассмотрите возможность использования формы Recorder.setOutputFile (), которая принимает дескриптор файла, а не путь, и дает ему fd для дочернего процесса. Но сначала проверьте это в своем коде. Прямо сейчас я подозреваю, что вы пытаетесь соединить непрозрачный фреймворк Android с непрозрачным ffmpeg - попробуйте разместить свой собственный код на обоих концах, чтобы понять, как работает механизм.   -  person Chris Stratton    schedule 17.05.2011
comment
Возможно актуально: stackoverflow.com/questions/2740321/   -  person fadden    schedule 18.05.2011
comment
К сожалению, это не так актуально, потому что я нахожусь в полностью java-среде.   -  person Rob    schedule 18.05.2011


Ответы (2)


Хорошо, я попытался решить проблему с помощью самого дурацкого приложения, которое существует. Вы можете найти его как суть на github.

Пока что я обнаружил это:

  • Единственное место, где работает труба, - это папка приложения (т.е. /data/data/package.full.name/)
  • Если вы хотите передать данные в другую программу, вам лучше запустить ее как дочернюю по отношению к вашему приложению, чтобы убедиться, что они находятся в одной группе и, следовательно, имеют одинаковую авторизацию для папки. Если вы не можете, вы можете поиграть с группами (сделайте ls -l -a на /data/data/ и посмотрите на название группы).

НЕ ЗАБУДЬТЕ: вы не можете писать в трубу, пока кто-то не слушает на другой стороне. Так что, если вы протестируете файл, который я разместил на github, вы получите такой же результат logcat.

I/ActivityManager(  220): Start proc fr.stackr.android.upt for activity fr.stackr.android.upt/.UnixPipeActivity: pid=1359 uid=10048 gids={}
I/UPIPE   ( 1359): Attempt started
W/ActivityManager(  220): Launch timeout has expired, giving up wake lock!
W/ActivityManager(  220): Activity idle timeout for HistoryRecord{4643c8b8 fr.stackr.android.upt/.UnixPipeActivity}

Здесь система останавливается, потому что ничего не происходит ... Затем я запускаю cat v_pipe на телефоне.

V/UPIPE   ( 1359): SEND :: Try to write the first paragraph ....
V/UPIPE   ( 1359): SEND :: Bip
V/UPIPE   ( 1359): Flushing...
V/UPIPE   ( 1359): SEND :: Bip post flush
V/UPIPE   ( 1359): Closing…
I/UPIPE   ( 1359): Attempt ended

Готово.

закрытие: когда я закрываю OutputStreamWriter, сторона прослушивания (т.е. cat) заканчивается. Если я закомментирую строку, cat все равно будет ждать ввода.

промывка: кажется важным, если вы хотите что-то получить, не обращаясь к вам.

Возврат каретки: используйте \n.

person Rob    schedule 18.05.2011

Я думаю, вы можете использовать ParcelFileDescriptor.createPipe()

Он вернет массив каналов для чтения и записи. Для получения дополнительной информации посетите веб-сайт разработчиков.

person Narayan Choudhary    schedule 23.04.2015