Probleme bei automatisierter Bluetooth Discovery


#1

Hallo mal wieder
Ich möchte per App Verbindungen mit Bluetooth herstellen, dazu muss ich aber zu erst Geräte in der Nähe finden. Über das System an sich, finde ich mein Testgerät(Laptop) wunderbar, aber meine App findet irgendwie gar nichts. Für das Discovern hab ich folgenden Code nach dem offiziellen Tutorial benutzt. Was mach ich falsch?

public static void sucheHosts(MainActivity a, final ArrayList<BluetoothDevice> devices) {
        bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (bluetoothAdapter == null) {
            Log.i("BTVerbindung", "Kein Bluetooth");
        }
        if (!bluetoothAdapter.isEnabled()) {
            bluetoothAdapter.enable();
        }
        mReceiver = new BroadcastReceiver() {
            public void onReceive(Context context, Intent intent) {
                String action = intent.getAction();
                if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
                } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
                } else if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                    BluetoothDevice device = (BluetoothDevice) intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                    Log.i("BTVerbindung", "Found device " + device.getName());
                }
            }
        };
        if (bluetoothAdapter.isDiscovering())
            bluetoothAdapter.cancelDiscovery();
        IntentFilter filter = new IntentFilter();
        filter.addAction(BluetoothDevice.ACTION_FOUND);
        filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
        filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        a.registerReceiver(mReceiver, filter);
        bluetoothAdapter.startDiscovery();
    }
BluetoothChatHandler.sucheHosts(this, gefundeneGeräte);
        new Thread(new Runnable(){
            @Override
            public void run() {
                while(gefundeneGeräte.size() <= 0){}
                if(gefundeneGeräte.size() > 0){
                    ListView liste = (ListView) findViewById(R.id.listView);
                    for(final BluetoothDevice d : gefundeneGeräte){
                        Button textview = new Button(liste.getContext());
                        textview.setText(d.getName()+" "+d.getAddress());
                        textview.setOnClickListener(new View.OnClickListener(){
                            @Override
                            public void onClick(View v) {
                                BluetoothChatHandler.connectToHost(d);
                            }
                        });
                        liste.addFooterView(textview);
                    }
                    setContentView(R.layout.verbinden);
                }else{
                    Log.i("BTVerbindung", "Keine geräte gefunden");
                }
            }
        }).start();

#2

Hast du die Permissions für Blutooth im Manifest deklariert/eingeholt?

<manifest ... >
  <uses-permission android:name="android.permission.BLUETOOTH" />
 <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
  ...
</manifest>

Die erste ist für Blutooth allgemein, die zweite für die Blutooth Suche.

Seit Android 6.0 bzw. API 23 musst du dir die Permissions zusätzlich zum Installationszeitpunkt noch zur Laufzeit einholen.
https://developer.android.com/training/permissions/requesting.html#perm-request


#3

Im Manifest hab ich die Permissions gesetzt, das verlangt Androidstudio ja sogar von einem, bevor man starten kann. Ich benutz API 21, also brauch ich das mit der Laufzeit nicht.


#4

Das ist mir neu (?).
Nichts desto trotz kann ich mir den Code frühestens am Montag genau anschauen.
Vielleicht weiß ja wer anderst weiter.


#5

ich kann mir das gar nicht so richtig vorstellen - das wäre eine Sicherheitslücke. Dann brauch ich nur API21 verwenden und der Benutzer wird nicht nochmal zu Sicherheit gefragt - und das unter Android 6. Klar Abwärtskompatibilität & so…


#6

Aber wenn ich in Androidstudio API 21 einstelle, kann ich ja nicht mal die Methoden bestimmter Klassen nutzen, weil es die anscheinend noch nicht gibt.


#7

Das ist exakt wie das funktioniert. Stattdessen musst du zum Installationszeitpunkt zustimmen als während der Laufzeit gefragt zu werden.
Zur Laufzeit kannst du dir die Berechtigung auch “irgendwann” holen und dann für alles immer verwenden auch wenn der Nutzer in einem anderen Kontext zugestimmt hat, da man nicht mehrmals zustimmen muss.
Klar ist die Idee dass der Nutzer kurz vor Aufruf der Funktion zustimmt…

Fun Fact: Berechtigungen kann man auch an x beliebige Programme übertragen.
Wenn deine App (z.B. Facebook) Fotoberechtigung als auch Internetberechtigung anfordert und dann eine Fotoapp anfordert zum Bilder schießen und hochladen und du als Nutzer wählst im Dialog irgendeine drittanbieter App aus…
Das wurde nicht ganz durchdacht.


#8

Aber du sagtest ja diese Änderungen kommen mit API 23. Aber da ich weder im Editor damit arbeite, weder auf dem Testgerät installiert habe, kann mein Problem überhaupt daran liegen?


#9

Das galt mogel das es genau so funktioniert wie er sich das nicht erhofft hatte. :wink:
Aber ja das betrifft dich dann nicht.


#10

Woran könnte das Problem dann liegen?