通过OBEX Object PushProfile通过蓝牙接收文件

wwa*_*rzy 5 android bluetooth obex

我有使用OBEX Object Push Profile(OPP)通过蓝牙发送数据的设备.

使用adb logcat我看到我的android设备收到连接(但是中止了这个连接?)

08-22 11:14:37.939: I/BtOppRfcommListener(22586): Accepted connectoin from 00:07:CF:5F:52:A0
08-22 11:14:37.939: I/BtOpp Service(22586): Start Obex Server
08-22 11:14:38.109: D/Obex ServerSession(22586): java.io.IOException: Software caused connection abort
08-22 11:14:38.109: D/PowerManagerService(180): @PowerManagement: 'BtOppObexServer' releaseWakeLock when screen locked
08-22 11:14:39.219: D/BluetoothEventLoop(180): Device property changed: 00:07:CF:5F:52:A0 property: Connected value: false
Run Code Online (Sandbox Code Playgroud)

当我安装蓝牙文件传输(市场上的免费应用程序),然后我就能够接收文件.但我不想安装其他应用程序.

Dav*_*ara 2

我相信我有(至少是部分)解决方案,该解决方案应该允许通过 OPP 拦截文件并添加自定义代码。第一步是进入设置>应用程序>运行>蓝牙共享并杀死BluetoothOppService

然后我使用反射来访问(下面的代码)上的方法BluetoothAdapter,该方法允许侦听特定端口。之后我们可以拦截传入的 OPP 通信并与输入和输出流进行交互。SO线程将有助于OPP通信部分,但作为初始步骤,我读取数据流并回复OPP“OK”消息,即os.writeByte(ObexSession.OBEX_SUCCESS | ObexSession.OBEX_FINAL_BIT);

// simplified exception handling
public class BluetoothAdapterProxy
{
    public static final int CHANNEL_OPP = 12;

    final BluetoothAdapter target;
    static final Class<?> targetClass = BluetoothAdapter.class;
    Method listenOn;

    public BluetoothAdapterProxy(BluetoothAdapter target)
    {
        this.target = target;
        Class<?>[] args = new Class[] { int.class };
        try
        {
            this.listenOn = targetClass.getDeclaredMethod(
                "listenUsingRfcommOn", args);
        }
        catch (NoSuchMethodException e)
        {
            e.printStackTrace();
        }
    }

    public BluetoothServerSocket listenUsingRfcommOn(int channel)
    {
        try
        {
            return (BluetoothServerSocket) (listenOn.invoke(target, 
                new Object[] { channel }));
        }
        catch (Exception e)
        {
            // complain loud, complain long
            throw new RuntimeException(ex);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:初始化使用

serverSocket = new BluetoothAdapterProxy(BluetoothAdapter.getDefaultAdapter())
    .listenUsingRfcommOn(BluetoothAdapterProxy.CHANNEL_OPP);
Run Code Online (Sandbox Code Playgroud)

之后,使用以下来自单独的Thread(以防止阻塞)和远程设备可以通过连接socket = serverSocket.accept();