I'm writing an Android App that receives text messages from a server via HTTP. I have a button on my App labeled "Poll". When I press this button, the App Polls the a server via HTTP and fetches some text messages.
These texts messages are to be sent out via SMS. What I would like to happen, is for there to be a background queue where these messages are added to. As soon as a message is added to the queue, the queue must immediately be attempted to be "flushed" (i.e. send all pending SMSs over the network). If the sending fails, the App must retry by itself every 60 seconds indefinitely.
What is the best way to achieve this? I guess I'm looking for some form of implementation where an IntentService has a timer that expires every 60 seconds, but can be forced to be expired on demand once a new text message comes in.
I'm ok regarding SMS functionality, as I've been following this guide: http://mobiforge.com/developing/story/sms-messaging-android
It's just the queue handing I need some help with.
Any help is appreciated, thanks
Related
I have been trying to develop an android app like whatsapp, hike, etc....
I'm using SQLITE DATABASE to store messages local including images byte-codes.
I'm using the Runnable Handler with postDelayed() method of 3 seconds, which means every 3 seconds, the application connects with server for new messages and status be drawn, updated in listView and saved in sqllite database.
Now I'm facing trouble if the number of incoming messages are more say 150-200 messages.... the handler re-launch the code before the previous all 150 messages stored in database.
handler = new Handler();
handler.post(runnableCode);
Runnable runnableCode = new Runnable() {
#Override
public void run() {
if (check.check(1)) { //Check for Network Connection
asyncExecute = false;
getNewMessages(); //Calling method of asynctask for New Messages
}
handler.postDelayed(this, 3000); //Run this every 3 seconds
}
};
So, what I want is, till all my messages get saved in database and images downloaded completed, the handler should not be called. After saved and downloaded fully, the next handler should be called.
Tell me the best way to achieve this.
The way you did it may work but it's not a good way of doing it.
The way you got your solution together have a huge performance problem of consuming a lot of battery from the celular radio by keeping keeping it awake everytime even when the server doesn't have anything new.
If you want a more detailed explanation about this you can check it here.
To solve this problem you can do it in two ways:
1- Implement Google Cloud Messaging(GCM) on your app and server. When the user first opens the app you register the device to GCM, get key generated for you representing your device and send it to your server so that you can save it along side the user information.
Whenever a message comes for this user, all you need to do on your server is to look for the user devices IDs(multiple if you let him sign in on different phones at same time or single) and send a message to GCM passing the device id and the payload.
On your app side you can implement a broadcast receiver that waits for incoming GCM messages and you process them as you like.
2- The second way, that I think it is simpler is to user the new GCMNetworkManager to help you with this and also some more features as scheduling tasks etc.
Have you thought on a bidirectional connection with the server? If you make one for example, with WebSockets the client could just need to wait for new updates coming from the server in real time.
Here you have an example of socket.io (a WebSockets library) working on android:
Native socket.io and android
Another library including support for HTTP, Websocket, raw sockets and socket.io
AndroidAsync
In Android, i have a socket keeping real-time communication with the server.
This app socket is being controlled by a service, that starts on boot and / or whenever a request is being emitted by the app.
Because I cannot depend on Google PlayStore, I fully control the sending + receving of push-messages manually.
Whenever a new push-message arrives from the server, the socket-service sends a local broadcast message and the listening activities can follow there own action.. If no activities are found, a default android notification is given to the user, saying '[ap] You have {n} new message(s)'...
This has its stability problems (the service can be shut down by the OS when low on memory for example) but its okay.
Now, consider the following:
I have multiple activities that listens-for and shows a count of unread messages.
HomePage
ConversationsOverviewPage
'The' conversation page (chatpage)
Each activity can be on the foreground, but can also be in memory for when the user back-presses and goes back 1 activity. So in Theory, there can be a situation where you want to update different/multiple activities at once.. This prevents having to 're-load' the unread messages from the server when the user gets back to a 'savedInstance'. So the broadcast pattern works best I think.
What is best practise for keeping global track of unread messages, while minimising the server trip on every activity instance:
Very simpel: Make a server request on each and every activity instance, and write update code again for every activity. But this results in the user seeing a delay, as it takes a second before the app receives data from the server and show the 'unread-messages' balloon.
Simpel: Have a global class.. Holding the unread messages for each conversation, But I feel this can give problems with data being incomplete.. Especially when the app is not 'active'
My old vote: Have another service thats keeping track of the unread messages, that starts on boot (just like the socket).. Only when the service starts / boots, it will requests all unread-messages data from the server. Each activity can than 'ask' for the unread-messages data and don't have to worry about it anymore.
But this could be overkill?
My new vote: Keep the socket-service, and add a separate class to this service.. That holds the unread-data.. But this also does not feel to be right.. As the activity would have to ask the service something out-of-scope.. Its not the sockets concern to manage unread messages (separation of concerns), right?
Any thanks from experienced developers is much appreciated!
Third options is ok. Not sure where is overkill exactly. Obviously you shouldn't download all unread messages on every boot or socket reconnection. The most important rule of thumb is to load data when the app really needs it. Few moments about how I've developed about the same app:
there is socket Service which handles connecting, disconnecting, sending data(messages) and receiving data.
there is Notification manager which receives events from SocketService. It saves new data which comes from server and decides which broadcast notification should be sent.
when socket is connected it receives state data from server:
dates(timestamp) of last update for every chat. For instance if local database contains that chat A was updated yesterday but freshly received data from server says that the chat A was updated few seconds ago you need to broadcast event like chat A has been updated since last connection and save update date. If there there is any activity which somehow show the chat A it loads(through http or whatever) new data.
last messages for every chat. The app just compares locally saved last messages and freshly received. If there is new one the app again broadcast event like there is unread message/messages from user x. If there is visible activity which shows updated chat it updates data otherwise the app shows notification.
So the basic flow of handling unread messages is next: connect to the server > check if there is data about unread messages > save new data to the local database > broadcast events about new data.
And I would recommend you to use GCM and socket connection simultaneously. GCM really helps to keep data updated. It wakes up a phone and sometimes delivers data when socket connection just could not be established due to network problems.
I've implemented instant messaging through GCM. At the time of sending I show dummy message until app receives acknowledgement.
In this process user can send multiple messages. all through AsyncTask. Sometimes messages are not sending in queue.
My question is:
Is there any method to send messages in queue?
You can take look at these superb queuing library one from Path team and other from Sqaure team
https://github.com/path/android-priority-jobqueue
https://github.com/square/tape
I also heard about "GCM Network Manager" last week in google i/o, check that too.
https://developers.google.com/cloud-messaging/network-manager
I am a web developer and writing services for android. The android developer, whom with I am working, is sending multiple async calls to the server, and asking me to send a service code with in the response of each service, as he will able to decide about a particular response belongs to which service that he sent before.
Is'nt there a way in android to keep track the responses of multiple async calls? Why should the server tell to android that which service is served.
There is no need for the server to send any code . He could send each http request using IntentService with a key. On each response from your server, he puts the key in a bundle, compare it and do what he wants.
See this code : https://github.com/JCERTIFLab/jcertif-android-2013/blob/master/src/com/jcertif/android/fragments/InitialisationFragment.java
I think their is no need of service code to keep track of the response-request pair, because if 5 threads sends the 5 different request, then, all of them receive their responses only.
Order of retrieval of response may vary.
Lets assume a condition,
ThreadA sends requestA.
ThreadB sends requestB.
Then,
ThreadA receives responseA only.
ThreadB receives responseB only.
Order variation:
ThreadB response may come before ThreadA.
I am currently trying to design a particular application and I don't really know how. The app has to run like this.
What I have to do :
The user launches the application. This action starts something independent of the UI (a Service currently), which has to request a remote server to get test scenario, execute the tests and send results to the same server, even if the UI of the application is not on the screen.
Second constraint : the user chooses, at the beginning, the time between two requests of scenario from the server.
Example : The user starts the app, chooses "do one request of test scenario every 5 min" and after, he can do what ever he wants on his phone. And the app, every 5 min, send a request to get test scenario (not one, but a various number, 50 for example), do the test scenario, and send the results to the server ; and then, wait for the next request.
During this, I think a notification icon in the status bar could be a good thing to access to the UI of the app. With that, when the user feels that the app has done enough tests, he can access to the UI and stop the app.
What I have already done :
I create an Activity which creates a Service. I also set an alarm with AlarmManager, received with an AlarmReceiver which calls the Service every X min/seconds/... and starts in the Service a request to the server to get the scenario (the http request is done in an AsyncTask). The service puts a notification in the status bar in its onCreate() method. I also managed to parse JSON, send HttpRequest and just technical things like that.
What my problems are :
I find that the Service stops itself at the end of the onStartCommand(). It finishes the method and then go to onDestroy() (where I don't put stopSelf()), but is the Service really closed ? If yes, how could I managed to have it "up" during all the duration of the application ?
The notification in the status bar just appeared and disappeared with the rythme given by the AlarmManager. How could I "stabilize" it ?
If you have already designed an app like that (a mail app, I think, is a good example, which request the mail server every X minutes to check new mail, and send a notification), how can I reach my goal ? To reuse the mail app example : is the service which checks the new mail on the server is always running ?
I really don't know how to design this king of app, so any help is welcome.
Sorry for my bad English. If you want precisions, code of the Service, the Activity, just ask.
Regards
Looks like your Service is running on the UI thread. You should create a new thread inside your Service, where all networking operations will work. So, there is no need in AlarmManager - just wait X milliseconds inside your Thread.
P.S. If you don't know how to create new thread:
new Thread(new Runnable(){
public void run(){
//your code here
}
}).start();
but I highly recommend you to read about multithreading first.