I am looking around on how to call a method which is there in an AbstractActivity from a BroadCast Receiver. I tried making the method static and calling it straight away from the broadcast receiver just by using the classname. But the app then crashes with a nullpointer exception in the switch statement which is there in the static method.
Example:
public class MainActivity extends AbstractActivity{
Context context;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public static void additionDone(Context context,int number){
switch(number)
case 1:
Toast.makeText(context, "First case" , Toast.LENGTH_SHORT).show();
break;
}
}
BroadCast Receiver example:
public class receiver extends BroadcastReciever{
#Override
public void onReceive(Context context, Intent intent) {
//logic
}
public class anotherMethod(){
MainActivity.additionDone(1,context);
}
}
Is something wrong with the code above? Or is there a different way of calling a static method which belongs to a abstract activity?
The order of the parameters/arguments don't match.
additionDone(Context context,int number)
MainActivity.additionDone(1,context)
Your Context context; of the MainActivity is never assigned,
change your code to this
public static void additionDone(int number, Context context){
...//work with that context
}
and in your reciever
MainActivity.additionDone(1, context); //call with the context you got in your receiver constructor
Related
I am developing an Android app. In my app, I am deleting data from database when app is closed. So I open broadcast receiver onDestroy and delete data inside receiver. When I call delete method of database helper inside Activity, it is working. But when I call it inside receiver, it is not working.
This is my receiver:
public class InspectDataReceiver extends BroadcastReceiver {
private DatabaseHelper dbHelper;
#Override
public void onReceive(final Context context, Intent intent) {
}
public void refreshData(final Context context,String type)
{
dbHelper = new DatabaseHelper(context);
dbHelper.deleteCategories();
} }
This is delete method of database helper:
public void deleteCategories()
{
db = getWritableDatabase();
db.delete(CATEGORY_TABLE,null,null);
db.close();
}
This is how I delete data in the onDestroy event of my activity:
#Override
protected void onDestroy() {
super.onDestroy();
updateCacheData();
}
private void updateCacheData()
{
InspectDataReceiver receiver = new InspectDataReceiver();
receiver.refreshData(getBaseContext(),getResources().getString(R.string.data_receiver_type_category));
}
But data are not deleted.It is not throwing error as well. When I delete within activity. Delete method is working. How can I fix it?
you are not doing anything inside onReceive(), you need to call refreshData():
#Override
public void onReceive(final Context context, Intent intent) {
refreshData(context);
}
or call deleteCategories() method directly:
#Override
public void onReceive(final Context context, Intent intent) {
dbHelper = new DatabaseHelper(context);
dbHelper.deleteCategories();
}
in second case you dont need to define refreshData() in the receiver class
I have a class structure as below
public class Admin extends DeviceAdminReceiver
{
public static class PubSub extends Activity
{
protected void onCreate(Bundle savedInstanceState) {
messageIntentReceiver = new MQTTMessageReceiver();
IntentFilter intentCFilter = new IntentFilter(MQTTService.MQTT_MSG_RECEIVED_INTENT);
registerReceiver(messageIntentReceiver, intentCFilter);
}
#Override
protected void onDestroy()
{
unregisterReceiver(messageIntentReceiver);
super.onDestroy();
}
public class MQTTMessageReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
Bundle notificationData = intent.getExtras();
String newTopic = notificationData.getString(MQTTService.MQTT_MSG_RECEIVED_TOPIC);
String newData = notificationData.getString(MQTTService.MQTT_MSG_RECEIVED_MSG);
Log.e("Received Message on",newTopic+"- "+newData);
}
}
}
}
The receivers are dynamically registered and unregistered. The broadcast receiver works while PubSub activity stays on the screen. How to make it work from outside of activity?
I tried to do it in static way by registering in manifest.xml, but that dint work as MQTTMessageReceiver is a non static inner class. Cant able to instantiate the receiver runtime error I get.
I cant change the MQTTMessageReceiver class static as i need to access outer class members.
I've set up a class called NetworkStatus that monitors the network status of the device. Within NetworkStatus I've defined a BroadcastReceiver that monitors if there has been a connectivity change, i.e., if the internet has been switched off or on. I want to 'expose' this method (i.e. onReceive) to the activity that instantiated the instance of NetworkStatus.
I'm trying to achieve this by setting up an interface in the NetworkStatus class, but I'm not sure how to call the interface from the onReceive method of the BroadcastReceiver i.e.,
public class NetworkStatus {
public static interface NetworkStatusCallbacks {
void onReceive();
}
public static class ConnectivityChange extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
// need to call NetworkStatusCallbacks onReceive here
}
}
}
Then in the main activity I would do something like,
public class MyActivity extends Activity implements NetworkStatus.NetworkStatusCallbacks {
#Override
public void onReceive() {
// Do stuff here
}
}
Would really appreciate some pointers. Thanks.
Possible Solution
Think I have found a solution. As Selvin pointed out, to do this requires the Activity. I therefore obtained the Activity by casting it from the activity context that is passed to a constructor for the NetworkStatus class, i.e., setting a constructor for the class as
private static nsc NetworkStatusCallbacks;
public NetworkStatus (Context context) {
Activity activity = (Activity) context;
nsc = (NetworkStatusCallbacks) activity;
}
I can then call the interface from the onReceive method of the BroadcastReceiver as follows:
public void onReceive(Context context, Intent intent) {
nsc.onReceive();
}
Try something like this:
public class NetworkStatus {
public static interface NetworkStatusCallbacks {
void onReceive();
}
private final NetworkStatusCallbacks m_cb;
NetworkStatus(NetworkStatusCallbacks cb)
{
m_cb=cb;
}
public static class ConnectivityChange extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
// need to call NetworkStatusCallbacks onReceive here
m_cb.onReceive()
}
}
}
I have created an application in which i am sending a broadcast to my activity and in this broadcast i am sending two values, one is type and other is a badge, i am receiving these values in my inner class which is extending BroadcastReceiver but when i am going to set these values in the TextView of my main class then it is not setting these values, i am not able to understand why is this happening.
Following is my main acitivity in which inner class is present, and it is extending BroadcastReceiver :-
import java.util.List;
import android.widget.ScrollView;
import android.widget.ViewAnimator;
public class TabActivity extends Activity implements OnClickListener{
static String type;
static String badges;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
................
}
public static class TabBroadcast extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
SharedPreferences shrd = context.getSharedPreferences("Gallery", context.MODE_WORLD_READABLE);
type = shrd.getString("type", "null");
badges = shrd.getString("badge_count", "null");
badge_tips_text.setText(badge);
/*Editor edit = shrd.edit();
edit.remove("type");*/
Toast.makeText(context, "" + type + "\n" + badge_tips_text.getText().toString(), Toast.LENGTH_LONG).show();
}
}
}
I am receiving the values but unable to set them in TextView, please reply any help will be appreciable.
Thanks
You can't reference instance(non static) TextView from a static inner class. Instead, pass the stuff required through constructor:
public static class TabBroadcast extends BroadcastReceiver{
private final TextView textview;
public TabBroadcast(TextView t){
this.textview = t;
}
#Override
public void onReceive(Context context, Intent intent) {
t.setText("works");
}
}
TabBroadcast is inner class of an Activity then try as to access UI elements :
public class TabActivity extends Activity implements OnClickListener{
static String type;
static String badges;
public TextView badge_tips_text; //<<<< TextView declare here
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
................
//<<<< initilze TextView here after setContentView
}
public static class TabBroadcast extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
if(TabActivity.this.badge_tips_text !=null)
TabActivity.this.badge_tips_text.setText(badge);
// your code here ...
}
}
}
and make sure you have initialized TextView before calling TextView.setText
This is happening because the broadcast receiver is running on a different thread. Try using a handler that is passed from your activity:
Where you create your broadcast class use:
new TabBroadcast(new Handler());
Pass the handler through the TabBroadcast constructor and now inside of your TabBroadcast onReceive, you can do the following:
handler.post(new Runnable() {
public void run() {
myTextview.setText("Text");
}
});
You will need to set myTextview as final
I would like to launch some other apps if my call is reaching others voicemail. How to detect it in android?
Thanks
You could listen to the broadcast of LISTEN_MESSAGE_WAITING_INDICATOR and then act upon it
http://developer.android.com/reference/android/telephony/PhoneStateListener.html#LISTEN_MESSAGE_WAITING_INDICATOR
You would extend PhoneStateListener and then initialize the class
public class VoicemailListener extends PhoneStateListener {
private final Context context;
public VoicemailListener(Context context) {
this.context = context;
}
#Override
public void onMessageWaitingIndicatorChanged(boolean mwi) {
//Message Recieved, do your work here
}
}