2017-08-02 7 views
0

ターゲットボード(マイクロコントローラ)に接続されたBLEデバイス(RN4020)と通信するアンドロイドアプリを開発しています。私はRN4020を介してターゲットボードにデータを送信することができ、UARTを通じて正常に受信したアプリを開発しました。しかし、ターゲットデバイスからアプリにデータを受け取ることができません。私はマイクロコントローラから1秒ごとにデータを送信しています。しかし、アプリケーションでは、MLDP端末は、プレイストアからダウンロードして同時にデータを送受信できます。BLEデバイスからアンドロイドアプリに連続してデータを読み取る方法は?

デバッグ中は、の文字コードには届きません。

デバイスからアプリにデータを受け取る方法は?通知を有効にするに

package com.example.designemb5.tempworking; 

import android.Manifest; 
    import android.app.AlertDialog; 
import android.bluetooth.BluetoothAdapter; 
import android.bluetooth.BluetoothDevice; 
import android.bluetooth.BluetoothGatt; 
import android.bluetooth.BluetoothGattCallback; 
import android.bluetooth.BluetoothGattCharacteristic; 
import android.bluetooth.BluetoothGattService; 
import android.bluetooth.BluetoothManager; 
import android.bluetooth.BluetoothProfile; 
import android.bluetooth.le.BluetoothLeScanner; 
import android.bluetooth.le.ScanCallback; 
import android.bluetooth.le.ScanResult; 
import android.content.Context; 
import android.content.DialogInterface; 
import android.content.Intent; 
import android.content.pm.PackageManager; 
import android.os.AsyncTask; 
import android.os.Build; 
import android.os.Bundle; 
import android.os.ParcelUuid; 
import android.support.annotation.RequiresApi; 
import android.support.v7.app.AppCompatActivity; 
import android.text.method.ScrollingMovementMethod; 
import android.util.Log; 
import android.view.View; 
import android.widget.Button; 
import android.widget.TextView; 
import android.widget.Toast; 

import java.util.List; 
import java.util.Map; 
import java.util.Timer; 
import java.util.TimerTask; 
import java.util.UUID; 

public class MainActivity extends AppCompatActivity { 

BluetoothManager btManager; 
BluetoothAdapter btAdapter; 
BluetoothLeScanner btScanner; 
BluetoothDevice mBluetoothDevice; 
public BluetoothAdapter mBluetoothAdapter; 
public BluetoothGatt mBluetoothGatt; 
public BluetoothGattService mBluetoothGattService; 
private int mConnectionState = STATE_DISCONNECTED; 
private BluetoothGattCharacteristic mWriteCharacteristic; 
private static final int STATE_DISCONNECTED = 0; 
private static final int STATE_CONNECTING = 1; 
private static final int STATE_CONNECTED = 2; 
Button startScanningButton; 
Button stopScanningButton; 
Button connectButton; 
Button disconnectButton; 
public boolean mConnected = false; 
public boolean mCharacteristics = true; 
private static final String TAG = "BLUETOOTH_LE"; 
public static List<ParcelUuid> MY_UUID; 
public final static String ACTION_GATT_CONNECTED = "com.example.designemb5.tempworking.ACTION_GATT_CONNECTED"; 
public final static String ACTION_GATT_DISCONNECTED = "com.example.designemb5.tempworking.ACTION_GATT_DISCONNECTED"; 
public final static String ACTION_GATT_SERVICES_DISCOVERED = "com.example.designemb5.tempworking.ACTION_GATT_SERVICES_DISCOVERED"; 
public final static String ACTION_DATA_AVAILABLE = "com.example.designemb5.tempworking.ACTION_DATA_AVAILABLE"; 
public final static String EXTRA_DATA = "com.example.designemb5.tempworking.EXTRA_DATA"; 

public final static UUID MY_UUID_RN4020_SERVICE = UUID.fromString("00035b03-58e6-07dd-021a-08123a000300"); 
public final static UUID MY_UUID_RN4020_CHARACTERISTIC_WRITE = UUID.fromString("00035b03-58e6-07dd-021a-08123a000301"); 
public final static UUID MY_UUID_RN4020_CHARACTERISTIC_READ = UUID.fromString("00035b03-58e6-07dd-021a-08123a0003ff"); 
TextView peripheralTextView; 
private final static int REQUEST_ENABLE_BT = 1; 
private static final int PERMISSION_REQUEST_COARSE_LOCATION = 1; 
public String mDeviceAddress; 
public int mTestVal = 1; 
public static Map<ParcelUuid, byte[]> mDeviceData; 
@RequiresApi(api = Build.VERSION_CODES.M) 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    connectButton = (Button) findViewById(R.id.ConnectButton); 
    disconnectButton = (Button) findViewById(R.id.disonnectButton); 

    peripheralTextView = (TextView) findViewById(R.id.PeripheralTextView); 
    peripheralTextView.setMovementMethod(new ScrollingMovementMethod()); 

    startScanningButton = (Button) findViewById(R.id.StartScanButton); 
    startScanningButton.setOnClickListener(new View.OnClickListener() { 
     public void onClick(View v) { 
      startScanning(); 
     } 
    }); 

    stopScanningButton = (Button) findViewById(R.id.StopScanButton); 
    stopScanningButton.setOnClickListener(new View.OnClickListener() { 
     public void onClick(View v) { 
      stopScanning(); 
     } 
    }); 
    stopScanningButton.setVisibility(View.INVISIBLE); 

    btManager = (BluetoothManager)getSystemService(Context.BLUETOOTH_SERVICE); 
    btAdapter = btManager.getAdapter(); 
    btScanner = btAdapter.getBluetoothLeScanner(); 



    if (btAdapter != null && !btAdapter.isEnabled()) { 
     Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); 
     startActivityForResult(enableIntent,REQUEST_ENABLE_BT); 
    } 


    // Make sure we have access coarse location enabled, if not, prompt the user to enable it 
    if (this.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 
     final AlertDialog.Builder builder = new AlertDialog.Builder(this); 
     builder.setTitle("This app needs location access"); 
     builder.setMessage("Please grant location access so this app can detect peripherals."); 
     builder.setPositiveButton(android.R.string.ok, null); 
     builder.setOnDismissListener(new DialogInterface.OnDismissListener() { 
      @Override 
      public void onDismiss(DialogInterface dialog) { 
       requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_COARSE_LOCATION); 
      } 
     }); 
     builder.show(); 
    } 
} 


public void startScanning() { 
    System.out.println("start scanning"); 
    peripheralTextView.setText(""); 
    startScanningButton.setVisibility(View.INVISIBLE); 
    stopScanningButton.setVisibility(View.VISIBLE); 
    AsyncTask.execute(new Runnable() { 
     @Override 
     public void run() { 
      btScanner.startScan(leScanCallback); 
     } 
    }); 
} 

public void stopScanning() { 
    System.out.println("stopping scanning"); 
    peripheralTextView.append("Stopped Scanning"); 
    startScanningButton.setVisibility(View.VISIBLE); 
    stopScanningButton.setVisibility(View.INVISIBLE); 
    AsyncTask.execute(new Runnable() { 
     @Override 
     public void run() { 
      btScanner.stopScan(leScanCallback); 
     } 
    }); 
} 

public void connect(View view) { 
    connectButton.setVisibility(View.INVISIBLE); 
    disconnectButton.setVisibility(View.VISIBLE); 

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

    final BluetoothDevice device = btAdapter 
      .getRemoteDevice(mDeviceAddress); 
    mBluetoothGatt = device.connectGatt(this, false, mGattCallback); 
} 

public void disconnect(View view) { 
    connectButton.setVisibility(View.VISIBLE); 
    disconnectButton.setVisibility(View.INVISIBLE); 
    mBluetoothGatt.disconnect(); 
} 

public void senddata(View view) { 
    { 
     int value = 0x01; 
     if (mBluetoothAdapter == null || mBluetoothGatt == null) { 
      Log.w(TAG, "BluetoothAdapter not initialized"); 
      return; 
     } 
    /*check if the service is available on the device*/ 
     BluetoothGattService mCustomService = mBluetoothGatt.getService(MY_UUID_RN4020_SERVICE); 
     if (mCustomService == null) { 
      Log.w(TAG, "Custom BLE Service not found"); 
      return; 
     } 
    /*get the read characteristic from the service*/ 
     BluetoothGattCharacteristic mWriteCharacteristic = mCustomService.getCharacteristic(MY_UUID_RN4020_CHARACTERISTIC_WRITE); 
     mWriteCharacteristic.setValue(value, BluetoothGattCharacteristic.FORMAT_UINT8, 0); 
     if (mBluetoothGatt.writeCharacteristic(mWriteCharacteristic) == false) { 
      Log.w(TAG, "Failed to write characteristic"); 
     } 
    } 
} 

public void receivedata(View view) { 
    { 
     if (mBluetoothAdapter == null || mBluetoothGatt == null) { 
      Log.w(TAG, "BluetoothAdapter not initialized"); 
      return; 
     } 
    /*check if the service is available on the device*/ 
     BluetoothGattService mCustomService = mBluetoothGatt.getService(MY_UUID_RN4020_SERVICE); 
     if (mCustomService == null) { 
      Log.w(TAG, "Custom BLE Service not found"); 
      return; 
     } 

     BluetoothGattCharacteristic mReadCharacteristic = mCustomService.getCharacteristic(MY_UUID_RN4020_CHARACTERISTIC_READ); 
     if (mBluetoothGatt.readCharacteristic(mReadCharacteristic) == false) { 
      Log.w(TAG, "Failed to read characteristic"); 
     } 
     mBluetoothGatt.readCharacteristic(mReadCharacteristic); 
    } 
} 

// Device scan callback. 
private ScanCallback leScanCallback = new ScanCallback() { 
    @Override 
    public void onScanResult(int callbackType, ScanResult result) { 
     processResult(result); 
    } 

    private void processResult(ScanResult result){ 
     mBluetoothDevice = result.getDevice(); 
     mDeviceAddress = result.getDevice().getAddress(); 
     mDeviceData = result.getScanRecord().getServiceData(); 
     MY_UUID = result.getScanRecord().getServiceUuids(); 
     peripheralTextView.append("Device Name: " + mDeviceAddress + "\n"); 
     stopScanning(); 
    } 
}; 

private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { 

    @Override 
    public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { 
     super.onCharacteristicWrite(gatt, characteristic, status); 
//   updateStatus(characteristic); 
     Log.e("gatt", "writeChar"); 
    } 

    @Override 
    public void onConnectionStateChange(BluetoothGatt gatt, int status, 
             int newState) { 
     String intentAction; 
     if (newState == BluetoothProfile.STATE_CONNECTED) { 
      intentAction = ACTION_GATT_CONNECTED; 
      mConnectionState = STATE_CONNECTED; 
      broadcastUpdate(intentAction); 
      Log.i(TAG, "Connected to GATT server."); 
      // Attempts to discover services after successful connection. 
      Log.i(TAG, "Attempting to start service discovery:" 
        + mBluetoothGatt.discoverServices()); 
      TimerTask task = new TimerTask() { 
       @Override 
       public void run() { 
        if (mBluetoothGatt != null) 
         mBluetoothGatt.readRemoteRssi(); 
       } 
      }; 
      Timer mRssiTimer = new Timer(); 
      mRssiTimer.schedule(task, 1000, 1000); 

     } else if (newState == BluetoothProfile.STATE_DISCONNECTED) { 
      intentAction = ACTION_GATT_DISCONNECTED; 
      mConnectionState = STATE_DISCONNECTED; 

      Log.i(TAG, "Disconnected from GATT server."); 
      broadcastUpdate(intentAction); 
     } 
    } 

    @Override 
    public void onServicesDiscovered(BluetoothGatt gatt, int status) { 

     if (status == BluetoothGatt.GATT_SUCCESS) { 
      broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED); 
     } else { 
      Log.w(TAG, "onServicesDiscovered received: " + status); 
     } 

     BluetoothGattService mCustomService = mBluetoothGatt.getService(MY_UUID_RN4020_SERVICE); 

     BluetoothGattCharacteristic mReadCharacteristic = mCustomService.getCharacteristic(MY_UUID_RN4020_CHARACTERISTIC_READ); 

     gatt.readCharacteristic(mReadCharacteristic); 
     gatt.setCharacteristicNotification(mReadCharacteristic, true); 
    } 

    @Override 
    public void onCharacteristicRead(BluetoothGatt gatt, 
            BluetoothGattCharacteristic characteristic, int status) { 
     if (status == BluetoothGatt.GATT_SUCCESS) { 
      gatt.readCharacteristic(characteristic); 
      broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic); 
     } 
    } 

    @Override 
    public void onCharacteristicChanged(BluetoothGatt gatt, 
             BluetoothGattCharacteristic characteristic) { 
     broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic); 
    } 

}; 

@Override 
public void onRequestPermissionsResult(int requestCode, 
             String permissions[], int[] grantResults) { 
    switch (requestCode) { 
     case PERMISSION_REQUEST_COARSE_LOCATION: { 
      if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { 
       System.out.println("coarse location permission granted"); 
      } else { 
       final AlertDialog.Builder builder = new AlertDialog.Builder(this); 
       builder.setTitle("Functionality limited"); 
       builder.setMessage("Since location access has not been granted, this app will not be able to discover beacons when in the background."); 
       builder.setPositiveButton(android.R.string.ok, null); 
       builder.setOnDismissListener(new DialogInterface.OnDismissListener() { 

        @Override 
        public void onDismiss(DialogInterface dialog) { 
        } 

       }); 
       builder.show(); 
      } 
      return; 
     } 
    } 
} 

public void writeCharacteristic(BluetoothGattCharacteristic characteristic) { 
    mBluetoothGatt.writeCharacteristic(characteristic); 
} 


private void broadcastUpdate(final String action) { 
    final Intent intent = new Intent(action); 
    sendBroadcast(intent); 
} 

private void broadcastUpdate(final String action, 
          final BluetoothGattCharacteristic characteristic) { 
    final Intent intent = new Intent(action); 

    // This is special handling for the Heart Rate Measurement profile. Data 
    // parsing is 
    // carried out as per profile specifications: 
    // http://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.heart_rate_measurement.xml 
    /* if (UUID_HEART_RATE_MEASUREMENT.equals(characteristic.getUuid())) { 
     int flag = characteristic.getProperties(); 
     int format = -1; 
     if ((flag & 0x01) != 0) { 
      format = BluetoothGattCharacteristic.FORMAT_UINT16; 
      Log.d(TAG, "Heart rate format UINT16."); 
     } else { 
      format = BluetoothGattCharacteristic.FORMAT_UINT8; 
      Log.d(TAG, "Heart rate format UINT8."); 
     } 
     final int heartRate = characteristic.getIntValue(format, 1); 
     Log.d(TAG, String.format("Received heart rate: %d", heartRate)); 
     intent.putExtra(EXTRA_DATA, String.valueOf(heartRate)); 
    } else { 
     // For all other profiles, writes the data formatted in HEX. 
     final byte[] data = characteristic.getValue(); 
     if (data != null && data.length > 0) { 
      final StringBuilder stringBuilder = new StringBuilder(
        data.length); 
      for (byte byteChar : data) 
       stringBuilder.append(String.format("%02X ", byteChar)); 
      intent.putExtra(EXTRA_DATA, new String(data) + "\n" 
        + stringBuilder.toString()); 
     } 
    }*/ 


    final byte[] data = characteristic.getValue(); 

    Log.v(TAG, "data.length: " + data.length); 

    if (data != null && data.length > 0) { 
     final StringBuilder stringBuilder = new StringBuilder(data.length); 
     for(byte byteChar : data) { 
      stringBuilder.append(String.format("%02X ", byteChar)); 

      Log.v(TAG, String.format("%02X ", byteChar)); 
     } 
     intent.putExtra(EXTRA_DATA, new String(data) + "\n" + stringBuilder.toString()); 
    } 

    sendBroadcast(intent); 
} 



private void showMessage(String str){ 
    Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT).show(); 
} 

} 
+0

データを継続的に受信したい場合は、何度も何度も繰り返し読み込むのではなく、通知を有効にする必要があります。 – Emil

+0

私はこれを初めて知ったので、データを受け取るための通知を有効にする方法はありません。あなたは私にその事例を教えてもらえますか? –

答えて

0

その後、
gatt.setCharacteristicNotification(yourCharacteristic, true); 



BluetoothGattDescriptor desc = yourCharacteristic.getDescriptor(UUID); 

desc.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); 
gatt.writeDescriptor(desc); 

これを実行した後、onCharacteristicChanged()は、データが送信されるたびに呼び出されなければなりません。 onDescriptorWrite()メソッドをオーバーライドして、通知を有効にしたことを確認します。

+0

記述子のUUIDは、クライアント特性設定記述子(00002902-0000-1000-8000-00805F9B34FB)のBluetooth SIG定義のものでなければなりません。 – Emil

+0

@エミールああ、あなたはそれを認識してくれてありがとう! –

関連する問題