Well I am having a stranger problem here in my android app.
I made an alarm that starts a service, something like this:
public class ExecutaAcoes extends Service implements Runnable {
protected static final String URL = "http://www.mysite.com.br"
#Override
public void onCreate() {
Log.i("Teste","Service started");
new Thread(this).start();
}
#Override
public void run() {
try {
Log.i("Teste","Thread started");
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet(URL);
HttpResponse response = client.execute(request);
HttpEntity entity = response.getEntity();
if (entity != null) {
...
} catch (Throwable e) {
Log.i("Teste","erro excepty: "+e.toString());
} finally {
};
So, every 30 seconds alarm manager starts the service and it accesses the webpage www.mysite.com.br. This code works fine in emulator but not on my device. When the phone sleeps (and the screen blackout) the webpage is not accessed and application returns an error in catch (Throwable e): "java.net.UnknownHostException: Host is unresolved" or return a socket error.
The strange thing is that if I press any button on the device and the screen lights up the application returns to work normally and the web site is accessed.
Does anyone know how to solve this problem?
Thanks for some help
Alexandre
This is normal. When device goes to sleep some functions are not available. AlarmManager holds a CPU wake lock, so that your onReceive() method gets executed when alarm goes off. Note that this only affects this method: if you start a service this guarantee does not extend to this service. Also, it only gives you CPU wake lock, meaning that CPU will be running, but not the screen and network.
To access the Wifi from your service you need to acquire the WifiManager.WifiLock. For 3g, screen and other functions see PowerManager.
Also, running network scan every 30s all the time will drain the battery in a matter of hours - users will not like this. Reconsider using server push (with wifi lock) or sync adapter.
You should try this http://developer.android.com/reference/android/net/wifi/WifiManager.WifiLock.html in order to keep the Wifi active until you finish the operation. When the phone sleeps, the Wifi closes. Hope this helps!
Related
my App get a Notification when i get time Like Alarm i Just want to Run my app on Background to Can Push my Notification when time come
i was Try to Search about that Problem and ask on Many Android Groups and i Use then a Thread but Nothing work
if (level==100){
Thread T1 = new Thread(new Runnable() {
#Override
public void run() {
// PushNotification Method
PushNotification();
}
});
T1.start();
}
The Code only Run when App Open but When Close the App the Code Not work
If you're trying to receive notifications from GCM, then create a WakefulBroadcastReceiver that can be used to receive the notification and handle it appropriately.
On the other hand, if you're trying to send a normal notification from within your app, then create your own background Service that can be used to send the notification. Here's a link to a similar SO answer that you can use for reference.
Most of the times we as programmers experience this problem, when we are in between of certain Asynctask doinBackground() Method - performing an operation which requires Network (Internet Connection), and if in between the network is lost then our Application results in Force Close or Crash, or FreeZed. To stop this we use try/catch operations to be used with the code.
I just want to know is there any perfect means to do the same, Scenario written below,
Here in my case:
I require Internet Connection after every 20secs to parse an API in the Asyntask, and based upon the result of the API, I have to update the UI on the screen.
Here is my Timer Method
timer = new Timer();
TimerTask task = new TimerTask() {
#Override
public void run() {
if(DCCStaticMethod.checkInternet(DriverMainMenuActivity.this)){
try {
if(mLocalAreaDriverPass.getStatus() == AsyncTask.Status.FINISHED){
mLocalAreaDriverPass = new LocalAreaDriverPass(DriverMainMenuActivity.this,true);
mLocalAreaDriverPass.execute();
Log.d("RefreshLocalAreaTimerDriver", "running");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
};
timer.scheduleAtFixedRate(task, 20000, 20000);
Suppose at any instant of time, the internet connectivity is lost or goes down, how to cancel and restart the timer again to achieve my requirement.
I HAVE SO MANY TRICKS AND CRANKS TO PERFORM THE SAME, BUT I AM IN SEARCH OF GOOD MEANS TO PERFORM THESE TYPES OF TASKS IN FUTURE, AS THESE TYPES OF TASKS OCCUR IN ALMOST ALL THE APPS
In Catch block first cancel the Timer and register a broadcast for Network Connection. In broadcast receiver start your timer again.Here are the docs for monitoring Network.
Make broadcast receiver for checking internet connection. and get status of that. if connection is lost then set value to variable of any application class or simple class and then use that variable in activity for stop timer.
There is a custom class CountdownTimerwithPause.By using this you can pause and cancel the timer in middle of Asyn Task
Refer the below link
How to extend CountDown Timer With Pause?
On my Android App, I'm implementing SignalR connection (https://github.com/erizet/SignalA) to connect to a Hub server to send requests and receive responses.
a sample of my code is as follows:
signalAConnection = new com.zsoft.SignalA.Connection(Constants.getHubUrl(), this, new LongPollingTransport())
{
#Override
public void OnError(Exception exception)
{
}
#Override
public void OnMessage(String message)
{
}
#Override
public void OnStateChanged(StateBase oldState, StateBase newState)
{
}
};
if (signalAConnection != null)
signalAConnection.Start();
There's also the sending bit
signalAConnection.Send(hubMessageJson, new SendCallback()
{
public void OnError(Exception ex)
{
}
public void OnSent(CharSequence message)
{
}
});
The sending and receiving will occur across activites, and some responses will be sent at random times regardless of the activity, also, the connection should be opened as long as the app is running (even if the app is running in the background) that's why I wish to implement the signalA connection as a background service
The question is should I implement it as:
1 - a Service (http://developer.android.com/reference/android/app/Service.html)
OR
2 - an Intent Service (http://developer.android.com/training/run-background-service/create-service.html)
Keeping in mind that I will need to send strings to the service and get response strings from the service.
I would be most grateful if someone would show me how to implement this kind of connection in code as a background service/intentservice.
Thanks for reading.
UPDATE:
Please see this demo activity made by the developer as how he implemented SignalA
https://github.com/erizet/SignalA/blob/master/Demo/src/com/zsoft/SignalADemo/DemoActivity.java
The problem is AQuery (which I know nothing about) is being used in this demo activity. Does AQuery run in the background all the time ?
The problem is, the latest update on SignalA mentions the following
I have changed the transport. LongPolling now uses basic-http-client
instead of Aquery for http communication. I've removed all
dependencies on Aquery.
Hence I'm not sure whether I should follow this demo activity or not
Update 2:
This is the thing that is confusing me most
in the IntentService, the OnHandleIntent method calls stopSelf after it finishes its tasks, when I actually want the code in the IntentService to keep running all the time
protected abstract void onHandleIntent (Intent intent)
Added in API level 3
This method is invoked on the worker thread with a request to process. Only one Intent is processed at a time, but the processing happens on a worker thread that runs independently from other application logic. So, if this code takes a long time, it will hold up other requests to the same IntentService, but it will not hold up anything else. When all requests have been handled, the IntentService stops itself, so you should not call stopSelf().
SignalA is running on the thread that creates and starts the connection, but all network access is done in the background. The remaining work on the starting thread is really lightweight, hence its perfectly ok to do it on the UI tread.
To answer your question, you need to have a thread running the signala connection. Therefore I think a Service is the best choice since SignalA need to be running all the time.
Regarding Aquery and the demo project. I removed all dependencies to Aquery in the libraries, not in the Demo. To be clear, you don't need Aquery to run SignalA.
In my case, what I wanted was a Service not an Intent Service, since I wanted something that would keep running until the app closes
I have been searching about this but I did not find my specific question. I understand that AskyncTask can be canceled using .cancel(true) but this only happens if I have a loop in which I can check the value isCanceled().
But my question here is.. how can I cancel an AsyncTask (that is stuck in httpclient.execute() ) when the user presses back? If the user navigates away from that Activity and goes to another I dont want to have an uncontrolled number of AsyncTask running because this may lead to memory problems, the user could navigate back and forth and create undetermined number of tasks. That is why I want to close them. Anyone knows a way? I post the code I use to connect:
public class Test extends Activity {
#Override
protected void onStart() {
super.onStart();
new ConnectionTask().execute("https://www.mywebserver.com/webservice.php?param1=test");
}
private class ConnectionTask extends AsyncTask<String, Void, String>{
#Override
protected String doInBackground(String... params) {
try {
HttpClient httpclient = DefaultHttpClient(params,clientConnectionManager);
HttpPost httpPost = new HttpPost(params[0]);
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
if(httpEntity != null)
return EntityUtils.toString(httpEntity);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
}
Do you know what I should add in onStop() to cancel the ongoing httpClient.execute() function? Sometimes gets stuck almost forever.
I would really appreciate your help, thank you very much in advance.
UPDATE
If I close the ConnectionManager I have to do the handshaking for https again, right? Look at this code when I create the httpClient, I use this for https:
HttpClient httpclient = DefaultHttpClient(params,clientConnectionManager);
Thank you all for your quick responses and the variety of solutions exposed here. I will try to use the timeouts (for not having to wait too much) + the cancel() function to avoid processing onPostExecute. I will tell if the results are as expected! Thank you very much you all!
according to HttpClient docs, use HttpUriRequest#abort() to abort request
1.4. Aborting requests
In some situations HTTP request execution fails to complete within the expected time frame due to high load on the target server or too many concurrent requests issued on the client side. In such cases it may be necessary to terminate the request prematurely and unblock the execution thread blocked in a I/O operation. HTTP requests being executed by HttpClient can be aborted at any stage of execution by invoking HttpUriRequest#abort() method. This method is thread-safe and can be called from any thread. When an HTTP request is aborted its execution thread - even if currently blocked in an I/O operation - is guaranteed to unblock by throwing a InterruptedIOException
There is a cancel() method in AsyncTask class. Maintain a member to asynctask and cancel it in onDestroy(). then set the member to null.
Update
Use ClientConnectionManager to shutdown the connection.
http://developer.android.com/reference/org/apache/http/conn/ClientConnectionManager.html
Update 2
Check this link to set the timeout for your connection.
How to set HttpResponse timeout for Android in Java
In onPause() or onBackButtonPressed(), call cancel() on your task. In doInBackground() right after
HttpResponse httpResponse = httpClient.execute(httpPost);
Check isCanceled() and immediatelly return if true.
Of course, you still have a risk of having multiple tasks running, but since this operation is UI driven (that is task started by user interactions) there should be at most couple of them running at the same time, provided that timeout on HttpClient is reasonable.
Update
You can shutdown connection manager as well once you determine that the task needs to be canceled. see docs
That should close sockets and cause immediate return from execute(). Connection manager is set when you create DefaultHttpClient.
My understanding is that httpClient.execute() is blocking, so there is no code running to check the value of isCancelled(). And you'd prefer not to close the Connection Manager.
This might be a bit hacky, but in lieu of any better solutions, what happens if you call Thread.interrupt() on the Thread whilst httpClient.execute() is blocking?
A quick test can verify this, just add private instance variable of type Thread inside your ConnectionTask definition, set it to Thread.currentThread() at the top of doBackground(), and add a public method that calls .interrupt() on it.
If you're lucky that will cause httpClient.execute() to immediately exit, throwing an Exception. You can catch that and do any tidup you need to before the method call ends and the AsyncTask ends naturally.
You can override
onPause() method of the activity and write the stop connection code there. If the option is specific to back button then you can override
onBackButtonPressed() method to stop the execute.
Well there is a quick solution for this problem which I used to solve in my case. It may not be the correct way, as when you press back the app will respond immediately but in background network operation will continue (until timeout if you set) without blocking the application:-
Do all you network operation in a new Service say NSERV. Make the NSERV extend the Thread class and do all you network operation in the run method. For more clarity in your code better make the activity/service starting the NSERV also extend Thread class and start the NSERV from their run method.
Then use static fields or singleton to access the variables in the activity/service from NSERV.
EX:
public class NSERV extends Service implements Runnable{
public int onStartCommand (Intent intent, int flags, int startId)
{
Thread t = new Thread (this, "abc");
t.start();
return super.onStartCommand(intent, flags, startId);
}
public void run()
{
//NETWORK OPERATION...
onDestroy();
}
public void onDestroy()
{
stopSelf();
super.onDestroy();
}
}
I am having a problem where my service is being killed even though I am holding a wake lock and I have called startForeground. When this occurs the tablet (ASUS Transformer TF101), stops the service without calling onDestroy. There are no other apps visible, and log cat shows nothing out of the ordinary (no 'out of memory' message etc). Immediately after being killed, the service restarts.
The app I am developing is a chat client and needs a constant connection, it is also plugin based, so my app is developed as such: Client - HostService - Multiple child 'Services'.
The host service is sticky holds the wake lock and calls startForeground (and displays a notification as such), the child services are not sticky, do not hold wake locks and are background services.
If the client itself is open the issue does not occur, but the model I am going for is that the user can use the device and stay connected (receiving messages etc) without having the client itself open at all times.
Can anybody offer any explanation as to why the service is being killed in this way, and if so prevent it from happening? As the chat clients show when a user logs on and off, and the service dying kills all open connections, this makes the chat client 'bounce'. At present it seems to happen somewhere between every 15 and 45 minutes.
Also, if anybody is aware of a way to keep a socket connection open continuously without holding a wake lock for the entire connection duration, I would love to hear it!
The trimmed test case version of the host service source is below.
public class HostService extends Service
{
PowerManager m_powerManager = null;
PowerManager.WakeLock m_wakeLock = null;
#Override
public IBinder onBind( Intent intent )
{
return m_serviceImplementation;
}
#Override
public void onCreate()
{
super.onCreate();
}
#Override
public void onDestroy()
{
if( m_wakeLock != null )
{
m_wakeLock.release();
m_wakeLock = null;
}
stopForeground( true );
super.onDestroy();
}
#Override
public int onStartCommand( Intent intent, int flags, int startId )
{
// Display a notification about us starting. We put an icon in the
// status bar.
Notification notification = createNotification();
startForeground( R.string.service_running, notification );
if( m_powerManager == null )
{
m_powerManager = (PowerManager)getSystemService(Context.POWER_SERVICE);
}
if( m_wakeLock == null )
{
m_wakeLock = m_powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Keep background services running");
m_wakeLock.acquire();
}
// We want this service to continue running until it is explicitly
// stopped, so return sticky.
return START_STICKY;
}
/**
* Create a notification to show the service is running
*/
private Notification createNotification()
{
CharSequence text = getText( R.string.service_running );
CharSequence title = getText( R.string.app_name );
// The PendingIntent to launch our activity if the user selects this
// notification
PendingIntent contentIntent = PendingIntent.getActivity( this, 0, new Intent(this, MainChat.class) , 0 );
Notification notification = new Notification( android.R.drawable.sym_action_chat, title, System.currentTimeMillis() );
notification.setLatestEventInfo( this, title, text, contentIntent );
return notification;
}
private final IMessageInterface.Stub m_serviceImplementation = new IMessageInterface.Stub()
{
...
};
}
Android Manifest (relevant bits):
<uses-sdk android:minSdkVersion="11" android:targetSdkVersion="11" />
<service android:name="com.mydomain.chatClient.server.HostService" android:exported="true" android:enabled="true" android:process=":remote"/>
<uses-permission android:name="android.permission.WAKE_LOCK" />
I am having a problem where my service is being killed even though I am holding a wake lock and I have called startForeground.
startForeground() reduces the likelihood of a service being killed, but it does not prevent it.
The app I am developing is a chat client and needs a constant connection, it is also plugin based, so my app is developed as such: Client - HostService - Multiple child 'Services'.
I recommend getting rid of one of those layers. Even if the OS doesn't shut you down, many users will (e.g., task killer, Running Services in Settings), considering you to be running too many services.
If the client itself is open the issue does not occur, but the model I am going for is that the user can use the device and stay connected (receiving messages etc) without having the client itself open at all times.
I recommend making that optional. You may think it's sexy. Some of your users will attack you for wasting their battery.
Can anybody offer any explanation as to why the service is being killed in this way, and if so prevent it from happening?
I'd start by getting rid of android:process=":remote". You don't need it. You don't want it. You may be hurting yourself by having it, as it may accelerate Android's interest in getting rid of your service. You absolutely are hurting users by having it, because you are wasting RAM for no good reason.
Then, I'd get rid of the plugins, if you implemented those as separate applications. In that case, each one of those will be running in its own process, wasting yet more RAM. Besides, your current implementation would be flawed, as you would be stuck having your service be named com.mydomain.chatClient.server.HostService until the end of time, since you didn't use an <intent-filter> to separate the concerns of "what the service is named internally" and "what the service is called by other separately-installed applications that wish to use it". And if you didn't implement the plugins as separate applications, then I fail to see the value in having them be in separate services, rather than folding them all into the one service.
Also, if anybody is aware of a way to keep a socket connection open continuously without holding a wake lock for the entire connection duration, I would love to hear it!
If the socket is on wireless data, instead of WiFi, you do not need a WakeLock all the time. The socket will remain open, and incoming packets on that socket will wake up your code. At that point, you'd want to grab a WakeLock long enough for you to do whatever you're doing with the data when it arrives, then release the WakeLock.
If you are on WiFi, though, this trick doesn't work, so a WakeLock (and probably a WifiLock) will be required.