IOException during HTTP request in BOOT_COMPLETED - android

I have an Android application that has this statement that posts data to the server.
HttpResponse httpresponse = httpclient.execute(httppost);
When I start the application, this statement executes fine. I have made my application automatially start after booting. When it boots up, I am getting an IOEXCeption at this line with message my hostname. The host is running all the time as the same statement works fine when I start the application manually. This issue occurs only when the phone boots up.
Has anyone encountered this issue before?
CommansWare,
I have this new method in my onReceive call to check the network connection. With this my problem is resolved, meaning it posts the "in boot Completed" message and goes on executing the http request successfully but it looks like it does not exit the while look as the "not online" message showing up endlessly. How can it happen? Is this not the correct solution?
public void onReceive(Context context, Intent intent)
{
while(!isOnline(context) )
{
Toast toast = Toast.makeText(context, "Not online", Toast.LENGTH_SHORT);
toast.show();
}
Toast toast = Toast.makeText(context, "in boot completed", Toast.LENGTH_SHORT);
toast.show();
}
}
protected boolean isOnline(Context context) {
ConnectivityManager cm = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnected())
{
Toast toast = Toast.makeText(context, "returned true", Toast.LENGTH_SHORT);
toast.show();
return true;
}
else
{
Toast toast = Toast.makeText(context, "returned false", Toast.LENGTH_SHORT);
toast.show();
return false;
}
}

There may not be an active Internet connection at that point in time. After all, the device just powered on from being turned off. This is no different than any other OS.
You may need to do something to delay your HTTP operations until such time as an Internet connection is available. For example, your BOOT_COMPLETED receiver could use AlarmManager and set() to arrange to get control again in a few minutes, by which time the device will hopefully be more stable. Of course, you will also want to use ConnectivityManager to determine whether there is an Internet connection at that time as well, and you may prefer to do some sophisticated receiver work to listen for a ConnectivityManager broadcast, to perhaps do your HTTP work a bit more quickly than you would get with the AlarmManager route.

Related

get notification before connectivity changes

I am working over a project. In this, I am running a background service, in this their is connection between device and server. I want when device is connected to internet the service gets started and connection gets builtup between server and device and when internet disconnected the connection between server and device also gets disconnected
For this I have to send request to disconnect the connection, but that also requires internet connection that is currently not available.
So I want to disconnect the connection between server and device before internet gets disconnected. For this I need the stage i.e prior to internet disconnected that may be like Going to disconnect internet.
The code I tried is not sufficient for this work
public class NetworkChangeReceiver extends BroadcastReceiver {
#Override
public void onReceive(final Context context, final Intent intent) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
try{
if(netInfo.isConnected() && netInfo != null){
System.out.println("Connected to internet");
context.startService(new Intent(context,MessageService.class));
}
}catch(NullPointerException e){
System.out.println("Not Connected to internet");
context.stopService(new Intent(context,MessageService.class));
}
}
}
Can anyone tell any soln for this?

How To Connect my android Application To Internet Automatically whenever network found

My android application is based on network connection i.e WIFI/Mobile Network. It works fine when my mobile is connected to internet but when internet connection disconnected it stops working (obesely) and it still stop working after my mobile again connected to internet.
I wish to (re)start my application automatically whenever internet connection is (re)established.
You can check the network state using broadcast receiver. Whenever the network is available, you can start your application.
First, create a background service and start your service when the device boots up. Now, in this service, register a broadcast receiver and monitor the network state. If the network is available, you can start your application; and if unavailable, you can close it.
Please refer to the code below for broadcast receiver.
public class BroadCastSampleActivity extends Activity
{
/** Called when the activity is first created. */
#Override
protected void onCreate(Bundle savedInstanceState)
{
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
this.registerReceiver(this.mConnReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
}
private BroadcastReceiver mConnReceiver = new BroadcastReceiver()
{
public void onReceive(Context context, Intent intent)
{
boolean noConnectivity = intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
String reason = intent.getStringExtra(ConnectivityManager.EXTRA_REASON);
boolean isFailover = intent.getBooleanExtra(ConnectivityManager.EXTRA_IS_FAILOVER, false);
NetworkInfo currentNetworkInfo = (NetworkInfo) intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
NetworkInfo otherNetworkInfo = (NetworkInfo) intent.getParcelableExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO);
if(currentNetworkInfo.isConnected())
{
Toast.makeText(getApplicationContext(), "Connected", Toast.LENGTH_LONG).show();
}
else
{
Toast.makeText(getApplicationContext(), "Not Connected", Toast.LENGTH_LONG).show();
}
}
};
}
I think you must need to checking continue for network connections, that means you need to check for internet connection in background tasks. Android Services is better option for that, create one Service and start it when your app starts, inside that just do one code and that is for checking Internet Connectivity, when it lost, do some task and when it found you can do whatever you want. So I suggest you to use services and get your task done.
Here are some links to refer.
http://www.tutorialspoint.com/android/android_services.htm
http://www.vogella.com/tutorials/AndroidServices/article.html
I think you should create a spread thread or service in background for checking network connection after some interval . use following code in thread or service whatever you want to create .
NetworkInfo i = conMgr.getActiveNetworkInfo();
if (i == null)
return false;
if (!i.isConnected())
return false;
if (!i.isAvailable())
return false;
return true;

How to detect device status Offline/Online in Android

I am noob in Android. I want to display device status at web dashboard whether device is offline/online. Is GCM helpful for this to do or something what should I use for this .
Or Should I call any Web API continuous to send the phone status from phone to server until phone is ON so that I can display here "Online" status of phone at web dashboard ??
Offline status when your device is OFF & Online status when your device is ON
Any idea ??
Step 1 -> Register for the Broadcast Receiver to check for device status offline/online.
Inside the onReceive() method of the Broadcast Receiver, check for network changes, if there is a change go to step 2.
Step 2 -> Get the device status and call the web api along with the POST parameter "device_status".
Use the below API to get status for Internet Connectivity.
public boolean testNetwork(Context context) {
ConnectivityManager connManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
if ((connManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) != null && connManager
.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).isConnected())
|| (connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI) != null &&
connManager
.getNetworkInfo(ConnectivityManager.TYPE_WIFI)
.isConnected())) {
return true;
} else {
return false;
}
}
BroadcastReceiver networkStateReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
boolean connectivity = CommonUtils.getInstance().testNetwork(
BaseActivity.this);
if (!connectivity) {
// write your code
} else {
//write your code
}
}
};
IntentFilter filter = new IntentFilter(
ConnectivityManager.CONNECTIVITY_ACTION);
try {
registerReceiver(networkStateReceiver, filter);
} catch (Exception e) {
e.printStackTrace();
}
use this method :
You should not send ping to server.Server should send ping after some time interval to the device and device should reply. If device is not replying this means user is offline. Basically you need to create socket connection with server and exchange ping
same thing is implemented on openfire server
public boolean isOnline() {
ConnectivityManager conMgr = (ConnectivityManager) getActivity()
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = conMgr.getActiveNetworkInfo();
if (netInfo == null || !netInfo.isConnected() || !netInfo.isAvailable()) {
/*
* Toast.makeText(getActivity(), "No Internet connection!",
* Toast.LENGTH_LONG).show();
*/
return false;
}
return true;
}
and call it like
if (isOnline()) {
//code if online
} else {
AlertDialog alertDialog = new AlertDialog.Builder(getActivity())
.create();
alertDialog.setTitle("Info");
alertDialog
.setMessage("Internet Not Available, Cross Check Your Internet Connectivity and Try Again!");
alertDialog.show();
}
Implement XMPP Protocol along with any Jabber server.
It gives you correct info because it was created to make the offline/ online system
for help use link below
https://xmpp.org/about/

notification is displaying in other apps also

I am using the following code to check the internet connection in my entire app.
public class UpdateReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager connectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetInfo = connectivityManager
.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
boolean isConnected = activeNetInfo != null
&& activeNetInfo.isConnectedOrConnecting();
if (isConnected){
Log.i("NET", "connecte" + isConnected);
Toast.makeText(context, "net Connected", Toast.LENGTH_LONG)
.show();
}
else{
Log.i("NET", "not connecte" + isConnected);
Toast.makeText(context, "No Internet Connection", Toast.LENGTH_LONG)
.show();
}
}
}
The problem is when their is no internet connection/wi-fi signal, the toast message is displaying in other apps too.. how do I avoid that?
Thanks:)
Create an application class:
public class MyApplication extends Application {
private static MyApplication instance;
// Returns the application instance
public static MyApplication getInstance() {
if (instance == null)
instance = this;
return instance;
}
}
Add to manifest:
<application
android:name=".MyApplication"
... >
In your broadcast receiver:
Toast.makeText(MyApplication.getInstance().getApplicationContext(), "No Internet Connection", Toast.LENGTH_LONG)
.show();
Use this or getBaseContext() instead of contex .
You are using BroadcastReceiver receiver to check whether there is an internet connection. This will get executed whenever there is a change in network connectivity irrespective of the application. Since you are new, I'll explain it.
We can relate Broadcast receiver to a radio which listens for certain type of broadcasts and Broadcast is something which is send by the android system when ever an event occurs. So if the event is of the type of your broadcast receiver, you will get it.
So from your application if you just need to check for connection, you can simply create a method and call it.
public boolean isNetworkAvailable(Context context) {
ConnectivityManager connectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetInfo = connectivityManager
.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
boolean isConnected = activeNetInfo != null
&& activeNetInfo.isConnectedOrConnecting();
if (isConnected){
Log.i("NET", "connecte" + isConnected);
Toast.makeText(context, "net Connected", Toast.LENGTH_LONG)
.show();
}
else{
Log.i("NET", "not connecte" + isConnected);
Toast.makeText(context, "No Internet Connection", Toast.LENGTH_LONG)
.show();
}
return isConnected;
}
Call this method, whenever you need to check the connection.
OR
if you need to get notified of the above event changes as you require above, you can use the same broadcast receiver and instead of registering the broadcast receiver in Manifest file, register it from code of your application when it starts and unregister it when your application ends.
I am sorry to say none of the answers actually answers the original question "... the toast message is displaying in other apps too.. how do I avoid that?"
Toast is shown irrespective of which app is on the top. It is designed that way. So you can not 'avoid' that. You have to avoid using Tosat to avoid this behavior. The receiver acts in the background and shows a Toast. It does not bother which app is being shown currently to the user.
Please check this link also.
http://developer.android.com/guide/topics/ui/notifiers/toasts.html

Turn on the Internet on Android when in sleep

I have an Android app that needs to sync to the internet, but as soon as the phone goes to sleep I can't access the internet. It only happens when the user uses the "battery mode", when it turns off the data after 15 minutes. I wrote a test app and its turning the data on, but it still does connect to the server.
What I tried:
When I turn the data manually off, then the app is turning it on and it works
I also tried WakeLock, but it did not help.
The alarm works as expected, even when the phone goes to sleep for hours
Tested on Motorola Atrix Android 2.3.3. I can't rely on Wifi. In real life it will sync every week. How can we make it possible?
AlarmManager:
alarm_manager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, AlarmReceiver.class);
PendingIntent pending = PendingIntent.getBroadcast(this, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
alarm_manager.setRepeating(AlarmManager.RTC_WAKEUP,
System.currentTimeMillis(), 15000, pending);
AlarmReceiver:
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("MYTAG", "RECEIVED getMobileDataEnabled: " + getMobileDataEnabled(context));
if (!isOnline(context)) {
Log.d("MYTAG", "NO INET");
if (turnOnInet(context)) {
Log.d("MYTAG", "INET IS ON");
}
}
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://xxx.xxx.xxx.xxx/ping/pong/moto/");
try {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
nameValuePairs.add(new BasicNameValuePair("short_code", "ROFL"));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
httpclient.execute(httppost);
Log.d("MYTAG", "POST FINISHED");
}
catch (Exception e) {
Log.e("MYTAG", "MYTAG", e);
}
}
public boolean isOnline(Context context) {
ConnectivityManager cm = (ConnectivityManager)context.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if (netInfo != null){
Log.d("MYTAG", "isAvailable: "+netInfo.isAvailable());
}
if (netInfo != null && netInfo.isConnectedOrConnecting()) {
return true;
}
return false;
}
public boolean turnOnInet(Context context) {
ConnectivityManager mgr = (ConnectivityManager)context.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
if (mgr == null) {
Log.d("MYTAG", "ConnectivityManager == NULL");
return false;
}
try {
Method setMobileDataEnabledMethod = mgr.getClass().getDeclaredMethod("setMobileDataEnabled", boolean.class);
if (null == setMobileDataEnabledMethod) {
Log.d("MYTAG", "setMobileDataEnabledMethod == null");
return false;
}
setMobileDataEnabledMethod.invoke(mgr, true);
}
catch(Exception e) {
Log.e("MYTAG", "MYTAG", e);
return false;
}
return true;
}
private boolean getMobileDataEnabled(Context context) {
ConnectivityManager mgr = (ConnectivityManager)context.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
if (mgr == null) {
Log.d("MYTAG", "getMobileDataEnabled ConnectivityManager == null");
return false;
}
try {
Method method = mgr.getClass().getMethod("getMobileDataEnabled");
return (Boolean) method.invoke(mgr);
} catch (Exception e) {
Log.e("MYTAG", "MYTAG", e);
return false;
}
}
}
AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
First, you need to get that HttpPost code out of the BroadcastReceiver and into an IntentService. Never do network I/O on the main application thread, and onReceive() is called on the main application thread. For example, if you take too long, Android will terminate your code partway through your Internet operation.
Second, given the IntentService, you need to use a WakeLock. That may steer you to use my WakefulIntentService, which handles both problems. Or, use WakefulBroadcastReceiver, which has the same purpose.
Third, delete turnOnInet() and getMobileDataEnabled(). You do not need them, they are unreliable, and in particular turnOnInet() is user-hostile -- if the user wanted mobile data on, they would have turned it on.
Now, given all of that, in your onHandleIntent() of your IntentService() (or your doWakefulWork() of your WakefulIntentService), if you do not have an Internet connection right away, as a temporary workaround, SystemClock.sleep() for a second and try again, repeating a few times in a loop. If you find that you are getting Internet access after a bit, then you can consider getting more sophisticated (e.g., listening for connectivity change broadcasts rather than polling, though this would drive you away from WakefulIntentService and into a regular Service with your own background thread and a state machine for WakeLock management). Or, just stick with the sleep() -- it's unlikely to be the end of the world if you tie up this background thread for a few seconds. If you do not get connectivity after a modest amount of time, though, please do not keep trying indefinitely, as there are any number of reasons why you might not get a connection, including user-driven bandwidth management on Android 4.0+.
I'd suggest to change a bit that approach, which is not bad at all, it's even nice to make sure that you are always synced, with the only problem that you are not giving the user the chance to decide, since if I, as an user, decide to turn off my data I just don't want anybody to turn it on. There could be several reasons for that, and any of them should be enough, but say that you get out of the country and you have no international data plan and by accident or default you have Data roaming activated.
If I'd discover that some certain app turned my data on and spent a sensitive amount of money I'd be pretty pissed, and I'll be personal.
A more proper approach and straight solution as well would be to make a hard/full sync from time to time whenever the user opens your app or has access to some wifi connection (ConnectivityManager is your friend) based on some easy conditions (last time sync longer than a week, outdated saved data, inconsistencies, etc) and make a soft sync (update data in the background) in the rest of cases.
Moreover syncing periodically means wasting user data in case that user doesn't use the app.
Ultimately, this turns your app into perfect candidate to be shut down by the system every once in a while.
Hope it helps. Keep us updated with your progress.
Related read: Optimizing downloads for efficient network access
Not an exact answer - but this approach would absolutely ruin the battery life. The whole point of sleep is to save battery power and this app would do nothing more than be an annoyance for customers no matter how useful the features are.
What I would suggest is that if it is absolutely necessary to connect to the internet while the app is not in use - set a trigger for when the phone wakes up. If it is not completely necessary it probably would be best to simply reconnect to the internet every time the app is opened.

Categories

Resources