Delete data from database not working in broadcast receiver in Android - android

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

Related

LifeCycleOwner in Broadcast reciever

I am using Android Room to store my application data. After device reboot I need to retrieve them and do some functions. I am using LiveData for getting data from database. But I cannot bind Broadcast Reciever as owner. How should I resolve this problem?
public class BootReciever extends BroadcastReceiver {
#Override
public void onReceive(final Context context, Intent intent) {
if (context != null) {
ProductUIRepository mRepository = new ProductUIRepository(context.getApplicationContext());
mRepository.findAllProducts().observe(this, new android.arch.lifecycle.Observer<List<ProductUI>>() {
#Override
public void onChanged(#Nullable List<ProductUI> productUIS) {
NotificationMan.setAlarmForProducts(context, productUIS);
}
});
}
}
}
using "this" makes that applications isn't compiling.

Android how to start a database operation from a broadcast receiver if I cannot pass application context

In my app, when a Broadcast Receiver does what it does, I want to start a database operation as well, but the class that handles the database operation reqiures an instance of the DB singleton, which I usually hold in the application object, which is not accessible through the service context
Here is what happens:
This is my database handler:
public class DatabaseManager extends SQLiteOpenHelper {
// Its a good practice for DBTools to be a singleton. Do not instantiate it with "new DBTools(context)" but with
// DBTools.getInstance(context) instead
private static DatabaseManager sInstance;
public SQLiteDatabase database;
public static DatabaseManager getInstance(Context context) {
if (sInstance == null) {
sInstance = new DatabaseManager(context);
}
return sInstance;
}
public DatabaseManager(Context context) {
super(context, Preferences.LOCAL_SQLITE_DATABASE_NAME, null, 1);
}
In my Application Class I instatiate it this way:
// SQLite Database Handler
public DatabaseManager databaseManager;
#Override
public void onCreate() {
super.onCreate();
databaseManager = DatabaseManager.getInstance(this);
in my receiver I want to start a database operation:
public class PushNotificationReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
//DatabaseManager databaseManager = DatabaseManager.getInstance(context); -> This didnt work when the database was closed in onDestroy of my app.
new IncrementProgressIntoDB(context, eventId).execute();
and this is IncrementProgressIntoDB
public class IncrementProgressIntoDB extends AsyncTask<Void, Void, Boolean> {
private int eventId;
private Context context;
public IncrementProgressIntoDB(Context context, int eventId) {
this.context = context;
this.eventId= eventId;
}
#Override
protected Boolean doInBackground(Void... params) {
((MyApplication) context).databaseManager.database.beginTransaction();
and in this last line, I get the following exception:
06-02 10:45:00.552: E/AndroidRuntime(7778):
Caused by: java.lang.ClassCastException: android.app.ReceiverRestrictedContext
cannot be cast to com.asdqwe.asd.MyApplication
I tried the solution from here: Static way to get 'Context' on Android?
but the context that I got was unable to resolve the databaseManager as a field.
In the onReceive() method of your BroadcastReceiver, replace:
new IncrementProgressIntoDB(context, eventId).execute();
with:
new IncrementProgressIntoDB((MyApplication)context.getApplicationContext(), eventId).execute();
Try this. It should work.

How to make dynamically registered receive from outside of activity ?

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.

Calling a activity method from a BroadCast Receiver

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

How to Interface onReceive Method

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()
}
}
}

Categories

Resources