Автономный нативный сканер маяков BLE работает, но не работает, когда тот же код используется в нативном плагине Unity. - PullRequest
0 голосов
/ 01 мая 2019

Я использую некоторый нативный код Android для сканирования устройств BLE.Код работает нормально при использовании в автономном приложении Android, но не работает при использовании в родном плагине Android Unity.

У меня есть все авторизации в моем файле манифеста, особенно Bluetooth и Coarse Location:

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

и телефон Samsung A5 2017 с Android 8 имеют Bluetooth и точную локализацию.Этот код сделан для версии 5 Android.(Цель в Unity и Eclipse).

Следующая функция вызывается из Unity без каких-либо проблем:

startBLEScan();

Но функция

 public void onLeScan(final BluetoothDevice device, final int rssi, final byte[] scanRecord)

никогда не вызывается даже при 3 активных маяках BLE рядом с телефоном..

Чего мне не хватает?

Собственный подключаемый модуль Unity:

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.widget.Toast;

import com.unity3d.player.UnityPlayer;
import com.unity3d.player.UnityPlayerActivity;

public class MainActivity extends UnityPlayerActivity {

protected static final String LOG_TAG = "Blutooth";
private BluetoothManager btManager;
private BluetoothAdapter btAdapter;
private Handler scanHandler = new Handler();
private int scan_interval_ms = 6000;
private boolean isScanning = false;
public static Context ctx;

private boolean AllowedScanning = false;

public String UUID = null;
public String BLEUUID = null;
public String Major = null;
public String Minor = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    ctx = this;
    // init BLE
    btManager = (BluetoothManager)getSystemService(Context.BLUETOOTH_SERVICE);
    btAdapter = btManager.getAdapter();

    //scanHandler.post(scanRunnable);


}

 public void startBLEScan(){
     Log.i("test","-----------------test_from_Android_PlugIn");
     AllowedScanning = true;
     scanHandler.post(scanRunnable);
     Toast.makeText(MainActivity.this, 
                "startBLEScan", Toast.LENGTH_LONG).show();

 }



private BluetoothAdapter.LeScanCallback leScanCallback = new BluetoothAdapter.LeScanCallback()
{
    @Override
    public void onLeScan(final BluetoothDevice device, final int rssi, final byte[] scanRecord)
    {
        Toast.makeText(MainActivity.this, "leScanCallback... ", Toast.LENGTH_LONG).show();
        int startByte = 2;
        boolean patternFound = false;
        while (startByte <= 5)
        {
            if (    ((int) scanRecord[startByte + 2] & 0xff) == 0x02 && //Identifies an iBeacon
                    ((int) scanRecord[startByte + 3] & 0xff) == 0x15)
            { //Identifies correct data length
                patternFound = true;
                break;
            }
            startByte++;
        }

        if (patternFound)
        {
            //Convert to hex String
            byte[] uuidBytes = new byte[16];
            System.arraycopy(scanRecord, startByte + 4, uuidBytes, 0, 16);
            String hexString = bytesToHex(uuidBytes);

            //UUID detection
            String uuid =  hexString.substring(0,8) + "-" +
                    hexString.substring(8,12) + "-" +
                    hexString.substring(12,16) + "-" +
                    hexString.substring(16,20) + "-" +
                    hexString.substring(20,32);

            // major
            final int major = (scanRecord[startByte + 20] & 0xff) * 0x100 + (scanRecord[startByte + 21] & 0xff);

            // minor
            final int minor = (scanRecord[startByte + 22] & 0xff) * 0x100 + (scanRecord[startByte + 23] & 0xff);

            Log.i(LOG_TAG,"UUID: " +uuid + "\\nmajor: " +major +"\\nminor" +minor);

            UUID = uuid.toString();
            BLEUUID = uuid.toString();
            Major = String.valueOf(major);
            Minor = String.valueOf(minor);

            Toast.makeText(MainActivity.this, 
                    "UUID  " + UUID, Toast.LENGTH_LONG).show();
        }

    }
};

static final char[] hexArray = "0123456789ABCDEF".toCharArray();
private static String bytesToHex(byte[] bytes) {
    char[] hexChars = new char[bytes.length * 2];
    for ( int j = 0; j < bytes.length; j++ ) {
        int v = bytes[j] & 0xFF;
        hexChars[j * 2] = hexArray[v >>> 4];
        hexChars[j * 2 + 1] = hexArray[v & 0x0F];
    }
    return new String(hexChars);
}

private Runnable scanRunnable = new Runnable()
{
    @SuppressWarnings("deprecation")
    @Override
    public void run() {

        if (isScanning)
        {
            if (btAdapter != null)
            {
                btAdapter.stopLeScan(leScanCallback);
            }
        }
        else
        {
            if (btAdapter != null)
            {
                btAdapter.startLeScan(leScanCallback);
                Toast.makeText(MainActivity.this, "Scanning... ", Toast.LENGTH_LONG).show();
            }
        }

        isScanning = !isScanning;

        scanHandler.postDelayed(this, scan_interval_ms);

        if (UUID != null) {
            onStop();
            Toast.makeText(MainActivity.this, "UUID  " + UUID, Toast.LENGTH_LONG).show();
            //BLEReturn(UUID);
        } else { Toast.makeText(MainActivity.this,"No beacon found ", Toast.LENGTH_LONG).show();    

    }
    }

};

protected void onStop() {
    super.onStop();
    scanHandler.removeCallbacks(scanRunnable);
}

}

Автономная версия, которая работает нормально, показывает 3 UUID 3 BLEмаяки возле телефона:

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;

public class MainActivity extends Activity {

protected static final String LOG_TAG = "Blutooth";
private BluetoothManager btManager;
private BluetoothAdapter btAdapter;
private Handler scanHandler = new Handler();
private int scan_interval_ms = 5000;
private boolean isScanning = false;
private TextView txtDisplay1;
public String UUID = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    txtDisplay1 = (TextView) findViewById(R.id.textView1);
    // init BLE
    btManager = (BluetoothManager)getSystemService(Context.BLUETOOTH_SERVICE);
    btAdapter = btManager.getAdapter();

    scanHandler.post(scanRunnable);


}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();
    if (id == R.id.action_settings) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}

private BluetoothAdapter.LeScanCallback leScanCallback = new BluetoothAdapter.LeScanCallback()
{
    @Override
    public void onLeScan(final BluetoothDevice device, final int rssi, final byte[] scanRecord)
    {
        int startByte = 2;
        boolean patternFound = false;
        while (startByte <= 5)
        {
            if (    ((int) scanRecord[startByte + 2] & 0xff) == 0x02 && //Identifies an iBeacon
                    ((int) scanRecord[startByte + 3] & 0xff) == 0x15)
            { //Identifies correct data length
                patternFound = true;
                break;
            }
            startByte++;
        }

        if (patternFound)
        {
            //Convert to hex String
            byte[] uuidBytes = new byte[16];
            System.arraycopy(scanRecord, startByte + 4, uuidBytes, 0, 16);
            String hexString = bytesToHex(uuidBytes);

            //UUID detection
            String uuid =  hexString.substring(0,8) + "-" +
                    hexString.substring(8,12) + "-" +
                    hexString.substring(12,16) + "-" +
                    hexString.substring(16,20) + "-" +
                    hexString.substring(20,32);

            // major
            final int major = (scanRecord[startByte + 20] & 0xff) * 0x100 + (scanRecord[startByte + 21] & 0xff);

            // minor
            final int minor = (scanRecord[startByte + 22] & 0xff) * 0x100 + (scanRecord[startByte + 23] & 0xff);

            Log.i(LOG_TAG,"UUID: " +uuid + "\\nmajor: " +major +"\\nminor" +minor);
            txtDisplay1.setText("UUID: " +uuid + "\\nmajor: " +major +"\\nminor" +minor);
            UUID = uuid.toString();
        }

    }
};

static final char[] hexArray = "0123456789ABCDEF".toCharArray();
private static String bytesToHex(byte[] bytes) {
    char[] hexChars = new char[bytes.length * 2];
    for ( int j = 0; j < bytes.length; j++ ) {
        int v = bytes[j] & 0xFF;
        hexChars[j * 2] = hexArray[v >>> 4];
        hexChars[j * 2 + 1] = hexArray[v & 0x0F];
    }
    return new String(hexChars);
}

private Runnable scanRunnable = new Runnable()
{
    @SuppressWarnings("deprecation")
    @Override
    public void run() {

        if (isScanning)
        {
            if (btAdapter != null)
            {
                btAdapter.stopLeScan(leScanCallback);
            }
        }
        else
        {
            if (btAdapter != null)
            {
                btAdapter.startLeScan(leScanCallback);
            }
        }

        isScanning = !isScanning;

        scanHandler.postDelayed(this, scan_interval_ms);

        if (UUID != null) {
            onStop();
            txtDisplay1.setText("Terminated, beacon found !");
        } else { txtDisplay1.setText("Beacon not found");}

    }

};

protected void onStop() {
    super.onStop();
    scanHandler.removeCallbacks(scanRunnable);
}

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...