使用 Android 蓝牙 API 的 Samsung Galaxy Tab 中的蓝牙检测问题

发布于 2024-11-07 08:01:50 字数 145 浏览 1 评论 0原文

我在使用 Android 蓝牙 API 检测 Galaxy Tab 零级蓝牙设备时遇到问题。尽管我可以用手机或计算机检测到某些设备,但它根本无法“看到”它们。有人遇到过这个问题吗?我正在编写一个应用程序,该应用程序依赖于通过蓝牙与设备配对,并且在这方面提供一些帮助将非常感激。

I have a problem detecting zero class bluetooth devices with my Galaxy Tab using the Android Bluetooth API. It simply does not "see" some devices although I can detect them with my phone or computer. Has anyone run into this problem? I´m writing an app which depends on pairing with a device through bluetooth and some help in this regard would be most appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

月依秋水 2024-11-14 08:01:50

注意:此解决方案仅适用于旧版 Android 操作系统,因为它需要访问设备日志。

是的!我有完全相同的问题,在三星 Galaxy S 和 LG Optimus One 上。我编写了一个类,您可以重复使用来解决此问题,不知道它是否适用于 Galaxy Tab,但您可以尝试:

package com.yourpackagename;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import android.app.Activity;
import android.app.ProgressDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.AsyncTask;

// This class exists due to a bug in the Broadcomm bluetooth stack, which is
// used by many Android smart-phone manufacturers (LG, Samsung HTC etc.).  That
// bug prevents discovery of ALL bluetooth devices that report their Class of Device (CoD)
// code as 0x00, which prevent many SPP (Serial Port Profile) devices from working.
// 
// See: http://www.google.com/codesearch/p?hl=en#4hzE-Xyu5Wo/vendor/brcm/adaptation/dtun/dtunc_bz4/dtun_hcid.c&q=%22Device%20[%25s]%20class%20is%200x00%20-%20skip%20it.%22&sa=N&cd=1&ct=rc
// And: http://stackoverflow.com/questions/4215398/bluetooth-device-not-discoverable
// And: http://www.reddit.com/r/Android/comments/hao6p/my_experience_with_htc_support_eu_anyone_has/
//
// How to use (from your Activity class):
// 
//  (new BluetoothClassZeroDiscoveryTask(this, new BluetoothDiscoveryCallback())).execute();
//
// Where BluetoothDiscoveryCallback is a class defined e.g. in your Activity.  The call method
// will be called after the discovery task completes, and is passed the complete list
// of paired bluetooth devices, including those that are undiscoverable due to the above bug.
//
//  private class BluetoothDiscoveryCallback implements Action<ArrayList<BluetoothDevice>>
//  {
//      public void call(ArrayList<BluetoothDevice> devices)
//      {
//          // Now you have the list of ALL available devices, 
//          // including those that report class 0x00.
//      }
//  }
//
//  // Java equivalent of the built-in Action from C#.
//  public interface Action<T>
//  {
//      void call(T target);
//  }
//
public class BluetoothClassZeroDiscoveryTask extends AsyncTask<Void, Void, Void>
{
    // This is the well-known ID for bluetooth serial port profile (SPP) devices.
    public static final UUID BluetoothSerialUuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

    private Activity _parent;
    private boolean _discoveryComplete = false;
    private Action<ArrayList<BluetoothDevice>> _callback;
    private ArrayList<BluetoothDevice> _devices = new ArrayList<BluetoothDevice>();
    private Calendar _discoveryStartTime;
    private SimpleDateFormat _logDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.SSS");
    private BluetoothAdapter _adapter;
    private ProgressDialog _progressDialog;

    public BluetoothClassZeroDiscoveryTask(Activity parent, Action<ArrayList<BluetoothDevice>> callback)
    {
        _callback = callback;
        _parent = parent;
        _adapter = BluetoothAdapter.getDefaultAdapter();

        IntentFilter foundFilter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
        _parent.registerReceiver(mReceiver, foundFilter);
        IntentFilter finishedFilter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        _parent.registerReceiver(mReceiver, finishedFilter);

        // This task performs a scan for bluetooth devices, which 
        // takes ~ 12 seconds, so show an indeterminate progress bar.
        _progressDialog = ProgressDialog.show(_parent, "", "Discovering bluetooth devices...", true);
    }

    // Kicks off bluetooth discovery.
    @Override
    protected Void doInBackground(Void... params)
    {
        _discoveryStartTime = Calendar.getInstance();
        _adapter.startDiscovery();

        while (!_discoveryComplete)
        {
            try
            {
                Thread.sleep(500);
            }
            catch (InterruptedException e) { }
        }

        _adapter.cancelDiscovery();
        return null;
    }

    // Provide notification of results to client.
    @Override
    protected void onPostExecute(Void result)
    {
        _progressDialog.dismiss();
        _parent.unregisterReceiver(mReceiver);
        _callback.call(_devices);
    }

    // Handler for bluetooth discovery events.
    private final BroadcastReceiver mReceiver = new BroadcastReceiver()
    {
        @Override
        public void onReceive(Context context, Intent intent)
        {
            String action = intent.getAction();
            if (BluetoothDevice.ACTION_FOUND.equals(action))
            {
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

                // If it's already paired, skip it, (we'll add it after the scan completes).
                if (device.getBondState() != BluetoothDevice.BOND_BONDED)
                {
                    _devices.add(device);
                }
            }
            else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action))
            {
                // Add all already-paired devices to the list.
                for (BluetoothDevice device : _adapter.getBondedDevices())
                {
                    _devices.add(device);
                }

                // Trawl through the logs to find any devices that were skipped >:(
                try
                {
                    Process process = Runtime.getRuntime().exec("logcat -d -v time *:E");
                    BufferedReader bufferedReader = new BufferedReader(
                            new InputStreamReader(process.getInputStream()));

                    String line;
                    Pattern pattern = Pattern.compile("(.{18}).*\\[(.+)\\] class is 0x00 - skip it.");
                    while ((line = bufferedReader.readLine()) != null)
                    {
                        Matcher matcher = pattern.matcher(line);
                        if (matcher.find())
                        {
                            // Found a blocked device, check if it was newly discovered.
                            // Android log timestamps don't contain the year!?
                            String logTimeStamp = Integer.toString(_discoveryStartTime.get(Calendar.YEAR)) + "-" + matcher.group(1);
                            Date logTime = null;
                            try
                            {
                                logTime = _logDateFormat.parse(logTimeStamp);
                            }
                            catch (ParseException e) { }

                            if (logTime != null)
                            {
                                if (logTime.after(_discoveryStartTime.getTime()))
                                {
                                    // Device was discovered during this scan,
                                    // now we want to get the name of the device.
                                    String deviceAddress = matcher.group(2);
                                    BluetoothDevice device = _adapter.getRemoteDevice(deviceAddress);

                                    // In order to get the name, we must attempt to connect to the device.
                                    // This will attempt to pair with the device, and will ask the user
                                    // for a PIN code if one is required.
                                    try
                                    {
                                        BluetoothSocket socket = device.createRfcommSocketToServiceRecord(BluetoothSerialUuid);
                                        socket.connect();
                                        socket.close();
                                        _devices.add(device);
                                    }
                                    catch (IOException e) { }
                                }
                            }
                        }
                    }
                }
                catch (IOException e) {}

                _discoveryComplete = true;
            }
        }
    };
}

另请参阅:
http://zornsoftware.codenature.info/博客/pairing-spp-bluetooth-devices-with-android-phones.html

Note: This solution will only work with old Android OSs, due to it's need for access to the device logs.

Yes! I have exactly the same problem, abeit on a Samsung Galaxy S, and LG Optimus One. I wrote a class you can reuse to fix this, no idea if it will work on the Galaxy Tab, but you can try:

package com.yourpackagename;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import android.app.Activity;
import android.app.ProgressDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.AsyncTask;

// This class exists due to a bug in the Broadcomm bluetooth stack, which is
// used by many Android smart-phone manufacturers (LG, Samsung HTC etc.).  That
// bug prevents discovery of ALL bluetooth devices that report their Class of Device (CoD)
// code as 0x00, which prevent many SPP (Serial Port Profile) devices from working.
// 
// See: http://www.google.com/codesearch/p?hl=en#4hzE-Xyu5Wo/vendor/brcm/adaptation/dtun/dtunc_bz4/dtun_hcid.c&q=%22Device%20[%25s]%20class%20is%200x00%20-%20skip%20it.%22&sa=N&cd=1&ct=rc
// And: http://stackoverflow.com/questions/4215398/bluetooth-device-not-discoverable
// And: http://www.reddit.com/r/Android/comments/hao6p/my_experience_with_htc_support_eu_anyone_has/
//
// How to use (from your Activity class):
// 
//  (new BluetoothClassZeroDiscoveryTask(this, new BluetoothDiscoveryCallback())).execute();
//
// Where BluetoothDiscoveryCallback is a class defined e.g. in your Activity.  The call method
// will be called after the discovery task completes, and is passed the complete list
// of paired bluetooth devices, including those that are undiscoverable due to the above bug.
//
//  private class BluetoothDiscoveryCallback implements Action<ArrayList<BluetoothDevice>>
//  {
//      public void call(ArrayList<BluetoothDevice> devices)
//      {
//          // Now you have the list of ALL available devices, 
//          // including those that report class 0x00.
//      }
//  }
//
//  // Java equivalent of the built-in Action from C#.
//  public interface Action<T>
//  {
//      void call(T target);
//  }
//
public class BluetoothClassZeroDiscoveryTask extends AsyncTask<Void, Void, Void>
{
    // This is the well-known ID for bluetooth serial port profile (SPP) devices.
    public static final UUID BluetoothSerialUuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

    private Activity _parent;
    private boolean _discoveryComplete = false;
    private Action<ArrayList<BluetoothDevice>> _callback;
    private ArrayList<BluetoothDevice> _devices = new ArrayList<BluetoothDevice>();
    private Calendar _discoveryStartTime;
    private SimpleDateFormat _logDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.SSS");
    private BluetoothAdapter _adapter;
    private ProgressDialog _progressDialog;

    public BluetoothClassZeroDiscoveryTask(Activity parent, Action<ArrayList<BluetoothDevice>> callback)
    {
        _callback = callback;
        _parent = parent;
        _adapter = BluetoothAdapter.getDefaultAdapter();

        IntentFilter foundFilter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
        _parent.registerReceiver(mReceiver, foundFilter);
        IntentFilter finishedFilter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        _parent.registerReceiver(mReceiver, finishedFilter);

        // This task performs a scan for bluetooth devices, which 
        // takes ~ 12 seconds, so show an indeterminate progress bar.
        _progressDialog = ProgressDialog.show(_parent, "", "Discovering bluetooth devices...", true);
    }

    // Kicks off bluetooth discovery.
    @Override
    protected Void doInBackground(Void... params)
    {
        _discoveryStartTime = Calendar.getInstance();
        _adapter.startDiscovery();

        while (!_discoveryComplete)
        {
            try
            {
                Thread.sleep(500);
            }
            catch (InterruptedException e) { }
        }

        _adapter.cancelDiscovery();
        return null;
    }

    // Provide notification of results to client.
    @Override
    protected void onPostExecute(Void result)
    {
        _progressDialog.dismiss();
        _parent.unregisterReceiver(mReceiver);
        _callback.call(_devices);
    }

    // Handler for bluetooth discovery events.
    private final BroadcastReceiver mReceiver = new BroadcastReceiver()
    {
        @Override
        public void onReceive(Context context, Intent intent)
        {
            String action = intent.getAction();
            if (BluetoothDevice.ACTION_FOUND.equals(action))
            {
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

                // If it's already paired, skip it, (we'll add it after the scan completes).
                if (device.getBondState() != BluetoothDevice.BOND_BONDED)
                {
                    _devices.add(device);
                }
            }
            else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action))
            {
                // Add all already-paired devices to the list.
                for (BluetoothDevice device : _adapter.getBondedDevices())
                {
                    _devices.add(device);
                }

                // Trawl through the logs to find any devices that were skipped >:(
                try
                {
                    Process process = Runtime.getRuntime().exec("logcat -d -v time *:E");
                    BufferedReader bufferedReader = new BufferedReader(
                            new InputStreamReader(process.getInputStream()));

                    String line;
                    Pattern pattern = Pattern.compile("(.{18}).*\\[(.+)\\] class is 0x00 - skip it.");
                    while ((line = bufferedReader.readLine()) != null)
                    {
                        Matcher matcher = pattern.matcher(line);
                        if (matcher.find())
                        {
                            // Found a blocked device, check if it was newly discovered.
                            // Android log timestamps don't contain the year!?
                            String logTimeStamp = Integer.toString(_discoveryStartTime.get(Calendar.YEAR)) + "-" + matcher.group(1);
                            Date logTime = null;
                            try
                            {
                                logTime = _logDateFormat.parse(logTimeStamp);
                            }
                            catch (ParseException e) { }

                            if (logTime != null)
                            {
                                if (logTime.after(_discoveryStartTime.getTime()))
                                {
                                    // Device was discovered during this scan,
                                    // now we want to get the name of the device.
                                    String deviceAddress = matcher.group(2);
                                    BluetoothDevice device = _adapter.getRemoteDevice(deviceAddress);

                                    // In order to get the name, we must attempt to connect to the device.
                                    // This will attempt to pair with the device, and will ask the user
                                    // for a PIN code if one is required.
                                    try
                                    {
                                        BluetoothSocket socket = device.createRfcommSocketToServiceRecord(BluetoothSerialUuid);
                                        socket.connect();
                                        socket.close();
                                        _devices.add(device);
                                    }
                                    catch (IOException e) { }
                                }
                            }
                        }
                    }
                }
                catch (IOException e) {}

                _discoveryComplete = true;
            }
        }
    };
}

See also:
http://zornsoftware.codenature.info/blog/pairing-spp-bluetooth-devices-with-android-phones.html

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文