蓝牙文件传输文件> 1024k

时间:2018-09-03 16:01:03

标签: android bluetooth

有人可以告诉我我做错了什么吗?抱歉,这是一个漫长的问题,但是我已经阅读了很多文章并尝试了很多事情,甚至比下面描述的还要多。

我正在尝试使用BluetoothChat示例作为基础通过Bluetooth传输文件,而超过1024k的任何内容我都无法成功传输。我的目标是使应用程序定期传输文件(每分钟1个文件),而无需用户交互(一旦用户启动了文件),因此需要透明地进行传输;因此希望通过代码而不是使用意图来实现。

1)基础。在BluetoothFragment中,我有

private void transferFile(String file) {
    File imageFile = new File(getActivity().getExternalFilesDir(null), file);
    if (!imageFile.exists()) {
        ...; return;
    } else {
        try {
            byte[] myByteArray = new byte[(int)imageFile.length()];
            FileInputStream fis = new FileInputStream(imageFile);
            BufferedInputStream bis = new BufferedInputStream(fis);
            bis.read(myByteArray,0,myByteArray.length);
            mBluetoothService.transferOut(myByteArray);
        } catch (IOException e) {
            e.printStackTrace();

和在BluetoothService中

public void transferOut(byte[] out) {
    ConnectedThread r;
    synchronized (this) {
        if (mState != STATE_CONNECTED) return;
        r = mConnectedThread;
    }
    r.transferOut(out);    
}
private class ConnectedThread extends Thread {
    private final BluetoothSocket mmSocket;
    private final InputStream mmInStream;
    private final OutputStream mmOutStream;
    ...
    public void transferOut(byte[] buffer) {
    try {
            //tried this
    //                mmOutStream.write(buffer);
            //then this
    //                for(int i = 0 ; i < buffer.length ; i++) {
    //                    mmOutStream.write(buffer[i]);}
            //then this. All had same results.
            mmOutStream.write(buffer, 0, buffer.length);
    ...
    public void run() {
        byte[] buffer = new byte[1024];
        int bytes, current;
        while (mState == STATE_CONNECTED) {
        try {
            bytes = mmInStream.read(buffer);
                mHandler.obtainMessage(Constants.MESSAGE_READ, bytes, -1, buffer)
                        .sendToTarget();

如果文件为<1024k,则BluetoothFragment中的处理程序会将其正确写入磁盘;如果较大,则会被裁剪。

2)找到此建议以重复阅读。将ConnectedThread run()更改为

    try {
                bytes = mmInStream.read(buffer, 0, buffer.length);
                current = bytes;
                do {
                    bytes = mmInStream.read(buffer, current, buffer.length - current);
                    if (bytes >= 0)
                        current += bytes;
                } while (bytes > -1);
                mHandler.obtainMessage(Constants.MESSAGE_READ, bytes, -1, buffer)
                        .sendToTarget();

但是它停留在do循环中,大概没有得到闭合的连接字节-1)。

3)另一个版本

public void run() {
byte[] imgBuffer = new byte[2048 * 2048];
int pos = 0;
while (mState == STATE_CONNECTED) {
    try {
        byte[] buffer = new byte[2048];
            int bytes = mmInStream.read(buffer);
        System.arraycopy(buffer, 0, imgBuffer, pos, bytes);
        pos += bytes;
        mHandler.obtainMessage(Constants.MESSAGE_READ, pos, -1, imgBuffer)
                .sendToTarget();

这有时可能有效,但即使如此也要花费很长时间(也许20分钟,只有几MB-有时最终结果是前一张图像!即使在测试中,我还是手动将其删除!)。

4)正在发送文件大小。要测试该概念,请从2个步骤开始。首先发送文件大小:

File imageFile = new File(getActivity().getExternalFilesDir(null), file);
String inputString = FILE_LENGTH + (int)imageFile.length();
byte[] myByteArrayLgth = new byte[1024];
myByteArrayLgth = inputString.getBytes();
mService.transferOutFileLength(myByteArrayLgth);

然后在ConnectedThread run()中手动说明文件大小,以最大程度地减少错误。尝试了几种方法,最后一种是:

    public void run() {
        byte[] buffer = new byte[80 * 1024];
        int bytes, current;
        int targetFileSize = 57828;
        while (mState == STATE_CONNECTED) {
            try {
                bytes = mmInStream.read(buffer);
                current = bytes;
                while (current < targetFileSize) {
                    bytes = mmInStream.read(buffer);
                    current = current + bytes;
                }
                mHandler.obtainMessage(Constants.MESSAGE_READ, current, -1, buffer)
                        .sendToTarget();

还将写入磁盘的内容更改为

fos.write(readBuf, 0, arg1);  //arg1 is filesize

此生成的文件的类型(jpeg)和大小正确,但无法显示(可能已损坏)。

有人能看到做错了什么或提出更好的方法吗? 也许蓝牙消息/块的大小和顺序太不可预测了;也许我应该考虑使用Wifi? 我正在测试的2个设备是Android 8.0.0和4.4.3。 (因此为sdk 19)。

0 个答案:

没有答案