Вы можете использовать библиотеку obex.Казалось, что Android не предоставляет библиотеку obex, но я решил проблему, и решение выложено здесь .
Дальнейшее объяснение (пожалуйста, начните читать с здесь если вы заняты)
- Я пытался создать удаленный контроллер телефона Android (и что-то похожее на сервер telnet), который поможет удаленно управлять телефоном с помощью моего старого телефона.
Основное содержание: Bluetooth FTP-клиент
Мой первый план состоял в том, чтобы приложение проверяло список файлов в каталоге моего телефонного аппарата.
Но я не знал, как подключиться к телефонам моего функционального телефона.FTP-сервер.
Я много гуглил о том, как подключиться к FTP-серверу через Bluetooth, но я мог только обнаружить, что FTP-сервер Bluetoorh использовал OBEX Protocol
.
Я нашел полезный материал (файл PDF) в потоке SO и изучил запросы OBEX connect, операции put и get.
Итак, я наконец написал несколько кодов, которыепытается подключиться к серверу Bluetooth FTP
.Я хочу показать их вам, но я потерял это :( Коды походили на прямую запись байтовых последовательностей в выходной поток.
Мне также было трудно узнать, что делает UUIDприложение подключается как FTP-клиент. Но я попробовал все UUID, извлеченные с использованием приведенного ниже кода.
String parcels="";
ParcelUuid[] uuids=mBtDevice.getUuids();
int i=0;
for (ParcelUuid p:uuids)
{
parcels += "UUID UUID" + new Integer(i).toString() + "=UUID.fromString((\"" + p.getUuid().toString() + "\"));\n\n";
++i;
}
Казалось, ничто не может привести к ответу, который я хотел. Поэтому я поискал больше и нашеля должен не только использовать UUID 00001106-0000-1000-8000-00805f9b34fb для подключения к FTP-серверу OBEX, но также должен передать целевой заголовок ** с UUID ** F9EC7BC4-953C-11D2-984E-525400DC9E09 при отправке запроса OBEX connect
. Приведенный ниже код показывает, как подключиться к FTP-серверу Bluetooth в качестве клиента.
try
{
mBtSocket = mBtDevice.createInsecureRfcommSocketToServiceRecord(UUID.fromString(" 00001106-0000-1000-8000-00805f9b34fb"));
}
catch (Exception e)
{
//e.printStackTrace();
}
Thread thread=new Thread(new Runnable() {
public void run()
{
UUID uuid=UUID.fromString("F9EC7BC4-953C-11D2-984E-525400DC9E09");
ByteBuffer bb = ByteBuffer.wrap(new byte[16]);
bb.putLong(uuid.getMostSignificantBits());
bb.putLong(uuid.getLeastSignificantBits());
byte [] bytes=bb.array();
Operation putOperation=null;
Operation getOperation=null;
try
{
// connect the socket
mBtSocket.connect();
//I will explain below
mSession = new ClientSession((ObexTransport)(mTransport = new BluetoothObexTransport(mBtSocket)));
HeaderSet headerset = new HeaderSet();
headerset.setHeader(HeaderSet.TARGET, bytes);
headerset = mSession.connect(headerset);
if (headerset.getResponseCode() == ResponseCodes.OBEX_HTTP_OK)
{
mConnected = true;
}
else
{
mSession.disconnect(headerset);
}
...
Тогда вытеперь подключен как FTP-клиент и готов использовать операции OBEX для отправки файлов, запроса файлов, списков каталогов и т. д.
- Однако я не хотел ждать час, чтобы отправить свою команду моемутелефон Android. (И это горебудет неэффективным, если я увеличу частоту опроса, так как все методы опроса.)
Начните читать отсюда, если вы заняты Основное содержание: OBEX OPP
По вышеупомянутой причине я жадно искал способы манипулирования OPP, которые я обнаружил в документации OBEX.
Возможно, вы захотите нормально передавать файлы через Bluetooth (без определения вашего протоколаи создание нового настольного приложения только для него) на ваш компьютер, верно?Тогда отправка на почтовый ящик OBEX OPP, который работает на вашем компьютере с Windows, является лучшим решением.Итак, как мы можем подключиться к службе входящих сообщений OPP (Obex Object Push)?
- Настройка библиотеки OBEX Добавьте
import javax.obex;
в свой исходный код.Если ваш компилятор не поддерживает библиотеку OBEX, загрузите исходники и добавьте в свой проект из здесь . - Реализация
ObexTransport
Вы должны предоставить класс, который реализует ObexTransport
для библиотеки, когдавы используете его.Он определяет, как библиотека должна отправлять данные (например, RFCOMM, TCP, ...).Пример реализации здесь .Это может вызвать некоторые ошибки во время выполнения или ошибки компиляции, такие как there's no method
.Но вы можете частично исправить их, заменив вызовы методов константами, такими как return 4096
вместо return mSocket.getMaxTransmitPacketSize();
, превзойдя if
операторы public int getMaxTransmitPacketSize()
.Или вы можете попробовать использовать отражение , чтобы получить эти методы выполнения. - Получить
BluetoothSocket
Получить разъем Bluetooth с помощью mBtDevice.createInsecureRfcommSocketToServiceRecord(UUID.fromString(" 00001105-0000-1000-8000-00805f9b34fb" ));
И вызвать connect()
. - Создать
ClientSession
Создайте экземпляр вашей реализации ObexTransport
и создайте новый ClientSession
, такой как mSession = new ClientSession((ObexTransport)(mTransport = new BluetoothObexTransport(mBtSocket)));
. Отправьте запрос OBEX-соединения на службу входящих сообщений вашего компьютера.
Отправлять OBEX-запросы на размещение, используя ClientSession
.
protected boolean Put(ClientSession session, byte[] bytes, String as, String type)
{
// TODO: Implement this method
//byte [] bytes;
String filename=as;
boolean retry=true;
int times=0;
while (retry && times < 4)
{
Operation putOperation=null;
OutputStream mOutput = null;
//ClientSession mSession = null;
//ArrayUtils.reverse(bytes);
try
{
// Send a file with meta data to the server
final HeaderSet hs = new HeaderSet();
hs.setHeader(HeaderSet.NAME, filename);
hs.setHeader(HeaderSet.TYPE, type);
hs.setHeader(HeaderSet.LENGTH, new Long((long)bytes.length));
Log.v(TAG,filename);
//Log.v(TAG,type);
Log.v(TAG,bytes.toString());
putOperation = session.put(hs);
mOutput = putOperation.openOutputStream();
mOutput.write(bytes);
mOutput.close();
putOperation.close();
}
catch (Exception e)
{
Log.e(TAG, "put failed", e);
retry = true;
times++;
continue;
//e.printStackTrace();
}
finally
{
try
{
if(mOutput!=null)
mOutput.close();
if(putOperation!=null)
putOperation.close();
}
catch (Exception e)
{
Log.e(TAG, "put finally" , e);
retry = true;
times++;
continue;
}
//updateStatus("[CLIENT] Connection Closed");
}
retry = false;
return true;
}
return false;
}
Наконец, отключите.
Тогда вот класс-обёртка.
import android.bluetooth.*;
import android.util.*;
import java.io.*;
import java.util.*;
import javax.obex.*;
public class BluetoothOPPHelper
{
String address;
BluetoothAdapter mBtadapter;
BluetoothDevice device;
ClientSession session;
BluetoothSocket mBtSocket;
protected final UUID OPPUUID=UUID.fromString(("00001105-0000-1000-8000-00805f9b34fb"));
private String TAG="BluetoothOPPHelper";
public BluetoothOPPHelper(String address)
{
mBtadapter=BluetoothAdapter.getDefaultAdapter();
device=mBtadapter.getRemoteDevice(address);
try
{
mBtSocket = device.createRfcommSocketToServiceRecord(OPPUUID);
}
catch (IOException e)
{
throw new RuntimeException(e);
}
}
public ClientSession StartBatch(int n)
{
ClientSession mSession = null;
// TODO: Implement this method
boolean retry=true;
int times=0;
while (retry && times < 4)
{
//BluetoothConnector.BluetoothSocketWrapper bttmp=null;
try
{
mBtSocket.connect();
//bttmp = (new BluetoothConnector(device,false,BluetoothAdapter.getDefaultAdapter(),Arrays.asList(new UUID[]{OPPUUID,OPPUUID, OPPUUID}))).connect();//*/ device.createInsecureRfcommSocketToServiceRecord(OPPUUID);
/*if(mBtSocket.isConnected())
{
mBtSocket.close();
}*/
}
catch (Exception e)
{
Log.e(TAG, "opp fail sock " + e.getMessage());
retry = true;
times++;
continue;
}
try
{
//mBtSocket=bttmp.getUnderlyingSocket();
// mBtSocket.connect();
BluetoothObexTransport mTransport = null;
mSession = new ClientSession((ObexTransport)(mTransport = new BluetoothObexTransport(mBtSocket)));
HeaderSet headerset = new HeaderSet();
// headerset.setHeader(HeaderSet.COUNT,n);
headerset = mSession.connect(null);
if (headerset.getResponseCode() == ResponseCodes.OBEX_HTTP_OK)
{
boolean mConnected = true;
}
else
{
Log.e(TAG, "SEnd by OPP denied;");
mSession.disconnect(headerset);
times++;
continue;
}
}
catch (Exception e)
{
Log.e(TAG, "opp failed;" , e);
retry = true;
times++;
continue;
//e.rintStackTrace();
}
retry=false;
}
return mSession;
}
protected boolean Put(ClientSession session, byte[] bytes, String as, String type)
{
// TODO: Implement this method
//byte [] bytes;
String filename=as;
boolean retry=true;
int times=0;
while (retry && times < 4)
{
Operation putOperation=null;
OutputStream mOutput = null;
//ClientSession mSession = null;
//ArrayUtils.reverse(bytes);
try
{
// Send a file with meta data to the server
final HeaderSet hs = new HeaderSet();
hs.setHeader(HeaderSet.NAME, filename);
hs.setHeader(HeaderSet.TYPE, type);
hs.setHeader(HeaderSet.LENGTH, new Long((long)bytes.length));
Log.v(TAG,filename);
//Log.v(TAG,type);
Log.v(TAG,bytes.toString());
putOperation = session.put(hs);
mOutput = putOperation.openOutputStream();
mOutput.write(bytes);
mOutput.close();
putOperation.close();
}
catch (Exception e)
{
Log.e(TAG, "put failed", e);
retry = true;
times++;
continue;
//e.printStackTrace();
}
finally
{
try
{
if(mOutput!=null)
mOutput.close();
if(putOperation!=null)
putOperation.close();
}
catch (Exception e)
{
Log.e(TAG, "put finally" , e);
retry = true;
times++;
continue;
}
//updateStatus("[CLIENT] Connection Closed");
}
retry = false;
return true;
}
return false;
}
protected boolean Put(ClientSession s, OPPBatchInfo info)
{
return Put(s,info.data,info.as,info.type);
}
private void FinishBatch(ClientSession mSession) throws IOException
{
mSession.disconnect(null);
try
{
Thread.sleep((long)500);
}
catch (InterruptedException e)
{}
mBtSocket.close();
}
public boolean flush() throws IOException
{
if (sendQueue.isEmpty())
{
return true;
}
try
{
Thread.sleep((long)2000);
}
catch (InterruptedException e)
{}
ClientSession session=StartBatch(sendQueue.size());
if (session == null)
{
return false;
}
while (!sendQueue.isEmpty())
{
if (Put(session, sendQueue.remove()) == false)
{
Log.e(TAG, "Put failed");
}
}
FinishBatch(session);
return true;
}
Queue<OPPBatchInfo> sendQueue;
public boolean AddTransfer(String as,String mimetype,byte[] data)
{
return sendQueue.add(new OPPBatchInfo(as,mimetype,data));
}
class OPPBatchInfo
{
String as;
String type;
byte[] data;
public OPPBatchInfo(String as,String type,byte[] data)
{
this.as=as;
this.data=data;
this.type=type;
}
}
}