Broadcast Receiver not displaying Toast via OnReceive method in Xamarin Android - android

Am trying to implement a Broadcast receiver class in my project, I have a receiver that extends class BroadcastReceiver and I intend to check if the Broadcast was received via a button click, The OnReceive method has a Toast code inside that should display the nessage Intent Detected if the broadcast was succesfully sent. My code looks like this...
class FlashActivity : AppCompatActivity
{
protected override void OnCreate(Bundle savedInstanceState)
{
//Button definition
Button button1 = this.FindViewById<Button>(Resource.Id.button1);
//Clicking on this button should send the Broadcast message
button1.Click += broadCastIntent;
}
//Method to send broadcast message on button click
private void broadCastIntent(object sender,EventArgs e)
{
Intent intent = new Intent();
intent.SetAction("com.Java_Tutorial.CUSTOM_INTENT");
SendBroadcast(intent);
}
//BroadCast Receiver class Implementation
[BroadcastReceiver(Name="com.Java_Tutorial.CUSTOM_INTENT")]
public class MyReceiver: BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
//Acknowledge message was received via a Toast
Toast.MakeText(context, "Intent Detected.", ToastLength.Long).Show();
}
}
}
The Receiver code section of my Manifest.xml file looks like this
<application android:allowBackup="true" android:icon="#mipmap/ic_launcher" android:label="#string/app_name" android:roundIcon="#mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="#style/AppTheme">
<receiver android:name="MyReceiver">
<intent-filter>
<action android:name="com.Java_Tutorial.CUSTOM_INTENT"></action>
</intent-filter>
</receiver>
</application>
When i click the button, No Toast is displayed please help...

When i click the button, No Toast is displayed
You do not register your BroadcastReceiver in your Activity.
Please register it like following code.
[Activity(Label = "#string/app_name", Theme = "#style/AppTheme", MainLauncher = true)]
public class MainActivity : AppCompatActivity
{
MyReceiver receiver;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.activity_main);
Button button1 = this.FindViewById<Button>(Resource.Id.button1);
receiver = new MyReceiver();
//Clicking on this button should send the Broadcast message
button1.Click += broadCastIntent; ;
}
private void broadCastIntent(object sender, System.EventArgs e)
{
Intent intent = new Intent();
intent.SetAction("com.Java_Tutorial.CUSTOM_INTENT");
SendBroadcast(intent);
}
//BroadCast Receiver class Implementation
protected override void OnResume()
{
base.OnResume();
RegisterReceiver(receiver, new IntentFilter("com.Java_Tutorial.CUSTOM_INTENT"));
// Code omitted for clarity
}
protected override void OnPause()
{
UnregisterReceiver(receiver);
// Code omitted for clarity
base.OnPause();
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
[BroadcastReceiver(Name = "com.Java_Tutorial.CUSTOM_INTENT")]
public class MyReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
//Acknowledge message was received via a Toast
Toast.MakeText(context, "Intent Detected.", ToastLength.Long).Show();
}
}
}
Here is running GIF.
Here is a helpful article about broadcast. You cna refer to it.
https://learn.microsoft.com/en-us/xamarin/android/app-fundamentals/broadcast-receivers#context-registering-a-broadcast-receiver
Update
tried to find a post where you detect if flashlight is already on via a broadcast and then toggle switch accordingly in my app
Android OS do not provide system broadcast for flashlight. But we can check the flashlight's status.If the flashlight's status is open, we can send an broadcast, then our broadcastReceiver to get it.
// note: camera come from: private Android.Hardware.Camera camera=Android.Hardware.Camera.Open();
if (camera.GetParameters().FlashMode.Equals(Android.Hardware.Camera.Parameters.FlashModeOff))
{
switchOn = false;
}
else if (camera.GetParameters().FlashMode.Equals(Android.Hardware.Camera.Parameters.FlashModeTorch))
{
switchOn = true;
Intent intent = new Intent();
intent.SetAction("com.Java_Tutorial.CUSTOM_INTENT");
SendBroadcast(intent);
}

You need to add an IntentFilter attribute
[BroadcastReceiver(Enabled = true)]
[IntentFilter(new[] { "com.Java_Tutorial.CUSTOM_INTENT" })]
public class MyReceiver: BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
//Acknowledge message was received via a Toast
Toast.MakeText(context, "Intent Detected.", ToastLength.Long).Show();
}
}

Related

I want my app to receive an sms to start the MainAcitivity. Even when the app is closed

I have developed an app that receives a specific text message and then do a pre-defined task. This app works fine when it is running. but when it is closed it does not do the pre-defined task. I believe there is some problem that my app do not receive broadcast when it is closed. maybe i'm not properly registering the receiver in the manifest file.
I have two classes. one is SMSReceiver that extends the broadCast Receiver. and the second one is MainActivity that is calling the broadcast receiver to receive the text message and perform a specific task.
My manifest file is:
<receiver android:name=".SMSReceiver" android:exported="true"
android:enabled="true" android:directBootAware="true">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
<activity
android:name=".MainActivity">
</activity>
SMSReceiver Class Code:
public class SMSReceiver extends BroadcastReceiver {
public String number;
public String nn;
public String v;
#Override
public void onReceive(Context context, Intent intent) {
}
}
MainActivity class code
public class MainActivity extends AppCompatActivity{
public String r_num;
Button btn;
EditText msg;
EditText num;
IntentFilter intentFilter;
private BroadcastReceiver intentReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//MYCODE
}
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
intentFilter = new IntentFilter();
intentFilter.addAction("SMS_RECEIVED_ACTION");
btn = (Button) this.findViewById(R.id.sendbtn);
msg = (EditText) this.findViewById(R.id.message);
num = (EditText) this.findViewById(R.id.numbertxt);
btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
}} });
}
private void sendMsg(String n, String m) {
}
protected void onResume()
{
registerReceiver(intentReceiver,intentFilter);
super.onResume();
}
protected void onPause()
{
unregisterReceiver(intentReceiver);
super.onPause();
}}
This code works fine when my app is running. i want my app to respond to the message even when the app is closed/not running. Thanks in advance
Remove broadcast receiver from MainActivity. In SMSReceiver's onReceive() start MainActivity instead sending broadcast. Put extra datas to intent and receive it in MainActivity's onNewIntent().
Intent intent = Intent(context, MainActivity.java)
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
context.startActivity(intent)
In MainActivity override onNewIntent(). Put broadcast receiver's code in MainActivity into onNewIntent()
Or put this code inside SMSReceiver instead sending broadcast.
if(v.equalsIgnoreCase("call.me")) {
Toast.makeText(context, "Generating Call, Please Wait", Toast.LENGTH_LONG).show();
Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.setData(Uri.parse(number));
context.startActivity(callIntent);
}
put extras to intent from SMSReceiver like this
intent.putExtra("message", str);
intent.putExtra("me", v);
intent.putExtra("num", number);
receive it from onNewIntent() like this
Bundle bundle = intent.getExtras();
String message = bundle.getString("message");
String me = bundle.getString("me");
String number = bundle.getString("num");

Limiting Broadcast Receiver for Fragment only

I have created a BroadCast Receiver to notify the GPS state as below :
public class GpsLocationReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().matches("android.location.PROVIDERS_CHANGED")) {
Toast.makeText(context, "asdsadasdsaD", Toast.LENGTH_SHORT).show();
}
}
Receiver in Manifest as below :
<receiver android:name=".utility.GpsLocationReceiver">
<intent-filter>
<action android:name="android.location.PROVIDERS_CHANGED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
Now, the issue is that What if I want to check gps state only in single Fragment ? Right now it broadcasting for overall app.
Thanks.
ReceiverActivity.java
A Activity that watches for notifications for the event named "custom-event-name"
#Override
public void onCreate(Bundle savedInstanceState) {
...
// Register to receive messages.
// We are registering an observer (mMessageReceiver) to receive Intents
// with actions named "custom-event-name".
LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
new IntentFilter("custom-event-name"));
}
// Our handler for received Intents. This will be called whenever an Intent
// with an action named "custom-event-name" is broadcasted.
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// Get extra data included in the Intent
String message = intent.getStringExtra("message");
Log.d("receiver", "Got message: " + message);
}
};
#Override
protected void onDestroy() {
// Unregister since the activity is about to be closed.
LocalBroadcastManager.getInstance(this)
.unregisterReceiver(mMessageReceiver);
super.onDestroy();
}
SenderActivity.java
Intent intent = new Intent("custom-event-name");
// You can also include some extra data.
intent.putExtra("message", "This is my message!");
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
in OnResume() of your fragment write
LocalBroadcastManager.getInstance(context).registerReceiver(gpsChangeReceiver , new IntentFilter("android.location.PROVIDERS_CHANGED"));
An in onPause() of your fragment write
LocalBroadcastManager.getInstance(context).unregisterReceiver(gpsChangeReceiver );
At bottom of your fragment write
private BroadcastReceiver gpsChangeReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "asdsadasdsaD", Toast.LENGTH_SHORT).show();
}
};

BroadcastReceiver does not receive intent Intent.ACTION_LOCALE_CHANGED

I want my app to be aware anytime the user changes the locale. So in my Application class, I create a receiver to listen to the system intent ACTION_LOCALE_CHANGED:
public final class MyApp extends Application {
private BroadcastReceiver myReceiver = new BroadcastReceiver() {
#Override public void onReceive(Context context, Intent intent) {
String locale = Locale.getDefault().getCountry();
Toast.makeText(context, "LOCALE CHANGED to " + locale, Toast.LENGTH_LONG).show();
}
};
#Override public void onCreate() {
IntentFilter filter = new IntentFilter(Intent.ACTION_LOCALE_CHANGED);
LocalBroadcastManager.getInstance(this).registerReceiver(myReceiver, filter);
}
}
When I press home and go to the settings app to change my locale, the Toast is not shown. Setting the breakpoint inside onReceive shows it never gets hit.
Why do you want the BroadcastReceiver in Application class. My suggestion is to have a separate class for BroadcastRecevier.
public class LocaleChangedReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction (). compareTo (Intent.ACTION_LOCALE_CHANGED) == 0)
{
Log.v("LocaleChangedRecevier", "received ACTION_LOCALE_CHANGED");
}
}
}
and register your Brodcast receiver in Manifest file.
<receiver
android:name=".LocaleChangedReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.LOCALE_CHANGED" />
</intent-filter>
</receiver>
Intent.ACTION_LOCALE_CHANGED is not a local broadcast, so it won't work when you register it with LocalBroadcastManager. LocalBroadcastManager is used for the broadcast used inside your app.
public class MyApp extends Application {
private BroadcastReceiver myReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String locale = Locale.getDefault().getCountry();
Toast.makeText(context, "LOCALE CHANGED to " + locale,
Toast.LENGTH_LONG).show();
}
};
#Override
public void onCreate() {
super.onCreate();
IntentFilter filter = new IntentFilter(Intent.ACTION_LOCALE_CHANGED);
registerReceiver(myReceiver, filter);
}
}

unable to send and receive Broadcast from activity :android

I am unable to send a Broadcast from one activity to other activity please see the code below. There are two buttons one for send Broadcast and other is for receiving Broadcast. I have tried following code. But my Receiver activity is running only when I click on checkBrodcast button.
public class MainActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) {
sendBrodcast = (Button) findViewById(R.id.send_brodcast);
checkBrodcast = (Button) findViewById(R.id.check_brodcast);
sendBrodcast.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Log.w("Check", "inside send broadcast");
Intent broadcast = new Intent();
broadcast.setAction("BROADCAST_ACTION");
broadcast.addCategory(Intent.CATEGORY_DEFAULT);
sendBroadcast(broadcast);
}
});
checkBrodcast.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent(MainActivity.this, Receiver.class);
startActivity(intent);
}
});
}
}
public class Receiver extends Activity {
BroadcastReceiver br = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.w("Check", "Inside On Receiver");
Toast.makeText(getApplicationContext(), "received",
Toast.LENGTH_LONG).show();
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
IntentFilter filter = new IntentFilter();
filter.addAction("BROADCAST_ACTION");
filter.addCategory(Intent.CATEGORY_DEFAULT);
registerReceiver(br, filter);
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(br);
}
}
The way you have Initiated the BroadCast is fine. You just need to change the way you intercept this Broadcast.
INITIATE A BROADCAST
Intent broadcast = new Intent();
broadcast.setAction("BROADCAST_ACTION");
broadcast.addCategory(Intent.CATEGORY_DEFAULT);
sendBroadcast(broadcast);
INTERCEPT IT
A) CREATE A RECEIVER
BroadcastReceiver br = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.w("Check", "Inside On Receiver");
Toast.makeText(getApplicationContext(), "received",
Toast.LENGTH_LONG).show();
}
};
B) REGISTER RECEIVER - Do this onCreate Activity Call Back
registerReceiver(br , new IntentFilter("BROADCAST_ACTION"));
Broadcast receivers registered this way(SINGLETON DECLARATION and NOT IN MANIFEST) - do not receive broadcasts unless the containing app is running. But as in your case you are firing a broadcast message onClick event, so the the app must be running. So I guess it is safe to assume that your receiver set up using this method, will work fine - provided the class in which you declared your receiver is created and exists in the activity stack, before you fire a broadcast from a different activity.
This is because you're not declaring your broadcast receiver in your Android Manifest. Dynamically registered receivers well not receive broadcasts unless the containing app is running.
If you want the second activity to get the broadcasts without having to click the button to start the app, then add the appropriate broadcast receiver to the second activities android manifest.
If you want to broadcast data from one activity to another, simply make use of Intent. In the light of your case simply call finish() in your onClickListener() and then in the onDestroy method of your second activity create Intent object and broadcast data as intent extra then, use intent.getExtra() method on onReceive() method of your broadcastReceiver class.
For more details:
follow this tutorial
The problem is with your manifest. You have to register your receiver in your Manifest like this:
<receiver android:name="MyReceiver" >
<intent-filter>
<action android:name="com.android.mybroadcast" />
</intent-filter>
</receiver>
But anyway, personally, I don't like how you are building the broadcast receiver structure.
You should create a class that extendes from BroadcastReceiver like:
public class MyBroadcastReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
Toast.makeText(context, "Your receiver!!!!.",
Toast.LENGTH_LONG).show();
}
}
Dont forget to set up your manifest:
<receiver android:name="MyBroadcastReceiver" >
</receiver>
And now the class from you are calling:
public class AlarmActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public void startAlert(View view)
{
int i = Integer.parseInt(text.getText().toString());
Intent intent = new Intent(this, MyBroadcastReceiver.class);
PendingIntent pendingIntent =
PendingIntent.getBroadcast(this.getApplicationContext(), 234324243, intent, 0);
}
}
Something like that!!!

End to end BroadcastReceiver linking

There are lots of posts out there on using BroadcastReceiver for receiving messages in an Activity that are broadcast from a Service. I've been through dozens and haven't found one that puts it all together. Bottom line is I can't get my Activity to receive broadcasts. Here's what I've done to date:
Service class broadcast:
Context context = this.getApplicationContext();
Intent intentB2 = new Intent(context, StationActivity.AudioReceiver.class);
intentB2.putExtra("Track", mSongTitle);
this.sendBroadcast(intentB2);
Log.i(TAG, "Broadcast2: " + mSongTitle);
Activity class declaration:
public String INCOMING_CALL_ACTION = "com.example.android.musicplayer.action.BROADCAST";
Activity class inline BroadcastReceiver:
public class AudioReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent) {
// Handle receiver
Log.i(TAG, "Inner BroadcastReceiver onReceive()");
String mAction = intent.getAction();
if(mAction.equals(INCOMING_CALL_ACTION)) {
Log.i(TAG, "Inner BroadcastReceiver onReceive() INCOMING_CALL_ACTION");
}
}
};
Android manifest receiver declaration:
<receiver android:name=".StationActivity.AudioReceiver">
<intent-filter>
<action android:name="com.example.android.musicplayer.action.BROADCAST" />
</intent-filter>
</receiver>
What am I missing? Thanks in advance.
In your service:
Intent intentB2 = new Intent("some_action_string_id");
intentB2.putExtra("Track", mSongTitle);
sendBroadcast(intentB2);
Then in your activity:
public class MyActivity extends Activity {
private BroadcastReceiver myReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(getApplicationContext(), "Woot! Broadcast received!", Toast.LENGTH_SHORT);
}
};
#Override
protected void onResume() {
super.onResume();
IntentFilter filter = new IntentFilter("some_action_string_id"); // NOTE this is the same string as in the service
registerReceiver(myReceiver, filter);
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(myReceiver);
}
}
This is the common approach to receive broadcast events in activities. Note that we are registering the receiver when the activity is in the foreground and unregistering it when the activity is no longer visible.
replace your service code with below code and add String INCOMING_CALL_ACTION in your service or directly use it from activity class.
Context context = this.getApplicationContext();
Intent intentB2 = new Intent();
intentB2.setAction(INCOMING_CALL_ACTION);
intentB2.putExtra("Track", mSongTitle);
this.sendBroadcast(intentB2);
Log.i(TAG, "Broadcast2: " + mSongTitle);

Categories

Resources