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
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);
}
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
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);
}
}
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.
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);
}
...
}