Используйте LocalSocket
, но будьте осторожны, поскольку это может сказаться на безопасности.
LocalSocket
- это Android API для работы с сокетами домена Unix. Доменные сокеты похожи на сокеты TCP / IP, за исключением того, что они существуют только на устройстве, их нельзя использовать для связи по сети.
Вот простое, но небезопасное решение вашей проблемы:
// Create a unique name for the socket.
String name = "your.package.name-" + UUID.randomUUID();
// Bind a server to the socket.
final LocalServerSocket server = new LocalServerSocket(name);
// Connect a client to the socket.
LocalSocket client = new LocalSocket(LocalSocket.SOCKET_STREAM);
client.connect(new LocalSocketAddress(name, LocalSocketAddress.Namespace.ABSTRACT));
// Start a thread to read from the server socket.
new Thread(new Runnable {
@Override
public void run() {
LocalSocket socket = server.accept();
// To read data sent by the client, read from socket.getInputStream().
// To send data to the client, write to socket.getOutputStream().
// After you are done you will need to call socket.close().
}
}).start();
// Get the FileDescriptor associated with the client.
// You can use this FileDescriptor to write data to and/or read data
// sent from the server.
FileDescriptor fileDescriptor = client.getFileDescriptor();
// After you are done you will need to call server.close() and client.close().
Это создает сокет в абстрактном пространстве имен сокетов. Это небезопасно, потому что сокеты домена являются общесистемными, а сокеты в абстрактном пространстве имен не ограничены какой-либо системой разрешений. Единственное требование для подключения или привязки к имени в абстрактном пространстве имен - это знать имя, а имя сокета, используемое вашим приложением, может быть легко обнаружено злоумышленником посредством декомпиляции. Также существует вероятность того, что другое приложение может случайно использовать то же имя сокета. Таким образом, другое приложение может перехватить ваши данные или отправить неожиданные данные через сокет, и от этого трудно защититься.
Лучшее, но более сложное решение - создать сокет в пространстве имен файловой системы. API для этого очень странный, но этого можно добиться следующим образом:
// Create a unique name for the socket in your app's private data area.
// Note this example creates a file named like socket-xxxx in the root of
// your app's private data area. You might want to put it in a subdirectory.
String name = context
.getFileStreamPath("socket-" + UUID.randomUUID())
.getAbsolutePath();
LocalSocketAddress address = new LocalSocketAddress(name, LocalSocketAddress.Namespace.FILESYSTEM);
// Bind a server to the socket.
LocalSocket server = new LocalSocket(LocalSocket.SOCKET_STREAM);
server.bind(address);
final LocalServerSocket serverWrapper = new LocalServerSocket(server.getFileDescriptor());
// Connect a client to the socket.
LocalSocket client = new LocalSocket(LocalSocket.SOCKET_STREAM);
client.connect(address);
// Start a thread to read from the server socket.
new Thread(new Runnable {
@Override
public void run() {
LocalSocket socket = serverWrapper.accept();
// To read data sent by the client, read from socket.getInputStream().
// To send data to the client, write to socket.getOutputStream().
// After you are done you will need to call socket.close() and
// serverWrapper.close().
}
}).start();
// Get the FileDescriptor associated with the client.
// You can use this FileDescriptor to write data to and/or read data
// sent from the server.
FileDescriptor fileDescriptor = client.getFileDescriptor();
// After you are done you will need to call server.close() and client.close().
Это создает файл в файловой системе, но никакие данные, проходящие через сокет, никогда не записываются на диск, они полностью находятся в памяти. Файл - это просто имя, представляющее сокет, аналогично файлам в /dev
, которые представляют устройства. Поскольку доступ к сокету осуществляется через файловую систему, на него распространяются обычные разрешения файловой системы, поэтому легко ограничить доступ к сокету, поместив сокет в область личных данных вашего приложения.
Поскольку этот метод создает файл в файловой системе, было бы неплохо удалить файл после того, как вы закончите, а также, возможно, время от времени проверять и очищать старые сокеты, на случай, если ваше приложение выйдет из строя и оставит старые файлы. валяется.
person
Daniel Cassidy
schedule
30.06.2020
FileDescriptor
? изContentProvider
? - person pskink   schedule 24.10.2017ParcelFileDescriptor.createPipe()
и kin, хотя я не уверен, что он будет делать то, что вы хотите. - person CommonsWare   schedule 24.10.2017MediaMuxer (FileDescriptor fd, int format)
, чтобы я мог записывать байты в выходной поток сокета TCP без записи данных в файл. - person PC.   schedule 24.10.2017ParcelFileDescriptor#fromSocket()
- person pskink   schedule 24.10.2017E/MPEG4Writer: cannot seek mFd: Illegal seek (29) 47
Невозможно найти выходной поток сокета TCP. Итак, ищем другое решение, которое включает ByteArrayOutputStream с FileDescriptor. - person PC.   schedule 24.10.2017"cannot seek mFd"
- я считаю, что доступен только физический файл - person pskink   schedule 24.10.2017