I have a problem !
I have 3 Activities, DB, and WebServer. Let say that every 20 min server clean my DB and fill it up with new Data. Every Activity use data from DB. How to refresh active activity automaticaly when new refresh of DB was done. Thanks.
I'd recommend sending a Broadcast each time the DB is updated and registering broadcastreceivers in each activity that needs to be informed of the update.
EDIT example:
In your DB-class, send this broadcast:
Intent intent = new Intent("my.db.updated");
context.sendBroadcast(intent);
In the Activities where you need to be informed of DB-changes:
public void onCreate(...) {
...
BroadcastReceiver receiver = new BroadcastReciever() {
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction.equals("my.db.updated") {
// Do something
}
}
};
registerReceiver(receiver, new IntentFilter("my.db.updated"));
}
I don't think you can push the new data. Take a look at timers and divide your activity like this onCreate -> init -> getData
and then put getData(); within a timer
Good luck
Related
I want to create an empty service that will just run in the background once a certain fragment is open - the service will fill an array in the background but is not used in the current (calling fragment):
Code to create the service:
Intent intent = new Intent();
intent.putExtra(ServiceActions.class.getName(), ServiceActions.GET_LIST_FROM_API);
intent.putExtra("api_code_id", "12345");
managerProvider.getRequestManager().startRetrievalService(intent);
Register & Unregister listener:
manager.registerReceiver(backgroundListReceiver , new IntentFilter(ServiceBroadcasts.GET_LIST_FROM_API_RESULT.name()));
manager.unregisterReceiver(backgroundListReceiver );
Then handle the receiver:
backgroundListReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
boolean result = extras.getBoolean(ServiceBroadcasts.GET_LIST_FROM_API_RESULT.name());
// DO Nothing here as the list is loading in the background
// and stored in the application class
}
};
I do register and unregister it in fragment, I guess I asking is this correct way to do it or is there another better process? The reason for doing it here is that the chance of the user selecting the list is quite high so I'm trying to preload the list prior to them selecting it.
Code to handle loading list in background:
private void getListInBackground() {
RequestResponse response = RestAPI.getListInBackground();
if (response.isSuccessful()) {
mApp.setBackgroundList(JacksonMapper.deserBackgroundList(response.getResponseString()));
}
Intent broadcast = new Intent(ServiceBroadcasts.GET_LIST_FROM_API_RESULT.name());
broadcast.putExtra(ServiceBroadcasts.GET_LIST_FROM_API_RESULT.name(), response.isSuccessful());
mManager.sendBroadcast(broadcast);
}
I have a background Service which updates the database in an Android App.
In the App this data is displayed, but I am having trouble finding a good way to trigger a refresh of the data.
Initially I just refreshed each time a view resumed, but that doesn't work obviously if the data is updated while the view is shown.
On iOS I use notifications, which I register in the view, and is triggered by the update process when completed. Is there a way to do something similar in Android to trigger an update on the UI thread from a background thread?
BroadcastReciever in your Activity is the best way to update Activity from the Service.
Activity:
BroadcastReceiver br = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
}
}
After that, all you need is to register some action for it in Activity:
public final static String BROADCAST_ACTION = "com.example.action";
IntentFilter intFilt = new IntentFilter(BROADCAST_ACTION);
registerReceiver(br, intFilt);
In your service you should build an intent and call sendBroadcast.
Service:
Intent intent = new Intent(MainActivity.BROADCAST_ACTION);
sendBroadcast(intent);
There's no need to use a BroadCastReceiver if you update your database and you're using a ContentProvider to saving your data to the db then whenever data change on the ContentProvider it should notify that data has changed and in your on your activity you use a CursorLoader then the Loader is notified and UI updated, this is very easy to do and has the advantage that a CursorLoader will run the thread on background see more here and here
I have a receiver, it does call details saving task like storing incoming call, outgoing call etc.. all these details goes to sqlite DB. If my activity is not running, then its fine.
Sometime, when my activity is running, i get some incoming call. the receiver runs & stores data to DB. UI wont get refreshed because it never knows about change in DB.
Here i need to manually tell from receiver that, if activity is running refresh screen. How to implement this process in android.
I'm slightly confused in this part
You can use a LocalBroadcastManager to send a local broadcast to your Activity (more efficient and more secure than using a global broadcast):
Intent intent = new Intent(action);
LocalBroadcastManager mgr = LocalBroadcastManager.getInstance(context);
mgr.sendBroadcast(intent);
http://developer.android.com/reference/android/support/v4/content/LocalBroadcastManager.html
Your Activity would have to register a BroadcastReceiver in onStart and unregister it in onStop:
private BroadcastReceiver mBroadcastReceiver;
mBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// do your thing
}
};
LocalBroadcastManager mgr = LocalBroadcastManager.getInstance(this);
mgr.registerReceiver(mBroadcastReceiver, new IntentFilter(action));
in onStop:
mgr.unregisterReceiver(mBroadcastReceiver)
Now that's the official Android way to do it. I most certainly prefer to use an event/message bus like Otto or EventBus (https://github.com/greenrobot/EventBus). You can use those to broadcast messages/events across different components in your app. The advantage is you don't need access to a Context (like you do when using Broadcasts), it's faster and it forces the developer to object oriented programming (since the events are always objects). Once you start using an event bus you'll never look back to local broadcasts and you'll replace many of the sometimes messy observer / listener patterns used across your app.
You can create a BroadcastReceiver inside an activity. Register it in onResume() and unregister it in onPause(). Whenever your other receiver receives a broadcast, send a broadcast to this receiver too. If the activity is running(i.e. on front), the broadcast will be received. Do whatever you want in its onReceive().
Example:
BroadcastReceiver br = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//Do stuff
}
};
Also override methods:
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(br);
}
#Override
protected void onResume() {
super.onResume();
registerReceiver(br, new IntentFilter("intent_filter"));//Use any string for IntentFilter you like
}
You can update fragments from activiy by creating methods inside fragment and access them from Fragment object inside activity.
I have some problems working with Android Services. I already have a Service which downloads a file from a server. (The Service checks cyclic for new data) Aftwerwards it parses the file and adds values to an ArrayList wich will be saved to SharedPreferences.
In my Activity there are two methods. One will display the values from the ArrayList/SharedPreferences in UI and the second method sets a Notification if needed.
But how do I now when my Service completed its task so the two methods can be started?
Register a BroadcastReceiver in your Activity something like:
myReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// do my stuff
}
};
registerReceiver(myReceiver , new IntentFilter("com.myapp.DOWNLOADCOMPLETE"));
Then in your service send the broadcast:
Intent i = new Intent("com.myapp.DOWNLOADCOMPLETE");
sendBroadcast(i);
You can also putExtras on your intent if you need to pass some values:
Documentation BroadcastReceiver
In my Android application, I have a simple list view with adapter. There's a heavy query which is to fill the list view with data. So I put it to an IntentService that runs in another thread.
The IntentService is normally running separately, on its own, just to query some data and insert it into the SQLite database.
But now I would like to have the following possibility:
The activity starts the IntentService with startService().
The IntentService does its heavy work.
When the IntentService is finished, it should inform the activity about the result so that the activity can be refreshed to show the new data.
Is this possible? I read a lot of questions here on Stack Overflow on this topic. But in every question, there was another solution. So I want to ask you all: Which solution is the best for my purpose?
Binding the IntentService to the Activity does not seem to be the best solution as there might be conflicts with configuration changes of the activity etc. Correct?
This blog post suggests using AIDL with Parcelables - which sounds very complex to me. There is an easier way, isn't it?
One could set up a broadcast receiver in the activity and fire this broadcast in the IntentService when it is finished.
Some people say you should use createPendingResult() to pass a PendingIntent to the IntentService. If the IntentService finds that PendingIntent in its extras, it uses this to trigger off onActivityResult() in the Activity. Is this the way to choose?
As an example, I use a ResultReceiver to call notifyDataSetChanged() on the adapter of my Activity (which extends ListActivity). It can be adapted to do whatever you need.
ResultReceiver code:
public class MyResultReceiver extends ResultReceiver {
private Context context = null;
protected void setParentContext (Context context) {
this.context = context;
}
public MyResultReceiver(Handler handler) {
super(handler);
}
#Override
protected void onReceiveResult (int resultCode, Bundle resultData) {
// Code to process resultData here
((BaseAdapter) ((ListActivity)context).getListAdapter()).notifyDataSetChanged();
}
}
MyActivity code:
public class MyActivity extends ListActivity {
private MyResultReceiver theReceiver = null;
...
private void callService () {
theReceiver = new MyResultReceiver(new Handler());
theReceiver.setParentContext(this);
Intent i = new Intent("com.mycompany.ACTION_DO_SOMETHING");
// Code to define and initialize myData here
i.putExtra("someData", myData);
i.putExtra("resReceiver", theReceiver);
startService(i);
}
}
IntentService code:
Bundle resultBundle = new Bundle();
ResultReceiver resRec = intent.getParcelableExtra("resReceiver");
// Do some work then put some stuff in resultBundle here
resRec.send(12345, resultBundle);
When the IntentService completes, it should use LocalBroadcastManager to send an intent to any registered activity.
The IntentService will contain code like this:
private void sendBroadcast() {
Intent intent = new Intent("myBroadcastIntent");
intent.putExtra("someName", someValue);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
The activity receiving the notification will contain code like this:
#Override
protected void onCreate(Bundle savedInstanceState) {
// ...
BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String someValue = intent.getStringExtra("someName");
// ... do something ...
}
};
LocalBroadcastManager.getInstance(this)
.registerReceiver(receiver, new IntentFilter("myBroadcastIntent"));
}
For more depth, see the blog post Using LocalBroadcastManager In Service To Activity Communications.
None of the other answers references the official android documentation
https://developer.android.com/training/run-background-service/report-status.html
that states clearly that for the Activity-IntentService communication "The recommended way to send and receive status is to use a LocalBroadcastManager, which limits broadcast Intent objects to components in your own app"!
I would suggest using a Broadcast Receiver in the The Activity waiting for the result.
Your Service would just use sendBroadcast with a custom Intent.
I think the event bus is the way to go. Simple and effective interprocess communication.
http://square.github.io/otto/
https://github.com/greenrobot/EventBus