Receiving a notification in NotificationReceiver class that includes my data string. However, when trying to pass that string to a class in MainActivity I'm not getting any data. No errors either.
NotificationReceiver
#Override
public void onReceive(Context context, AppNotification notification) {
Toast.makeText(context, notification.payload, Toast.LENGTH_SHORT).show();
if (notification.appEvent.equals(NOTIFICATION_ACTION)) {
Intent intent = new Intent(context, MainActivity.class);
intent.putExtra("orderId", notification.payload);
context.startActivity(intent);
}
}
MainActivity
public void onNewIntent(Intent intent) {
Toast.makeText(mContext, "Hitting New Intent", Toast.LENGTH_SHORT).show();
}
protected void onHandleIntent(Intent intent) {
Toast.makeText(getApplicationContext(), "New Order Received!", Toast.LENGTH_LONG).show();
new OrderAsyncTask().execute(intent.getStringExtra("orderId"));
}
The expected result is to receive my string in either onHandleIntent or onNewIntent
UPDATED
MainActivity Class Example:
public class MainActivity extends Activity {
public final static String EXTRA_PAYLOAD = "payload";
public String orderId = null;
#SuppressLint("StaticFieldLeak")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = getIntent();
onNewIntent(intent.getStringExtra("orderId"));
}
#Override
protected void onResume() {
super.onResume();
Intent intent = getIntent();
onNewIntent(intent.getStringExtra("orderId"));
}
public void onNewIntent(String orderId) {
if(orderId != null) {
Toast.makeText(MainActivity.this, "List order " + orderId, Toast.LENGTH_LONG);
} else {
Toast.makeText(MainActivity.this, "Value is null", Toast.LENGTH_LONG);
}
}
}
The methods you are trying to get the caller intent on are not overridden from anything. I suggest you to try getting the intent and processing data on activity's onCreate method
Intent intent = getIntent();
new OrderAsyncTask().execute(intent.getStringExtra("orderId"));
Also suggest you to change
public String orderId = null;
into
public String mOrderId = null;
Or just remove it because it might get mixed up with other orderId variable on your
onHandleIntent(String orderId)
method
Edit: Since you want to pass data from notification receiver to your mainActivity while the activity is running, I would suggest you to register the receiver inside your MainActivity
Please see this link, example of such design with Clover SDK https://github.com/clover/clover-android-sdk/blob/master/clover-android-sdk-examples/src/main/java/com/clover/android/sdk/examples/AppNotificationTestActivity.java
From the code:
private String orderId;
private AppNotificationReceiver receiver = new
AppNotificationReceiver() {
#Override
public void onReceive(Context context, AppNotification notification) {
log("Received " + notification);
orderId = notification.payload();
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Register the receiver to your mainActivity
receiver.register(this);
}
#Override
protected void onDestroy() {
super.onDestroy();
receiver.unregister();
}
You can directly get orderId into your MainActivity like this
Related
I initialize the interface SMSListener in my MainActivity's onCreate but it is null in my overridden onReceive function. Am I incorrectly using the public interface variable in my onReceive? I have properly initialized the variable whenever I have tested it outside of the overridden function.
SmsReceiver:
public class SmsReceiver extends BroadcastReceiver {
public interface OnCustomReceiveSMS {
void OnReceiveSMS(String inNumber, String inText);
}
public OnCustomReceiveSMS SMSListener;
//constructor
public SmsReceiver(){
this.SMSListener = null;
}
//register sms listener
public void SetCustomEventListener(OnCustomReceiveSMS eventListener){
this.SMSListener = eventListener;
this.SMSListener.OnReceiveSMS("test1", "test2");
}
#Override
public void onReceive(Context context, Intent intent) {
//THIS IS ALWAYS FALSE EVEN AFTER INITIALIZED
if(this.SMSListener != null){
Toast.makeText(context, "SMSListener is NOT null", Toast.LENGTH_SHORT).show();
this.SMSListener.OnReceiveSMS("test3", "test4");
}else{
Toast.makeText(context, "SMSListener is NULL", Toast.LENGTH_SHORT).show();
}
}
}
MainActivity:
public class MainActivity extends AppCompatActivity {
SmsReceiver smsReceiverObj;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//initialize SMS receiver and register event listener
this.smsReceiverObj = new SmsReceiver();
this.smsReceiverObj.SetCustomEventListener(new SmsReceiver.OnCustomReceiveSMS() {
#Override
public void OnReceiveSMS(String inNumber, String inText) {
Toast.makeText(getApplicationContext(), "test event listener fired", Toast.LENGTH_SHORT).show();
}
});
}
}
The first test in SetCustomEventListener (test1, test2) works just fine immediately after initializing the interface variable. When I try using it in onReceive function later I always get the "SMSListener is NULL" debug message.
The problem might be a sticky broadcast, which will call onReceive method before you even setCustomEventListener, better way to do it is to initialize it in constructor
public class SmsReceiver extends BroadcastReceiver {
public interface OnCustomReceiveSMS {
void OnReceiveSMS(String inNumber, String inText);
}
public OnCustomReceiveSMS SMSListener;
//constructor
public SmsReceiver(OnCustomReceiveSMS eventListener){
this.SMSListener = eventListener;
this.SMSListener.OnReceiveSMS("test1", "test2");
}
#Override
public void onReceive(Context context, Intent intent) {
//THIS IS ALWAYS FALSE EVEN AFTER INITIALIZED
if(this.SMSListener != null){
Toast.makeText(context, "SMSListener is NOT null", Toast.LENGTH_SHORT).show();
this.SMSListener.OnReceiveSMS("test3", "test4");
}else{
Toast.makeText(context, "SMSListener is NULL", Toast.LENGTH_SHORT).show();
}
}
}
And in your activity
this.smsReceiverObj = new SmsReceiver(new SmsReceiver.OnCustomReceiveSMS() {
#Override
public void OnReceiveSMS(String inNumber, String inText) {
Toast.makeText(getApplicationContext(), "test event listener fired", Toast.LENGTH_SHORT).show();
}
});
EDIT
Problem is you are trying to register it in Manifest, remove receiver from manifest and register it inside the MainActivity , It will work like a charm
this.smsReceiverObj = new SmsReceiver(new SmsReceiver.OnCustomReceiveSMS() {
#Override
public void OnReceiveSMS(String inNumber, String inText) {
Toast.makeText(getApplicationContext(), "test event listener fired", Toast.LENGTH_SHORT).show();
}
});
registerReceiver(this.smsReceiverObj,new IntentFilter());
i try almost code in the internet, but i can't solve it.
i want to send data from specific method in the service to activity.
i use intent(putExtra), but it doesn't go to activity class.
here is my RecoBackgroundRangingService.java
(i omit unnecessary code)
private static final String TAG = "RecoBackgroundRangingService";
public static final String BROADCAST_ACTION = "com.example.hello ";
private final Handler handler = new Handler();
Intent intent;
int counter = 0;
#Override
public void onCreate() {
Log.i("BackRangingService", "onCreate()");
super.onCreate();
intent = new Intent(BROADCAST_ACTION);
Toast.makeText(getBaseContext(),"on create", Toast.LENGTH_SHORT).show();
}
#Override
public void didEnterRegion(RECOBeaconRegion region, Collection<RECOBeacon> beacons) {
/**
* For the first run, this callback method will not be called.
* Please check the state of the region using didDetermineStateForRegion() callback method.
*
//Get the region and found beacon list in the entered region
Log.i("BackRangingService", "didEnterRegion() - " + region.getUniqueIdentifier());
this.popupNotification("Inside of " + region.getUniqueIdentifier());
//Write the code when the device is enter the region
DisplayLoggingInfo();
Toast.makeText(getBaseContext(),"did enter region", Toast.LENGTH_SHORT).show();
//this.startRangingWithRegion(region); //start ranging to get beacons inside of the region
//from now, stop ranging after 10 seconds if the device is not exited
}
private void DisplayLoggingInfo() {
//Log.d(TAG, "entered DisplayLoggingInfo");
//intent.putExtra("time", new Date().toLocaleString());
//intent.putExtra("counter", String.valueOf(++counter));
intent.putExtra("status", 1);
sendBroadcast(intent);
Toast.makeText(getBaseContext(),"display logging", Toast.LENGTH_SHORT).show();
}
here is my CheckActivity.java
(when i receive data, my purpose is that store data to the server. therefore, i don't need to use layout. So, in order to check data, i use toast "hello". but toast never popup my phone...)
public class CheckActivity extends Activity {
private static final String TAG = "CheckActivity";
private Intent intent;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_check);
intent = new Intent(this, RecoBackgroundRangingService.class);
Toast.makeText(getBaseContext(), "check activity", Toast.LENGTH_SHORT).show();
}
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
updateUI(intent);
}
};
#Override
public void onResume() {
super.onResume();
startService(intent);
registerReceiver(broadcastReceiver, new IntentFilter(RecoBackgroundRangingService.BROADCAST_ACTION));
}
#Override
public void onPause() {
super.onPause();
unregisterReceiver(broadcastReceiver);
stopService(intent);
}
private void updateUI(Intent intent) {
int status = intent.getIntExtra("status", -1);
Toast.makeText(getBaseContext(), "hello", Toast.LENGTH_SHORT).show();
}
}
I'm trying to pass the data from the brodcast receiver to the activity to display it on the view using an interface, but, it's not working.Here are my files,MainActivity.java
public class MainActivity extends AppCompatActivity implements OtpPassing {
private TextView textView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public void onReceive(String msg) {
Toast.makeText(this, "o" + msg, Toast.LENGTH_SHORT).show();
textView = (TextView) findViewById(R.id.textView);
textView.setText("OTP: " + msg);
}
}
OtpPassing.java
public interface OtpPassing {
public void onReceive(String msg);
}
Receiver.java
public class Receiver extends BroadcastReceiver {
// Get the object of SmsManager
final SmsManager sms = SmsManager.getDefault();
public void onReceive(Context context, Intent intent) {
// Retrieves a map of extended data from the intent.
final Bundle bundle = intent.getExtras();
try {
if (bundle != null) {
final Object[] pdusObj = (Object[]) bundle.get("pdus");
for (int i = 0; i < pdusObj.length; i++) {
SmsMessage currentMessage = SmsMessage.createFromPdu((byte[]) pdusObj[i]);
String phoneNumber = currentMessage.getDisplayOriginatingAddress();
String senderNum = phoneNumber;
String message = currentMessage.getDisplayMessageBody();
Log.i("SmsReceiver", "senderNum: " + senderNum + "; message: " + message);
String otp = getOtp(message);
Toast.makeText(context, otp, Toast.LENGTH_LONG).show(); //This is working fine
OtpPassing otpPassing = new MainActivity();
otpPassing.onReceive(otp); //This is not working
} // end for loop
} // bundle is null
} catch (Exception e) {
Log.e("SmsReceiver", "Exception smsReceiver" +e);
}
}
private String getOtp(String message) {
String otp = null;
int index = message.indexOf("otp:");
if(index != -1){
int start = index + 5;
otp = message.substring(start, start+4);
}
return otp;
}
}
The receiver is woking(it's displaying the message on a Toast) but why is displaying the message on the screen via MainActivity not working?
You can create a broadcast receiver as a data member of your activity. You register for it in onCreate and unregister in onDestroy (or onStart and onStop).
That way the receiver has a reference to the parent activity and you can do whatever.
public class MainActivity extends AppCompatActivity implements OtpPassing {
private TextView textView;
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
//Access the parent activity as follows
MainActivity.this.textView.setText("...");
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//instantiate and register the receiver
setContentView(R.layout.activity_main);
}
#Override
protected void onDestroy() {
// Unregister the receiver here
super.onDestroy();
}
Here better way (I suppose) would be to use Android Intents
in your receiver, something like this
Intent intent = new Intent(context,MainActivity.class);
intent.putExtra(.....);
startactivity(intent);
now in your MainActivity, override onNewIntent(). Here check for the 'extras' you had passed from the receiver.
Please note, this might result in having multiple MainActivities running in your phone if your "older" MainActivity was not killed by the time this intent was passed via receiver. To overcome this, use 'singleTop' or similar flags in your Manifest file
I have an android application where I'm using GCM. I'm following the tutorials and using an InstanceIDListenerService class which I'm attempting to fire off as an IntentService after a "subscription" page where the user enters some information. There is also some preliminary code firing off prior to this subscription page on a splash screen behind the scenes. The InstanceIDListenerService constructor is being called (and subsequently, the onHandleIntent) in the SplashScreen activity before I even get to the SubscriptionActivity. Why is it doing this? Is it possible for an intent service to start on it's own?
I do have the service registered in the AndroidManifest.xml file, and when I comment out the following lines, it does not trigger the instance to get created automatically, the app works as intended (until I need to use the instance of course...)
<service
android:name=".service.receiver.InstanceIDListenerService"
android:exported="false" >
<intent-filter>
<action android:name="com.google.android.gms.iid.InstanceID" />
</intent-filter>
</service>
SplashScreen.java
public class SplashScreen extends Activity {
private BroadcastReceiver dbInsertReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
if(bundle != null) {
// Handle results and move to next activity, should
// be the subscribe activity where I want the instance
// id listener to start.
}
}
};
private BroadcastReceiver providerXMLReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
if(bundle != null) {
// Handle results and start the next service
}
}
}
};
/** Called when the activity is first created */
#Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.activity_splash_screen);
// Kick off the service download to update the provider data
Intent intent = new Intent(this, ProviderDataService.class);
startService(intent);
}
#Override
protected void onStart() {
super.onStart();
registerReceiver(providerXMLReceiver, new IntentFilter(ProviderDataService.CHANNEL));
registerReceiver(dbInsertReceiver, new IntentFilter(InternalDBService.NOTIFICATION));
}
#Override
protected void onResume() {
super.onResume();
registerReceiver(providerXMLReceiver, new IntentFilter(ProviderDataService.CHANNEL));
registerReceiver(dbInsertReceiver, new IntentFilter(InternalDBService.NOTIFICATION));
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(providerXMLReceiver);
unregisterReceiver(dbInsertReceiver);
}
private void moveToNextActivity(int subscriptionStatus) {
if(subscriptionStatus == DBSchemaHelper.IS_SUBSCRIBED_NOT_RESPONDED) {
Intent subscribeIntent = new Intent(SplashScreen.this, SubscribeActivity.class);
startActivity(subscribeIntent);
} else {
// Create an Intent that will start the Menu-Activity.
Intent mainIntent = new Intent(SplashScreen.this, MainActivity.class);
startActivity(mainIntent);
}
this.finish();
}
SubscribeActivity.java
public class SubscribeActivity extends CustomActionBarActivity {
public static final int NO_SUBSCRIPTION_STATUS = -99;
private DBMetaDataSource metaDao;
private int subscribeResult;
public SubscribeActivity() {
metaDao = new DBMetaDataSource(this);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_subscribe);
}
#Override
protected void onStart() {
super.onStart();
registerReceiver(tokenResponseReceiver, new IntentFilter(InstanceIDListenerService.TAG));
}
#Override
protected void onResume() {
super.onResume();
registerReceiver(tokenResponseReceiver, new IntentFilter(InstanceIDListenerService.TAG));
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(tokenResponseReceiver);
}
public void subscribeUser(View v) {
EditText emailTextView = (EditText) findViewById(R.id.subscriptionUserEmail);
String email = emailTextView.getText().toString();
// This is the only place I am manually starting this service.
// I have set a breakpoint here, but I never hit it and the service
// starts on its own and I hit the breakpoints in the service's
// onHandleIntent method.
Intent i = new Intent(this, InstanceIDListenerService.class);
i.putExtra("email", email);
startService(i);
}
public void goToNextActivity(View v) {
// They pressed the button to NOT subscribe, so we are calling this from the
// view rather than the intent receiver, meaning the view will not be null.
if(v != null) {
markUnsubscribed();
}
/* Create an Intent that will start the Menu-Activity. */
Intent mainIntent = new Intent(SubscribeActivity.this, MainActivity.class);
mainIntent.putExtra(MainActivity.SUBSCRIBE_STATUS_KEY, subscribeResult);
startActivity(mainIntent);
}
private void markUnsubscribed() {
metaDao.open(this);
DBMeta metaData = metaDao.get();
metaDao.update(Long.valueOf(metaData.getVersion()), metaData.getLastRunInMillis(), DBSchemaHelper.IS_SUBSCRIBED_RESPONDED_NO, null);
metaDao.close();
}
private BroadcastReceiver tokenResponseReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
subscribeResult = intent.getIntExtra(InstanceIDListenerService.RESPONSE_KEY, NO_SUBSCRIPTION_STATUS);
goToNextActivity(null);
}
};
}
You shouldn't be starting a InstanceIDListenerService yourself - that is for the system to call you when you need to refresh your Instance ID tokens via a callback to onTokenRefresh() - if you haven't created any instance id tokens yet, then you'd just have no work to do on that first call.
If you have other work to do, you should use your own service.
I want to start an Intent with an AlarmManager referring to code in an inner class.
My code in MainActivity.class
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
[...]
DataProcessing2 dp = new DataProcessing2();
startstop.setOnClickListener(new View.OnClickListener() {
public void onClick(View v1) {
if(!listening){
Log.i("Start","Button Pressed");
listening = true;
startstop.setText(R.string.stop);
dp.start(getApplicationContext());
}
}
});
}
}
My code in the DataProcessing2.class
public class DataProcessing2 {
public void start_accel(Context context){
Log.i("Start Accel","Accessed");
accel.setAccel(context);
accel.listenAccel();
Intent getAccelValuesIntent = new Intent(context, DataProcessing2.GetAccelValues.class);
PendingIntent getValues = PendingIntent.getService(context, 0, getAccelValuesIntent, 0);
getAccelData = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
getAccelData.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, System.currentTimeMillis(), sampling_acc_ms, getValues);
}
public class GetAccelValues extends IntentService {
public GetAccelValues() {
super("GetAccelValues");
}
[...]
#Override
protected void onHandleIntent(Intent intent) {
Log.i("Acc Values","Intent received");
accel.calculateAccelerometerData();
getCalculatedData();
boolean moving = sD.acc_delta > sD.acc_th;
Intent broadcastIntent = new Intent();
broadcastIntent.setAction(NOTIFICATION_SERVICE);
broadcastIntent.putExtra("name", "answerAccelerometer");
broadcastIntent.putExtra("moving", moving);
sendBroadcast(broadcastIntent);
}
}
The problem is that I never get the receive the Intent on GetAccelValues.
The problem is that you're using incompatible clocks. You should either use AlarmManager.ELAPSED_REALTIME_WAKEUP together with System.elapsedRealtime(), or AlarmManager.RTC_WAKEUP together with System.currentTimeMillis(). For example:
getAccelData.setInexactRepeating(AlarmManager.RTC_WAKEUP,
System.currentTimeMillis(), sampling_acc_ms, getValues);