Android internet connection checking [duplicate] - android

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Android - detect whether there is an Internet connection available
this is the code to check the internet availability on android device:
public boolean isInternetAvailable() {
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
if (cm.getActiveNetworkInfo() != null)
return cm.getActiveNetworkInfo().isConnected();
else
return false;
}
So this code is working correctly if no wifi or network available.
But if device is connected to wifi network but internet is not available then what should i do to check the internet is there or not?
any suggestion will be appreciated.

I do it like this:
I try to reach google.com and watch for response:
public static void isGoogleAvailable(final Handler handler)
{
new Thread()
{
private boolean hasGoogleResponded = false;
#Override
public void run()
{
new Thread()
{
#Override
public void run()
{
HttpGet requestForTest = new HttpGet("https://www.google.com/");
try
{
new DefaultHttpClient().execute(requestForTest);
hasGoogleResponded = true;
}
catch (Exception e)
{}
}
}.start();
try
{
int waited = 0;
while(!hasGoogleResponded && (waited < 60000))
{
sleep(100);
if(!hasGoogleResponded )
{
waited += 100;
}
}
}
catch(InterruptedException e)
{}
finally
{
if (hasGoogleResponded)
{
handler.sendEmptyMessage(1);
}
else
{
handler.sendEmptyMessage(0);
}
}
}
}.start();
}
Then I retrive messages in my handler:
Handler internetHandler = new Handler()
{
#Override
public void handleMessage(Message msg)
{
if (msg.what == 1) //connected
{
}
else //not connected
{
}
}
};
I hope this helps.

You could try to ping a server like google (that should always exist)
see this topic

You can try
ConnectivityManager m;
m.getAllNetworkInfo();
First check internet connection,then others.
But sometimes its depends on app architecture.
If application needed wifi and you havent - you can not check internet because
it is not necessary

Related

Android Bluetooth LE Scan how to check if device is out of range?

I have faced with the issue using startScan method of BluetoothLeScanner a BLE device was found, but when I turned off BLE device my phone still shows this device as turned on !!
I have tried to use:
private ScanCallback mScanCallback = new ScanCallback() {
#Override
public void onScanResult(int callbackType, ScanResult result) {
Log.i("ScanCallback", String.format("onScanResult(int callbackType[%d], ScanResult result)", callbackType));
final BluetoothDevice btDevice = result.getDevice();
if (btDevice == null){
Log.e("ScanCallback", "Could not get bluetooth device");
return;
}
final String macAddress = btDevice.getAddress();
if (callbackType == ScanSettings.CALLBACK_TYPE_MATCH_LOST) {
// NOTE: I've never got here
final BluetoothDevice outOfRangeDevice = mBtDevices.get(macAddress);
...
} else {
...
}
}
...
};
Guy, I have not found solution how to detect that BLE device is lost in other resources like (Android SDK reference, forums, stackoverflow and etc) (:
Any help will be appreciated !!
During googling and exploring the Android Documentations I have figured out how to detect if device is out of range. I would like to share my solution how I did it:
...
public void scanBLEDevices(final boolean enable) {
if(mLeScanner == null) {
Log.d(TAG, "Could not get LEScanner object");
throw new InternalError("Could not get LEScanner object");
}
if (enable) {
startLeScan();
} else {
stopLeScan(false);
}
}
private void startLeScan() {
Log.i(TAG, "startLeScan(BluetoothLeScanner mLeScanner)");
mScanning = true;
mInRangeBtDevices.clear();
if (mStartScanCallback != null) {
mHandler.removeCallbacks(mStartScanCallback);
}
if (Build.VERSION.SDK_INT < 21) {
mBluetoothAdapter.startLeScan(mLeScanCallback);
} else {
mLeScanner.startScan(mScanFilters, mScanSettings, mScanCallback);
}
mStopScanCallback = new Runnable() {
#Override
public void run() {
stopLeScan(true);
}
};
mHandler.postDelayed(mStopScanCallback, SCAN_PERIOD);
}
private void stopLeScan(final boolean isContinueAfterPause) {
Log.i(TAG, "stopLeScan(BluetoothLeScanner mLeScanner)");
mScanning = false;
if (mStopScanCallback != null) {
mHandler.removeCallbacks(mStopScanCallback);
}
removeOutOfRangeDevices();
if (Build.VERSION.SDK_INT < 21) {
mBluetoothAdapter.stopLeScan(mLeScanCallback);
} else {
mLeScanner.stopScan(mScanCallback);
}
if (isContinueAfterPause) {
mStartScanCallback = new Runnable() {
#Override
public void run() {
startLeScan();
}
};
mHandler.postDelayed(mStartScanCallback, SCAN_PAUSE);
}
}
private void removeOutOfRangeDevices() {
final Set<String> outOfRangeDevices = new HashSet<>();
for (String btAddress : mBtDevices.keySet()) {
if (!mInRangeBtDevices.contains(btAddress)) {
outOfRangeDevices.add(btAddress);
}
}
for (String btAddress : outOfRangeDevices) {
final BluetoothDevice outOfRangeDevice = mBtDevices.get(btAddress);
mBtDevicesRSSI.remove(btAddress);
mBtDevices.remove(btAddress);
}
}
...
Explanation:
As you can see I have added on each scanning period mInRangeBtDevices collection that will keep all devices found during the current scanning.
When I stop scanning, I am also removing out of range device from previous lists that is not available anymore using one additional helper collection outOfRangeDevices
I think this example would be usefull and you will be able to integrate it in your own code
This one is looking good (JAVA):
As I understood, you need to implement startLeScan().
Find BLE devices
To find BLE devices, you use the startLeScan() method. This method takes a BluetoothAdapter.LeScanCallback as a parameter. You must implement this callback, because that is how scan results are returned. Because scanning is battery-intensive, you should observe the following guidelines:
As soon as you find the desired device, stop scanning.
Never scan on a loop, and set a time limit on your scan. A device that was previously available may have moved out of range, and continuing to scan drains the battery.
The following snippet shows how to start and stop a scan:
public class DeviceScanActivity extends ListActivity {
private BluetoothAdapter mBluetoothAdapter;
private boolean mScanning;
private Handler mHandler;
// Stops scanning after 10 seconds.
private static final long SCAN_PERIOD = 10000;
...
private void scanLeDevice(final boolean enable) {
if (enable) {
// Stops scanning after a pre-defined scan period.
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
}, SCAN_PERIOD);
mScanning = true;
mBluetoothAdapter.startLeScan(mLeScanCallback);
} else {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
...
}
...}
Consider checking this tutorial as well.
Also this one.

Android sockets reconnect to server

I'm building a android app that using connection with Java server (on computer).
I have a problem- when I find that there is no connection with the server, I'm trying to reconnect to the server but it doesn't work.
Here is the Client class code:
public class Client extends AsyncTask {
private final int port = 1978;
private final String ip = "192.168.14.22";
private Socket socket;
private DataOutputStream output;
private DataInputStream input;
public Client() {
}
#Override
protected Object doInBackground(Object[] objects) {
try {
socket = new Socket(ip, port);
output = new DataOutputStream(socket.getOutputStream());
input = new DataInputStream(socket.getInputStream());
Log.d("Network c1", "Connected");
} catch (IOException e) {
socket = null;
Log.d("Network c1", "Not connected");
}
return null;
}
public boolean checkConnection() {
if (output == null)
return false;
try {
output.writeUTF("abc");
return true;
} catch (IOException e) {
return false;
}
}
#Override
protected void onProgressUpdate(Object[] values) {
}
}
And the Activity code:
public class LogInActivity extends AppCompatActivity {
Client client;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_log_in);
client = new Client();
client.execute();
//I used timer because it didn't work without it- That saied always 'not connected' message/Toast
new CountDownTimer(5, 0) {
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
check();
}
}.start();
}
private void check() {
boolean isProcess;
isProcess = !checkConnection();
if (isProcess) {
AlertDialog.Builder builder = new AlertDialog.Builder(this, R.style.Theme_AppCompat_Dialog_Alert);
builder.setTitle(getResources().getString(R.string.app_name));
builder.setMessage("Unable connect to the library");
builder.setPositiveButton("Try Again", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
//See note 1.
check();
}
});
builder.setCancelable(false);
builder.show();
}
}
public boolean checkConnection() {
if (client.checkConnection()) {
Toast.makeText(getApplicationContext(), "Connected to the library", Toast.LENGTH_SHORT).show();
return true;
} else {
Toast.makeText(this, "Unable connect to the library", Toast.LENGTH_SHORT).show();
return false;
}
}
}
Note 1:
The problem is here.
This Dialog need to be shown until the server/Library connected.
If the server is on before the app turned on, the check() method works well and says 'Connected successful' and the Dialog doesn't show.
But if when the app started, the server was unreachable, and turned on later (And became reachable)- the check() method don't work and always shows the Dialog.
What is the problem?
By the way, I tried to restart the client AsyncTask Class, but i didn't succeed.
(I tried to do close(true) to it, and after do excute() to it again, but the cancel() method didn't worked, and was a error that said that after a AsyncTask Class excuted, it can't excute again)
Thanks.
You should not check for connectivity periodically (every couple of seconds like you do in this code).
Instead you should let the OS do this for you, it will be more reliable and more efficient in terms of battery and CPU.
Take a look at this answer

Handling offline events

I am doing offline caching.I want to allow user to make events even when he/she is offline.For that I am using a handler that checks every second whether net connection is there or not and whenever net connection is there it executes the task associated with the event.For example if user want to post comment when he/she is offline then when he click on post button a handler will run which will post the comment whenever internet connection is there on user's device.But using a handler or thread may not be the best choice as they will keep running until net connection is there and also checking condition repeatedly.Is there any other better way to allow user to schedule events when he/she is offline and execute them whenever netconnection is there?
mPostCommentImageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(isNetworkAvailable())
{
postComment(mCommentEditText.getText().toString());
hideKeypad();
mCommentEditText.setText("");
}
else
{
Toast.makeText(getActivity(),"You comment will be posted once net connection is there",Toast.LENGTH_LONG).show();
comment= new Handler();
hideKeypad();
final String commenttext=mCommentEditText.getText().toString();
comment.postDelayed(runnable = new Runnable()
{
public void run() {
addComment(videoid,commenttext,comment,runnable);
comment.postDelayed(runnable, 2000);
}
},2000);
refreshCommentList();
}
}
});
public void addComment(String videoid,String commenttext, final Handler comment,final Runnable runnable) {
if (isNetworkAvailable()) {
CommentAPI.addComments(getApplicationContext(), videoid, commenttext, new APIResponseListener() {
#Override
public void onResponse(Object response)
{
comment.removeCallbacks(runnable);
}
#Override
public void onError(VolleyError error)
{
}
});
}
}
private boolean isNetworkAvailable()
{
ConnectivityManager connectivityManager= (ConnectivityManager)getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
You can use the ConnectivityManager BroadcastReceiver for this. More information on this is available at Determining and Monitoring the Connectivity Status.

Is this a bad hack? Is there a better way to do this?

I have some code that works, but just feels like a bad idea. I'm wondering if there's a better way to do this.
The Problem (You could honestly probably skip this and go to the code)
I have a bluetooth LE app that occasionally needs to write characteristics as fast as possible to multiple BLE devices (The app is a controller for a smart lamp). My current set up for BLE communication is to use a BluetoothContorller custom singleton which handles all communication, and Lamp objects which ask the controller to write to the lamps and hand off their BluetoothGatt and BluetoothGattCharacteristic to the controller.
The Solution
handler.post(new Runnable() {
#Override
public void run() {
if (control != null) {
synchronized (BluetoothController.this) {
Logger.d("BluetoothController", "Waiting......");
for(int i = 0; i < 100; i++){
if(isWaiting)
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
else
break;
}
isWaiting = true;
Logger.d("BluetoothController", "Done waiting.");
}
control.setValue(message);
mBluetoothGatt.writeCharacteristic(control);
}
}
});
And inside my gatt callback:
#Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
super.onCharacteristicChanged(gatt, characteristic);
if(isWaiting){
isWaiting = false;
}
}
Now, this code works but all my experience as a programmer tells me that this code will cause me a lot of pain and surely there is a better.
EDIT: New Code using Handler.Callback and Messages
I've changed my code to do the waiting in the handle message callback, using Thread.wait() and notify(), but It seems like the messages are getting backed up in the queue, and the last one to execute still seems kind of random.
#Override
public void run() {
Looper.prepare();
handler = new Handler(new Handler.Callback() {
#Override
public boolean handleMessage(Message msg) {
synchronized (BluetoothController.this) {
if (shouldWait) {
isWaiting = true;
try {
BluetoothController.this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
isWaiting = false;
}
shouldWait = true;
}
return true;
}
});
Looper.loop();
}

Show Toast on SplashScreen Android

I am stuck with following problem.I want my application to exit if it detects no network connection.My application starts with splash screen.Is it possible to show splash screen followed by toast if no network connection is on device.and then terminate the application
I have something like this in my splash screen code :
Inside onCreate()
ConnectivityManager connectivitymanager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkinfo = connectivitymanager.getActiveNetworkInfo();
connected = networkinfo != null && networkinfo.isAvailable()
&& networkinfo.isConnected();
Log.v("Network state : ", connected + "");
Thread splashThread = new Thread() {
#Override
public void run() {
try {
int waited = 0;
while (waited < 5000) {
sleep(100);
waited += 100;
}
} catch (InterruptedException e) {
// do nothing
} finally {
Looper.prepare();
if (connected == false) {
Toast.makeText(
splashscreenActivity.this,
"No Network Connection is available on device.",
Toast.LENGTH_LONG).show();
finish();
System.exit(0);
} else {
finish();
startActivity(new Intent(splashscreenActivity.this,
mainActivity.class));
}
Looper.loop();
}
}
};
splashThread.start();
1.Please see my code and guide me how can i show up that toast.
2.Or suggest me some other better way to do this
Thanks
EDIT :
Thank you everybody for replying :
I opted Dharmendra's way of showing toast via splashscreen activity :
The code that worked for is :
if (connected == false) {
splashscreenActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(splashscreenActivity.this,
"No Internet Connection.", 3000).show();
}
});
finish();
} else {
//migrate to main activity from splashscreen
}
You can do it like this, use Handler .Put the following code in the else condition
Handler mHandler = new Handler(Looper.getMainLooper());
mHandler.post(new Runnable() {
public void run() {
Toast.makeText(Splash.this, "Network error", Toast.LENGTH_LONG).show();
finish();
}
});
Or ,I am doing this in my application :
if(status.equals("CONNECTED"))
{
startActivity(new Intent(Splash.this,Activity.class));
finish();
}else
{
startActivity(new Intent(Splash.this,NetworkError.class));
finish();
}
where NetworkError class shows another layout with the image like "No Network,,,,"(or whatever you want to show instead of splash...)
You are creating and showing Toast from Thread so it may be not called
You have to write this code
splashscreenActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(c, "Internet connection not currently available.", 3000).show();
}
});
Just add a if else block.(using ur connection network info)
if(connected){
//put the splash thread here
}else{
finish();
}
A finally block is used if you do not wish to catch any exceptions. In your code, place all your code in a else loop, If time of 5000 lapses then, go to else statement and execute it. If you are adding catch you can remove finally.

Categories

Resources