2017-02-15 6 views
0

Вот он проблема. Я разработал приложение для iOS для управления светодиодным устройством BLE (и несколько других вещей). Все работает отлично и плавно. Теперь я хотел разработать одно и то же приложение для Android, и я уже отказываюсь при сканировании устройств BLE. Я попробовал несколько учебников и примеров кода, но что бы ни делал, я не могу найти никаких устройств. Я работаю над Moto G4 Play. Bluetooth работает, и я могу спарить устройства в настройках, но он не будет работать с каким-либо образцом кода/учебником, который я пробовал. Например: https://github.com/kaviles/BLE_TutorialsAndroid не найдено ни одного устройства BLE

Я создаю это приложение как есть, и он ничего не может найти.

Так что я скачал сканер BLE из Playstore и отлично работает и находит все устройства.

Я знаю, что трудно сказать без какого-либо образца кода, но я пробовал так много, и я не уверен, если я пропущу что-то совершенно основное.

+2

Проверьте разрешения приложения. Проверьте разрешения SDK 23, потому что вам нужны разрешения на размещение. Убедитесь, что службы определения местоположения включены. Кроме этого, проверьте, что ваш код в порядке! – zed

+0

Я установил все разрешения, но это все равно не сработает. В соответствии с этим: https://code.google.com/p/android/issues/detail?id=196485 кажется, что это довольно проблема. – Patricks

+0

Это не проблема, это предполагаемое поведение, потому что устройства BLE могут выдавать Информация о местонахождении. Вы должны добавить разрешения служб местоположения, а если вы создаете против API 23+, вы должны запросить разрешения во время выполнения. – zed

ответ

2

Как обсуждалось в комментариях, вы должны соответствующим образом настроить разрешения, если ваш targetSdk равен 23+ или другому. Услуги определения местоположения должны быть включены.

Manifest разрешений для API 23+:

<uses-permission android:name="android.permission.BLUETOOTH"/> 
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/> 
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> 
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> 
<uses-permission-sdk-23 android:name="android.permission.ACCESS_FINE_LOCATION"/> 
<uses-permission-sdk-23 android:name="android.permission.ACCESS_COARSE_LOCATION"/> 

Для проверки прав доступа Bluetooth:

public boolean hasBlePermissions() { 
     if (ContextCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION) 
       != PackageManager.PERMISSION_GRANTED || 
       ContextCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_COARSE_LOCATION) 
         != PackageManager.PERMISSION_GRANTED) { 
      return false; 
     } else { 
      return true; 
     } 
    } 

Просить разрешения во время выполнения с:

public void requestBlePermissions(final Activity activity, int requestCode) { 
    ActivityCompat.requestPermissions(activity, 
      new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, 
      requestCode); 
} 

Затем, чтобы проверить результаты грантов от OnRequestPermissionResult:

public boolean checkGrantResults(String[] permissions, int[] grantResults) { 
    int granted = 0; 

    if (grantResults.length > 0) { 
     for(int i = 0; i < permissions.length ; i++) { 
      String permission = permissions[i]; 
      if (permission.equals(Manifest.permission.ACCESS_FINE_LOCATION) || 
        permission.equals(Manifest.permission.ACCESS_COARSE_LOCATION)) { 
       if (grantResults[i] == PackageManager.PERMISSION_GRANTED) { 
        granted++; 
       } 
      } 
     } 
    } else { // if cancelled 
     return false; 
    } 

    return granted == 2; 
} 

услуги Проверить местоположение:

public boolean areLocationServicesEnabled(Context context) { 
    LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); 
    try { 
     return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || 
       locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); 
    } catch (Exception e) { 
     e.printStackTrace(); 
     return false; 
    } 
} 
0

Вы пробовали с кодом образца андроида BLE с сайта разработчика.

https://developer.android.com/samples/BluetoothLeGatt/index.html

Пожалуйста, убедитесь, что о UUID и сделать Нужные изменения для взаимодействия с андроида приложения в этом примере кода, если это необходимо.

1

Спасибо за хорошее объяснение. Теперь я чувствую себя довольно глупым, потому что я действительно не знаю, как это сделать.

Вот мой манифест:

<uses-permission android:name="android.permission.BLUETOOTH"/> 
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/> 
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> 
<uses-feature android:name="android.hardware.location.gps" /> 
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/> 

А вот моя активность:

public class LightActivity extends AppCompatActivity { 
private BluetoothAdapter mBluetoothAdapter; 
private boolean mScanning; 
private Handler mHandler; 
private final static int REQUEST_ENABLE_BT = 1; 

// Stops scanning after 10 seconds. 
private static final long SCAN_PERIOD = 10000; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_light); 

    if(hasBlePermissions() && areLocationServicesEnabled(this)) { 
     final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); 
     mBluetoothAdapter = bluetoothManager.getAdapter(); 

     if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) { 
      Toast.makeText(this, "Bluetooth low energy is not supported", Toast.LENGTH_SHORT).show(); 
      finish(); 
     } 

     // Ensures Bluetooth is available on the device and it is enabled. If not, 
     // displays a dialog requesting user permission to enable Bluetooth. 
     if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) { 
      Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); 
      startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); 
     } else { 
      scanLeDevice(true); 
     } 
    } 
} 

public boolean hasBlePermissions() { 
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED || 
     ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) { 
     return true; 
    } else { 
     return false; 
    } 
} 

public void requestBlePermissions(final Activity activity, int requestCode) { 
    ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, requestCode); 
} 

public boolean checkGrantResults(String[] permissions, int[] grantResults) { 
    int granted = 0; 

    if (grantResults.length > 0) { 
     for(int i = 0; i < permissions.length ; i++) { 
      String permission = permissions[i]; 
      if (permission.equals(Manifest.permission.ACCESS_FINE_LOCATION) || permission.equals(Manifest.permission.ACCESS_COARSE_LOCATION)) { 
       if (grantResults[i] == PackageManager.PERMISSION_GRANTED) { 
        granted++; 
       } 
      } 
     } 
    } else { // if cancelled 
     return false; 
    } 

    return granted == 2; 
} 

public boolean areLocationServicesEnabled(Context context) { 
    LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); 

    try { 
     return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); 
    } catch (Exception e) { 
     e.printStackTrace(); 
     return false; 
    } 
} 

private void scanLeDevice(final boolean enable) { 
    if (enable) { 


     mScanning = true; 
     mBluetoothAdapter.startLeScan(mLeScanCallback); 
    } else { 
     mScanning = false; 
     mBluetoothAdapter.stopLeScan(mLeScanCallback); 
    } 
} 

// Device scan callback. 
private BluetoothAdapter.LeScanCallback mLeScanCallback = 
     new BluetoothAdapter.LeScanCallback() { 
    @Override 
    public void onLeScan(final BluetoothDevice device, int rssi, 
         byte[] scanRecord) { 
     runOnUiThread(new Runnable() { 
      @Override 
      public void run() { 
       Log.i("NEW DEVICE", device.getName()); 
      } 
     }); 
    } 
}; 

}

Я просто признал, что hasBlePermissions() всегда возвращает ложь всеже разрешения в манифесте правильно установить.

ОБНОВЛЕНИЕ: Получил его работу. Как только вы это понимаете, это не так сложно. Сначала предоставите разрешения, затем сканируйте устройство.Вот мой обновленный код в OnCreate метод:

int permissionCheck = ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION); 

if (permissionCheck != PackageManager.PERMISSION_GRANTED) { 
    ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION); 
} else { 
    if(areLocationServicesEnabled(this)) { 
     mHandler = new Handler(); 

     if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) { 
      Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show(); 
      finish(); 
     } 

     final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); 
     mBluetoothAdapter = bluetoothManager.getAdapter(); 

     scanLeDevice(true); 
    } 
} 
+0

не работает для меня. вы уверены, что это код, который сработал для вас? –

+1

см. Мой обновленный код выше. Надеюсь, это неотъемлемая часть. Мой код немного изменился с момента моего последнего сообщения, так что у меня был след, где была проблема. – Patricks

0

Я использую плагин Cordova Cordova-плагин-BLE-центральный, который хорошо работает с Android. Плагин требует следующих разрешений:

ACCESS_COARSE_LOCATION

BLUETOOTH

BLUETOOTH_ADMIN

Надеется, что это помогает,

0

Для Xamarin, API> = 24 я понял, как заставить его работать , возможно, не интуитивно понятно, что вам нужно разрешение COARSE_LOCATION, чтобы заставить Bluetooth работать. Перейдите в проект на Xamarin> щелкните правой кнопкой мыши> Параметры> Установите флажки для Bluetooth и разрешения на доступ> OK -> перестроить на устройстве

Смежные вопросы