1

I have been toiling over an application that I am hoping will be able to send information from an Android phone to my Raspberry Pi 3, via Bluetooth. I have put together code from various similar projects. I have a main activity in which I simply have a Title and a start button. The press of the button starts the 2nd activity, which is a simple side by side webView, which will be used to view 2 web pages that house separate video streams (this app will be used for a VR Headset). Within that 2nd activity, I would like to read the phone's accelerometer measurements and send it over serial to the Pi, where I have a Python client script to handle the input (for now just simply reading and printing).

Here's my class to handle the Bluetooth connection:

package com.example.jbooda21.sdvideostream;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;

import java.io.IOException;
import java.io.OutputStream;
import java.util.UUID;

/**
* Created by jbooda21 on 7/7/16.
*/
public class BluetoothSerial {

private BluetoothAdapter bluetoothAdapter;
private BluetoothDevice bluetoothDevice;
private BluetoothSocket bluetoothSocket;
private OutputStream outputStream;

private static final String DEVICE_MAC = "A0:B4:A5:07:1C:89";
private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

public void connectOK() {
    bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    bluetoothDevice = bluetoothAdapter.getRemoteDevice(DEVICE_MAC);
    try {
        bluetoothSocket = bluetoothDevice.createRfcommSocketToServiceRecord(MY_UUID);
        bluetoothSocket.connect();
        outputStream = bluetoothSocket.getOutputStream();
    } catch (NullPointerException | IOException e) {
        e.printStackTrace();
    }
}

public void disconnect() {
    try {
        if (outputStream != null) outputStream.close();
        if (bluetoothSocket != null) bluetoothSocket.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
    bluetoothDevice = null;
    bluetoothAdapter = null;
}

public void send(byte[] data) {
    try {
        outputStream.write(data);
    } catch (IOException e) {
        e.printStackTrace();
    }

}

private BluetoothDevice getDeviceByName(BluetoothAdapter adapter, String name) {
    for (BluetoothDevice device : adapter.getBondedDevices()) {
        String thisDevice = device.getName();
        if (name.matches(thisDevice)) {
            return device;
        }
    }
    return null;
  }

}

I have my MainActivity.java file that is, again, very basic:

package com.example.jbooda21.sdvideostream;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {

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

    Button startVideo = (Button) findViewById(R.id.StartButton);

    startVideo.setOnClickListener(new View.OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            Intent vid_request = new Intent (MainActivity.this, VideoStream.class);
            startActivity(vid_request);
        }

    });
  }
}

And I just stuck all of the sensor information handling, as well as the video streaming in one .java file:

package com.example.jbooda21.sdvideostream;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.webkit.WebView;
import android.content.Context;
import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.PowerManager;
import android.util.Log;
import java.nio.ByteBuffer;

public class VideoStream extends AppCompatActivity implements SensorEventListener {

private PowerManager.WakeLock mWakeLock;
private SensorManager mSensorManager;
protected static BluetoothSerial bluetoothSerial;

private boolean enabled;
private double xPos;
byte[] bytes = new byte[8];

private WebView leftVideo;
private WebView rightVideo;
private String l_url;
private String r_url;

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

    leftVideo = (WebView) findViewById(R.id.leftEye);
    rightVideo = (WebView) findViewById(R.id.rightEye);

    l_url = "https://www.raspberrypi.org";
    r_url = "https://www.raspberrypi.org";

    setUpEye(leftVideo, l_url);
    setUpEye(rightVideo, r_url);

}

@Override
protected void onDestroy() {
    super.onDestroy();
    leftVideo.destroy();
    rightVideo.destroy();
    stop();
}

private void setUpEye(WebView webView, String url)
{
    webView.getSettings().setJavaScriptEnabled(true);
    webView.getSettings().setAllowFileAccessFromFileURLs(true);
    webView.loadUrl(url);
}

/**
 * Set up the wake lock to keep the screen on for as long as the service is running
 */
private void setUpWakeLock() {
    PowerManager mPowerManager = (PowerManager) getSystemService(POWER_SERVICE);
    mWakeLock = mPowerManager.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "Test");
    mWakeLock.acquire();
}

private void startOK() {
    setUpWakeLock();
    setUpSensors();
    try {
        bluetoothSerial.connectOK();
        enabled = true;
    }catch (Exception e){
        e.printStackTrace();
        enabled = false;
    }
}

private void setUpSensors() {
    mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);

    Sensor accelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
    mSensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_FASTEST);
}

private void stop() {
    if (mSensorManager != null)
        mSensorManager.unregisterListener(this);

    if (mWakeLock != null)
        mWakeLock.release();

    if (bluetoothSerial != null)
        bluetoothSerial.disconnect();

    enabled = false;
}

@Override
public void onSensorChanged(SensorEvent event) {
    switch (event.sensor.getType()) {
        case Sensor.TYPE_ACCELEROMETER:
            xPos = event.values[0];
            ByteBuffer.wrap(bytes).putDouble(xPos);
            bluetoothSerial.send(bytes);
            break;

        case Sensor.TYPE_GYROSCOPE:
            break;

        case Sensor.TYPE_MAGNETIC_FIELD:
            break;
    }
}

@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
    Log.d("Test", "Sensor : " + sensor.getName());
    Log.d("Test", "Accuracy: " + accuracy);
}
}

Where I'm coming up short is, on my Pi, I run:

$ sudo rfcomm listen XX:XX:XX:XX:XX:XX 1

Which is the same command I run to listen for connection between the Bluetooth Terminal App from the play store, and it works just fine.

I've released the channel and re-run the listen before re-running my app on the phone I've been testing on. Still the Pi cannot get a connection from my application.

I'm not sure where I'm going wrong. Could anyone assist at all as I'm running out of self generated solutions.

Please and thank you all.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.