Reputation: 1571
I'm working on a project which consists of two classes. The first, MainActivity.java, deals with sending a single char over a bluetooth connection. The second, SmsReceiver.java, is a broadcast reciver for detecting incoming sms messages. When SmsReceiver.java detects an incoming message it should call the method turnLedOn, which resides in the bluetooth class.
I've tested both of them and they work. Then I tried connecting them by calling MainActivity.turnLedOn(context);
in the onReceive
method of the broadcast receiver, but it didn't work.
Does anybody know why and what should be done to remedy this? Below is the code of the whole project.
Thank you in advance.
MainActivity.java
package com.example.bluetooth;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Set;
import java.util.UUID;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends Activity {
//You first have to connect with your android phone to the arduino bt module.
BluetoothAdapter mBluetoothAdapter = null;
ConnectThread mConnectThread = null;
BluetoothDevice mDevice = null;
public static ConnectedThread mConnectedThread = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Button button = (Button) findViewById(R.id.button1);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
mConnectedThread.write("1".getBytes());
}
});
final Button button2 = (Button) findViewById(R.id.button2);
button2.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
mConnectedThread.write("0".getBytes());
}
});
BluetoothDevice mDevice = null;
//Check if phone supports bluetooth
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null) {
// Device does not support Bluetooth
}
Toast.makeText(this, "BT supported", Toast.LENGTH_SHORT).show();
Log.e("BLUETOOTH", "BT supported");
// Check if bluetooth is enabled. If not, enable it.
if (!mBluetoothAdapter.isEnabled()) {
Toast.makeText(this, "BT disabled", Toast.LENGTH_SHORT).show();
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, 1);
}
Toast.makeText(this, "BT enabled", Toast.LENGTH_SHORT).show();
Log.e("BLUETOOTH", "BT enabled");
// Chech which device we connected with, at the beginning
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
Toast.makeText(this, "Paired with a BT device", Toast.LENGTH_SHORT).show();
Log.e("BLUETOOTH", "paired with a BT device");
for (BluetoothDevice device : pairedDevices) {
Toast.makeText(this, device.getName() + " " + device.getAddress(), Toast.LENGTH_SHORT).show();
mDevice = device;
}
}
// Source 7 - Creating the connection thread
mConnectThread = new ConnectThread(mDevice);
mConnectThread.start();
}
public static void turnLedOn(Context context){
mConnectedThread.write("1".getBytes());
}
public static void turnLedOff(Context context){
mConnectedThread.write("0".getBytes());
}
@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;
}
//Thread which creates a connection between arduino and phone
private class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
private final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
public ConnectThread(BluetoothDevice device) {
BluetoothSocket tmp = null;
mmDevice = device;
try {
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) { }
mmSocket = tmp;
}
public void run() {
mBluetoothAdapter.cancelDiscovery();
try {
mmSocket.connect();
} catch (IOException connectException) {
try {
mmSocket.close();
} catch (IOException closeException) { }
return;
}
//Source 10 - create the data transfer thread
//Manage connection
mConnectedThread = new ConnectedThread(mmSocket);
mConnectedThread.start();
}
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}
// end of connection thread
//Thread for sending and receiving messages
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket) {
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
byte[] buffer = new byte[1024];
int begin = 0;
int bytes = 0;
while (true) {
try {
bytes += mmInStream.read(buffer, bytes, buffer.length
- bytes);
for (int i = begin; i < bytes; i++) {
if (buffer[i] == "#".getBytes()[0]) {
mHandler.obtainMessage(1, begin, i, buffer)
.sendToTarget();
begin = i + 1;
if (i == bytes - 1) {
bytes = 0;
begin = 0;
}
}
}
} catch (IOException e) {
break;
}
}
}
public void write(byte[] bytes) {
try {
mmOutStream.write(bytes);
} catch (IOException e) {
}
}
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
}
}
}
//End of thread for sending and receiving
//Source 9 - handler for sending
Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
byte[] writeBuf = (byte[]) msg.obj;
int begin = (int) msg.arg1;
int end = (int) msg.arg2;
switch (msg.what) {
case 1:
String writeMessage = new String(writeBuf);
writeMessage = writeMessage.substring(begin, end);
break;
}
}
};
}
SmsReceiver.java
package com.example.bluetooth;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.SmsMessage;
import android.widget.Toast;
public class SmsReceiver extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent)
{
//---get the SMS message passed in---
Bundle bundle = intent.getExtras();
SmsMessage[] msgs = null;
String messageReceived = "";
if (bundle != null)
{
//---retrieve the SMS message received---
Object[] pdus = (Object[]) bundle.get("pdus");
msgs = new SmsMessage[pdus.length];
for (int i=0; i<msgs.length; i++)
{
msgs[i] = SmsMessage.createFromPdu((byte[])pdus[i]);
messageReceived += msgs[i].getMessageBody().toString();
messageReceived += "\n";
}
//---display the new SMS message---
Toast.makeText(context, messageReceived, Toast.LENGTH_SHORT).show();
MainActivity.turnLedOn(context);
// Get the Sender Phone Number
String senderPhoneNumber=msgs[0].getOriginatingAddress ();
}
}
}
MainActivity layout
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" />
<Button
android:id="@+id/button1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/textView1"
android:layout_below="@+id/textView1"
android:layout_marginTop="34dp"
android:text="On" />
<Button
android:id="@+id/button2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/button1"
android:layout_below="@+id/button1"
android:layout_marginTop="68dp"
android:text="Off" />
</RelativeLayout>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.bluetooth"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<receiver android:name=".SmsReceiver">
<intent-filter>
<action android:name=
"android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
<activity
android:name="com.example.bluetooth.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission>
</manifest>
Edit: Registered the broadcast receiver in the manifest as @donison24x7 suggested.
Edit2: Sorry about this. Also added the RECEIVE_SMS permission in the manifest. It works now.
Upvotes: 1
Views: 4017
Reputation: 304
You havn't registered the Broadcast receiver 'SmsReceiver.java' in manifest. Register it like this.....
<receiver
android:name=".SmsReceiver" >
<intent-filter>
<action android:name="your.Action.name" />
</intent-filter>
</receiver>
Upvotes: 2
Reputation: 150
One possible solution is to use LocalBroadcastManager to communicate between your receiver class and your activity class:
Fire up an Intent in your receiver class in onReceive() with:
Intent i = new Intent("NameYourIntentHere");
LocalBroadcastManager.getInstance(context).sendBroadcast(i);
Get the LocalBroadcast intent in your Activity class:
private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// Do your stuff here
}
};
And register your LocalBroadcast receiver in your activity class so it gets notified:
@Override
protected void onPause() {
super.onPause();
LocalBroadcastManager.getInstance(this).unregisterReceiver(mBroadcastReceiver);
}
@Override
protected void onResume() {
super.onResume();
LocalBroadcastManager.getInstance(this).registerReceiver(mBroadcastReceiver,
new IntentFilter("NameYourIntentHere"));
}
Upvotes: 1