TheAptKid
TheAptKid

Reputation: 1571

Calling a method from another class in broadcast receiver

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

Answers (2)

donison24x7
donison24x7

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

Joan S.
Joan S.

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

Related Questions