BroadcastReceiver setting own context - android

is is possible to set own context after creating broadcastreceiver like this:?
public class MyFragment extends Fragment(){
Button myButton;
#Override
onCreate {
myButton = (Button) findview...
myButton.setOnClickListner(myListener);
}
.
.
.
MyListener {
#Override
OnClickListner {
MyBroadCastReceiver receiver = new MyBroadCastReceiver()
receiver.setContext(mContext)
}
}
public static class MyBroadcastReceiver extends BroadcastReceiver {
Context mContext;
void setContext(Context context) {
mContext = context;
}
#Override
public void onReceive(Context context, Intent intent) {
if (mContext!= null){
log.d(TAG, "Context not null")
}
}
}
Every time method onReceive is invoked my mContext is null, is there any solution for that?

try this my friend
public class MyReceiver extends BroadcastReceiver {
Context mContext;
public MyReceiver() {
super();
}
#Override
public void onReceive(Context context, Intent intent) {
mContext = context;
if (mContext != null) {
log.d(TAG, "Context not null")
}else{
log.d(TAG, " null Context ")
}
}
}
create new object of your broadcast like this
MyReceiver receiver = new MyReceiver(this);

The problem was with declaring receiver in manifest, while it should be declared only in fragment, after changing it, everything works as it should.
Thanks for help.

Related

LocalBroadcastManager not receiving broadcasts in a Activity

I am using a LocalBroadcastManager to make broadcast to my activtiy and services using APPLICATION CONTEXT , like this:
public class CommonForApp extends Application{
public void broadcastUpdateUICommand(String[] updateFlags,
String[] flagValues) {
Intent intent = new Intent(UPDATE_UI_BROADCAST);
for (int i = 0; i < updateFlags.length; i++) {
intent.putExtra(updateFlags[i], flagValues[i]);
}
mLocalBroadcastManager = LocalBroadcastManager.getInstance(mContext);
mLocalBroadcastManager.sendBroadcast(intent);
}}
Now Using a Listener in my Service, I am calling broadcastUpdateUICommand() ,like this:
public class mService extends Service {
public BuildNowPLaylistListListener buildCursorListener = new BuildNowPLaylistListListener() {
#Override
public void onServiceListReady() {
mApp.broadcastUpdateUICommand(
new String[] { CommonForApp.INIT_DRAWER},
new String[] {""});
}}}
And i am receiving the broadcast in my Activity, like this:
public class mActivity extends Activity{
BroadcastReceiver mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
mtoast.showtext("in onreceive"); //toast to check
if (intent.hasExtra(CommonForApp.INIT_DRAWER))
initialiseDrawer();
}};
}
mApp is instance of Application.
CommonForApp is my Application Class.
But in my activity i am not receving any broadcast(the broadcast manager is initialised using application context) .
Can Anyone suggest me why i am not receiving broadcast in my activity? ..
.Thanks in advance !
in activity:
protected BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, final Intent intent) {
runOnUiThread(new Runnable() {
#Override
public void run() {
if(intent.hasExtra("type")){
// Do some action
}
}
});
}
};
#Override
public void onCreate(Bundle savedInstanceState, PersistableBundle persistentState) {
super.onCreate(savedInstanceState, persistentState);
LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
new IntentFilter("data-loaded"));
}
protected void onDestroy() {
super.onDestroy();
LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
}
then you send broadcast:
public static void sendBroadcastMessageDataLoaded(Context context, String dataType){
Intent intent = new Intent("data-loaded");
intent.putExtra("type", dataType);
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
}

I cannot unregister my receiver and I'm still getting broadcasts

In my activity I have this:
protected void onStart() {
super.onStart();
blc = new BluetoothClient(this);
}
protected void onStop() {
super.onStop();
try {
blc.close();
} catch (IOException e) { }
blc = null;
}
This is the class that has the receiver: (Just the important parts)
public class BluetoothClient implements Closeable {
final BroadcastReceiver receiver;
Context context;
...
public BluetoothClient(Context context) {
this.context = context.getApplicationContext();
receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
}
};
context.registerReceiver(receiver, new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED));
...
}
...
public void close() throws IOException {
try {
context.unregisterReceiver(receiver); // Causes IllegalArgumentException
} catch (Exception e) {
e.printStackTrace();
}
}
}
I get java.lang.IllegalArgumentException: Receiver not registered every time in BluetoothClient.close. How can I do this correctly.
Edit: added all the code (it is probably too much to look through at a glance)
full code (except main activity, forgot about that) is here: http://pastebin.com/aVit2L8M
main activity: http://pastebin.com/6Ww8sKwE
Either you are using a different context to unregister the broadcast rather than the context you registered with OR you are unregistering a different receiver.
You should set the incoming context as a field in the constructor and use it when unregistering.
public class BluetoothClient {
Context mContext;
public BluetoothClient(Context context) {
mContext = context;
...
}
public void close() {
try {
mContext.unregisterReceiver(receiver);
}
}
Register and Unregister the Broadcast Receiver in the onResume and onPause respectively and UseLocalBroadCastManger.getInstance(mContext).register(YourReceiver) and LocalBroadCastManger.getInstance(mContext).unregister(YourReceiver)
Check on Official Documentation also

Android - How to reference activity that registered receiver in BroadcastReceiver?

In my MainActivity I have:
this.registerReceiver(new SmsListener(),new IntentFilter("RECEIVED SMS"));
In my manifest.xml I have:
<receiver android:name="com.example.SmsListener">
and in my BroadcastReceiver subclass I have:
public class SmsListener extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
// how do I reference MainActivity here?
}
}
You can't get activity from Context. If you really need it, I guess your only option is to save the reference of your MainActivity in a private static field and then make a static "getInstance()" method.
public class MainActivity extends Activity {
private static MainActivity sActivity = null;
...
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sActivity = this;
...
}
public static MainActivity getInstance() {
return sActivity;
}
...
}
From your receiver you can now call
public class SmsListener extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
MainActivity myMainActivity = MainActivity.getInstance();
...
}
}
However, I don't think you want to do it.
try this solution
public class SmsListener extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent (context, MainActivity.class);
context.startActivity(i);
}
}

Calling a Activity method from BroadcastReceiver in Android

Here I am creating an online application that depends only on Internet.
So whenever there is a network error it must notify user. For that, I have created a BroadcastReciver that receives call when network connection gets lost(Internet).
All this works perfectly. Now what I need is that I have to call a method of Activity from this Broadcast Receiver, where I have created an Alert Dialogue.
I have read many answers on stack-overflow.com that I can declare that method static and call by using only Activity name,
e.g MyActivityName.myMethod()
But I can't declare my method static, because I am using Alert Dialogue there and it shows me error on line,
AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
that Cannot use this in a static context.
So, how can I call a method of Activity(must not static and without starting that activity) from a Broadcast Receiver ?
And can I get Activity(or fragment) name from Broadcast Receiver which is currently running?
try this code :
your broadcastreceiver class for internet lost class :
public class InternetLostReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
context.sendBroadcast(new Intent("INTERNET_LOST"));
}
}
in your activity add this for calling broadcast:
public class TestActivity extends Activity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
registerReceiver(broadcastReceiver, new IntentFilter("INTERNET_LOST"));
}
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// internet lost alert dialog method call from here...
}
};
#Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(broadcastReceiver);
}
}
INTERFACE: Keep BroadCastReceiver and Activity code separate!
You can make a CallBackListener interface. The interface will work as a bridge between BroadcastReceiver and Activity.
1) Create a CallbackListener
interface ConnectionLostCallback{
public void connectionLost();
}
2) Provide ConnectionLostCallback in your BroadcastReceiver
public class MyBroadcastReceiver extends BroadcastReceiver{
private ConnectionLostCallback listener;
public MyBroadcastReceiver(ConnectionLostCallback listener ){
this.listener = listener //<-- Initialze it
}
#Override
public void onReceive(Context context, Intent intent) {
listener.connectionLost();
}
}
3) Implement the ConnectionLostCallback in your Activity and override the method
YourActvity extends AppcompatActivity implements ConnectionLostCallback{
// Your Activity related code //
// new MyBroadcastReceiver(this); <-- create instance
private void showAlertMessage(){
AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
}
#Override
public void connectionLost(){
showAlertMessage(); //<--- Call the method to shoe alert dialog
}
}
Relevant link:
If you want to know how to make a BroadcastReceiver independent of any
activity ie How can you reuse the same BroadCastReceiver with
different Activities? Then READ THIS
Add a boolean variable in you activity from where you are open alertdialog
boolean isDialogOpened = false;
// in broadcast recever check
if(isDialogOpened) {
alertDialog();
}
And replace your code for alertdialog with this one
public void alertDialog() {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
alertDialog.setMessage("Network not found.");
alertDialog.setPositiveButton("Check Setting",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
});
alertDialog.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
});
alertDialog.setOnDismissListener(new OnDismissListener() {
#Override
public void onDismiss(DialogInterface dialog) {
isDialogOpened = false;
}
});
alertDialog.setOnCancelListener(new OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
isDialogOpened = false;
}
});
alertDialog.show();
}
Pass your Activity's context to BroadcastReceiver's contructor.
public class ResponseReceiver extends BroadcastReceiver{
MainActivity ma; //a reference to activity's context
public ResponseReceiver(MainActivity maContext){
ma=maContext;
}
#Override
public void onReceive(Context context, Intent intent) {
ma.brCallback("your string"); //calling activity method
}
}
and in your MainActivity
public class MainActivity extends AppCompatActivity {
...
public void onStart(){
...
ResponseReceiver responseReceiver = new ResponseReceiver(this); //passing context
LocalBroadcastManager.getInstance(this).registerReceiver(responseReceiver,null);
...
}
public void brCallback(String param){
Log.d("BroadcastReceiver",param);
}
}
hope it helps
Use lambdas. A Consumer would do.
protected void onCreate(Bundle savedInstanceState) {
...
receiver = new LocationBroadcastReceiver((whatever) -> doSomething(whatever));
registerReceiver(receiver, new IntentFilter("YOUR_MESSAGE"));
}
Where doSomething will be a method in your Activity.
...
class YourBroadcastReceiver extends BroadcastReceiver {
private Consumer<Whatever> callback;
public LocationBroadcastReceiver(Consumer<Whatever> callback) {
this.callback = callback;
}
#RequiresApi(api = Build.VERSION_CODES.N)
#Override
public void onReceive(Context context, Intent intent) {
this.callback.accept(new Whatever());
}
}
Is the alternative to all the other:
declare that method static and call by using only Activity name.
Apart from what you explained, that's a way of coupling.
pass your Activity's context to BroadcastReceiver's contructor.
That wouldn't work because you want to call a method that's not part of AppCompatActivity. And yeah, you could downcast, but then you end up coupled to your activity.
using another Broadcast or a Local Broadcasts instead
Well, you can only pass a bunch of primitives that way. What if you want to pass an object? Also, declaring a new BroadcastReceiver get quite verbose and maybe hard to follow.
Same as Vijju' s answer but using Local Broadcasts instead
public class SampleReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent intentToBroadcast = new Intent("YOUR_ACTION_HERE");
LocalBroadcastManager.getInstance(context).sendBroadcast(intentToBroadcast);
}
}
In your activity add this
public class SampleActivity extends Activity {
#Override
protected void onResume() {
super.onResume();
LocalBroadcastManager.getInstance(this).registerReceiver(mSampleReceiver, new IntentFilter(YOUR_ACTION_HERE));
}
#Override
protected void onPause() {
LocalBroadcastManager.getInstance(this).unregisterReceiver(mSampleReceiver);
super.onPause();
}
private SampleReceiver mSampleReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// your code here
}
};
}
Note Move the register/unregister calls to onCreate/onDestroy is you want to be notified even when your activity is in the background.

Get intent from broadcast receiver to activity

I want my activity class to receive an intent from broascast Receiver (example START_TALKING, STOP_TALKING). And when I receive that intent, I want to check what action was being passed. How can I do this. My receiver is in separate class, it's public.
Here's my code
public void onReceive(Context context, Intent intent)
{
if (Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction())) {
KeyEvent event = intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
switch (event.getKeyCode()) {
case KeyEvent.KEYCODE_HEADSETHOOK:
if (action == KeyEvent.ACTION_DOWN)
// here I want to notify my activity class (e.g. startActivity? I don't know)
break;
case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
// here I want to notify my activity class (e.g. startActivity? I don't know)
}
}
}
I really need your help guys tnx.
Here is my solution, in my project, hope it'll help you:
you should type this:
// put your action string in intent
Intent intent = new Intent("com.example.myproject.ADD_ITEM_BASKET");
// start broadcast
activity.sendBroadcast(intent);
public class Myclass extends Fragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// creating and register receiver
Receiver receiver = new Receiver();
IntentFilter intentFilterAdd = new IntentFilter("com.example.myproject.ADD_ITEM_BASKET");
IntentFilter intentFilterEdit = new IntentFilter("com.example.myproject.DELETE_ITEM_BASKET");
getActivity().registerReceiver(receiver, intentFilterAdd);
getActivity().registerReceiver(receiver, intentFilterDelete);
}
// your receiver class
class Receiver extends BroadcastReceiver
{
// catch messages from intent
#Override
public void onReceive(Context context, Intent intent) {
if("com.example.myproject.ADD_ITEM_BASKET".equals(intent.getAction().toString()))
{
// do something
}
else if("com.example.myproject.DELETE_ITEM_BASKET".equals(intent.getAction().toString()))
{
// do something
}
}
}
}
You can use putExtra() in your BroadcastReceiver's onReceive().
/**
* #author Skylifee7 on 23/06/2017.
* TemplateResultReceiver.java
*/
public class TemplateResultReceiver extends BroadcastReceiver {
private static final String TAG = "BleshTemplate";
public static final String EXTRA_MESSAGE = "TRANSACTION_MESSAGE";
Context mContext;
#Override
public void onReceive(Context context, Intent intent) {
mContext = context;
if (intent.getAction().equals(BleshConstant.BLESH_TEMPLATE_RESULT_ACTION)) {
String actionType = intent.getStringExtra(BleshConstant.BLESH_ACTION_TYPE);
String actionValue = intent.getStringExtra(BleshConstant.BLESH_ACTION_VALUE);
if (actionType != null && actionValue != null) {
switch (actionType) {
case "MENU": sendMessage(actionValue);
/*
You may want to increase the case possibilities here, like below:
case: "ADMOB"
case: "VIRTUAL_AVM"
case: "SMART_CAR_KEY"
*/
default: sendMessage(actionValue);
}
}
}
}
private void sendMessage(String actionValue) {
Intent intent = new Intent(mContext.getApplicationContext(),TransactionActivity.class);
intent.putExtra(EXTRA_MESSAGE, actionValue);
mContext.getApplicationContext().startActivity(intent);
}
}
And in your Activity class' onCreate() method:
/**
* #author Skylifee7 on 24/06/2017.
* TransactionActivity.java
*/
public class TransactionActivity extends AppCompatActivity {
private String bleshKey;
private String TAG = "Transaction_Activity";
private String amount;
private String isSuccessful; //may be cast to boolean type.
private double latitude, longitude;
private LocationRequest mLocationRequest;
protected GoogleApiClient mGoogleApiClient;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_payment);
requestPermission();
initLocationService();
// Get the Intent that started this activity and extract the string
Intent intent = getIntent();
bleshKey = intent.getStringExtra(BleshTemplateResultReceiver.EXTRA_MESSAGE);
ImageButton paymentBtn = (ImageButton) findViewById(R.id.buttonPay);
final EditText editTextAmount = (EditText) findViewById(R.id.editTextAmount);
paymentBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
amount = editTextAmount.getText().toString();
callApiService();
}
});
}
}
You have to register the receiver... Follow this example..
public class MyActivity extends Activity {
private BroadcastReceiver myBroadcastReceiver =
new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// your onreceive code here
}
});
...
public void onResume() {
super.onResume();
....
registerReceiver(myBroadcastReceiver, intentFilter);
}
public void onPause() {
super.onPause();
...
unregisterReceiver(myBroadcastReceiver);
}
...
}

Categories

Resources