Android Java callback null inside broadcastReceiver - java

I'm trying to get notification when Android receives a text message, so I wrote a new class for that like this:
public class MyBroadcastReceiver extends BroadcastReceiver {
public MyBroadcastCallback callback;
public MyBroadcastReceiver() {}
public MyBroadcastReceiver(MyBroadcastCallback callback) {
this.callback=callback;
Log.d("myTag", "MyBroadcastReceiver CONSTRUCTOR.... "+this.callback);
this.callback.OnReceiveSMS("phone TEST","message TEST");
}
#Override
public void onReceive(Context context, Intent intent) {
Bundle intentExtras = intent.getExtras();
if (intentExtras != null) {
Object[] sms = (Object[]) intentExtras.get("pdus");
for (int i = 0; i < sms.length; ++i) {
SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) sms[i]);
String phone = smsMessage.getOriginatingAddress();
String message = smsMessage.getMessageBody().toString();
this.callback.OnReceiveSMS(phone,message);
}
}
}
public interface MyBroadcastCallback {
void OnReceiveSMS(String phone,String message);
}
}
Then in my main activity I instantiate the class like this:
public class MainActivity extends AppCompatActivity implements MyBroadcastReceiver.MyBroadcastCallback {
MyBroadcastReceiver broadcastReceiver=null;
#Override
protected void onCreate(Bundle savedInstanceState) {
....
super.onCreate(savedInstanceState);
broadcastReceiver=new MyBroadcastReceiver(this);
....
}
#Override
public void OnReceiveSMS(String phone, String message) {
Log.d("myTag", "NEW SMS MESSAGE PHONE="+phone + " message="+message);
}
}
The Android manifest looks like this:
<receiver android:name=".MyBroadcastReceiver">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
When a text is received, OnReceive is called in the MyBroadCastReceiver class, that works great.
But when I try to call my own callback function inside OnReceive() to notify the main activity of the text message like this:
this.callback.OnReceiveSMS(phone, message);
It crashes with exception that this.callback is null.
I know it's not null in the beginning because in the constructor I pass in the main activity which implements that interface.
To debug I also printed out this.callback in the constructor and even called that function in there to make sure its not null, and all that works, but somehow it BECOMES null when a text comes in and Android OS calls OnReceive.
Does anybody knows why it's null? How to fix?

Related

interface cannot be cast (ClassCastException: AlarmReceiver cannot be cast to AlarmReceiver$OnAlarmOver)

I created a alarm and I hope when alarm is stop can set a String to TextView in MainActivity so I try to use interface but it's get error :
Caused by: java.lang.ClassCastException: AlarmReceiver cannot be cast to AlarmReceiver$OnAlarmOver
AlarmReceiver.java
public class AlarmReceiver extends BroadcastReceiver {
public AlarmReceiver() {
}
#Override
public void onReceive(Context context, Intent intent) {
...
OnAlarmOver onAlarmOver = (OnAlarmOver) context; //<--error
onAlarmOver.OnAlarmOverText("Alarm stop");
}
public interface OnAlarmOver {
public void OnAlarmOverText(String overText);
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity implements AlarmReceiver.OnAlarmOver {
...
public void OnAlarmOverText(String overText){
alarm_text.setText(overText);
}
}
My English is very poor, sorry.
You are trying to cast the context to OnAlarmOver. Of course, this is not going to work. I think you want to capture a broadcast emit somewhere else inside of your app.
1) You need to define your broadcast. Then, in your activity, you should register it. For example:
private BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
if (bundle != null) {
if(intent.getAction().equals(SearchService.NOTIFICATION)){
}
}
}
};
#Override
protected void onResume() {
super.onResume();
registerReceiver(receiver, new IntentFilter(SearchService.NOTIFICATION));
}
Remember to unregister in the pause method
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(receiver);
}
2) You need to create an Intent and the send the broadcast like this.
private void publishResults(Search result) {
Intent intent = new Intent(NOTIFICATION);
intent.putExtra(RESULT, result);
sendBroadcast(intent);
success = true;
}
To sum up, I don't know why you want to use an interface (listener) for this if it is is provided by Android. Maybe, you should explain a little more what do you want to do. I hope this answer can help you.

Android BroadcastReceiver inside service: issues

I am currently trying to create an Activity in Android with the capabilities of communicating with a started BroadcastReceiver inside of a service but I can't manage to do it well. I don't really know what the problem could be since (I think) I have followed all necessary steps.
In addition, I have other Activities which can communicate with this BroadcastReceiver without any problems. The code that I am using for the one I am having problems with is the following:
Registration of the name of the action in file ActivityList.java (Another activity):
public static final String ACTION1 = "com.test.ActionOne";
public static final String ACTION2 = "com.test.ActionTwo";
Registration of the actions with IntentFilter in the file GestTree.java which extends a Service:
Inside onCreate():
IntentFilter filter;
filter = new IntentFilter();
filter.addAction(ActivityList.ACTION1);
filter.addAction(ActivityList.ACTION2);
rec = new Receptor(); // This is a class which extends BroadcastReceiver
registerReceiver(receptor, filter);
Inside the function onReceive() of the private class Receptor of GestTree.java which extends BroadcastReceiver:
public final void onReceive(final Context context, final Intent intent) {
String action = intent.getAction();
if (action.equals(ActivityList.ACTION1)) {
Log.d(tag, "Test Passed!");
}
}
The definition of the service and the Activity State3Activity(the one I want to communicate with the service) in AndroidManifest.xml:
<activity
android:name="State3Activity"
android:label="#string/app_name" >
</activity>
<service
android:name="GestTree"
android:enabled="true"
android:label="#string/app_name" >
</service>
Code inside State3Activity.java:
public class State3Activity extends Activity {
Button mButton;
EditText editText_Name;
EditText editText_Desc;
private final String tag = this.getClass().getSimpleName();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.state3_layout);
mButton = (Button)findViewById(R.id.button_myButton);
editText_Nombre = (EditText)findViewById(R.id.editText_Name);
editText_Descripcion = (EditText)findViewById(R.id.editText_Desc);
mButton.setOnClickListener(
new View.OnClickListener()
{
public void onClick(View view)
{
Intent intent;
intent = new Intent();
intent.setAction(ActivityList.ACTION1);
// I have tried with all this combination of lines
// but none of them works
//intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
//intent.setClass(State3Activity.this, GestTree.class);
//intent.addCategory(Intent.CATEGORY_DEFAULT);
sendBroadcast(intent);
}
});
}
There is where the problem comes. The intent never enters on the onReceive() function of the class when I press the button. What am I leaving?
Are you sure your service started? If you have not start the service, the method of onCreate() will not be executed, and the receiver will not be registed.

Getting output from second activity class to first activity which is invokes by the first activity

My code has two activities.
public class OnCallingActivity extends Activity implement TextToSpeech.OnInitListener{}
public class TextReceiverActivity extends BroadcastReceiver{}
i want first activity to extend sencond activity
OnCallingActivity extends TextReceiverActivity {}
so I did this,
public class OnCallingActivity extends Activity implements TextToSpeech.OnInitListener {
private TextReceiverActivity TextReceiverActivityClass;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.on_calling_layout);
TextReceiverActivityClass= new TextReceiverActivity();
speaker= new TextToSpeech(this, this);
callerIdText=(TextView)findViewById(R.id.callerIdtextview);
callerText=(TextView)findViewById(R.id.callermsgtextview);
translatedText=(TextView)findViewById(R.id.translatedTextview);
speakButton=(ImageButton)findViewById(R.id.btnSpeak);
sendButton=(Button)findViewById(R.id.buttonsend);
endCallButton=(ImageButton)findViewById(R.id.buttonendCall);
}
my second activity is as follow,
public class TextReceiverActivity extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
number ="";
message="";
final Bundle bundle = intent.getExtras();
try {
if(bundle != null) {
final Object[] pduObjects = (Object[]) bundle.get("pdus");
for(int i = 0; i < pduObjects.length; ++i) {
SmsMessage currentMessage = SmsMessage.createFromPdu((byte[]) pduObjects[i]);
number = currentMessage.getDisplayOriginatingAddress();
message = currentMessage.getDisplayMessageBody();
Toast.makeText(context, "SENDER NUMBER: " + number + "; MESSAGE: " + message, Toast.LENGTH_LONG).show();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
in first activity i called the method of second activity like this
public void onReceive(Context context, Intent intent) {
TextReceiverActivityClass.onReceive(context, intent);
}
onReceive gives values for number and message..so how can i get them to my first activity to display them in TextViews.
onReceive is an inbuilt method so i can't change the return type.
If TextReceiverActivity extends BroadcastReceiver, then TextReceiverActivity isnt an Activity and I would refrain from calling it an Activity.
The onReceive method of a BroadcastReceiver is meant to be called from the Android sytem, not you.
To send a message from an Activity to a BroadcastReceiver you would send a Broadcast. See the docs.
If you want to send a message from your BroadcastReceiver to your Activity, there's a couple of questions about that.

Android receive a broadcast in ActionBarActivity

I have got an action bar activity with a LocalBroadcastManager defined exactly like in the answer here, except the only difference is that it is defined in an ActionBarActivity.
For some reason, no matter what I try I can't manage to get to the receiver's onReceive (i.e. successfuly receiving broadcast message).
Service code:
public class GcmIntentService extends IntentService {
#Override
protected void onHandleIntent(Intent intent) {
Intent toDrawerActivity = new Intent(syncActionName);
String syncType = extras.getString("data");
toDrawerActivity.putExtra("syncType", syncType);
System.out.println("sending intent in service");
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
}
And the activity code:
public class DrawerActivity extends ActionBarActivity {
private BroadcastReceiver dataUpdaterReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
System.out.println("in broadcast receiver");
}
};
protected void onCreate(){
...
...
LocalBroadcastManager.getInstance(this).registerReceiver(dataUpdaterReceiver,
new IntentFilter(GcmIntentService.syncActionName));
}
protected void onDestroy(){
LocalBroadcastManager.getInstance(this).unregisterReceiver(dataUpdaterReceiver);
}
}
What exactly am I doing wrong here?
Your have that problem due to you used the wrong parameter for sendBroadcast() method:
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
It should be:
LocalBroadcastManager.getInstance(this).sendBroadcast(toDrawerActivity);

about broadcast receiver

Hi all I want to create an application in which there is an activity say My activity. Now I want to start it with incoming call, if it is not answered within 20 seconds.Please Help me.
You would first need to register your receiver such as..
<receiver android:name=".CustomBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
Here you register to listen for the phones state to change.
Next you would want to extend the phonestateListener for your specifications.
public class CustomPhoneStateListener extends PhoneStateListener {
private static final String TAG = "CustomPhoneStateListener";
public void onCallStateChange(int state, String incomingNumber){
//Here you recieve the phone state being changed and are able to get the number and state.
switch(state){
case TelephonyManager.CALL_STATE_RINGING:
Log.d(TAG, "RINGING");
//Here you could count with for() for 20 seconds and then create a method to do what you want.
break;
Here you create your BroadCastReceiver...
public class CustomBroadcastReceiver extends BroadcastReceiver {
private static final String TAG = "CustomBroadcastReceiver";
#Override
public void onReceive(Context context, Intent intent) {
Log.v(TAG, "inside");
TelephonyManager telephony = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
CustomPhoneStateListener customPhoneListener = new CustomPhoneStateListener();
telephony.listen(customPhoneListener, PhoneStateListener.LISTEN_CALL_STATE);
Bundle bundle = intent.getExtras();
String phoneNr= bundle.getString("incoming_number");
Log.v(TAG, "phoneNr: "+phoneNr);
}
EDIT:
To count you could create a method such as
public void increment() {
if (count < maxCount) count++;
}

Categories

Resources