This question already has answers here:
Android check internet connection [duplicate]
(20 answers)
Closed 7 years ago.
This is not a duplicated question, I now how to check if there is internet connection, what I don't know is how to pop dialog in while loop and try again until internet connection is back
I am trying to pop Alert dialog if there is no internet connection,
and then wait for the user to hit "Try Again"
when he hit the button, check the internet connection and pop again this Alert Dialog if there is no internet connection.
When I am doing this with if statement it works good - pop the dialog when there is no internet and check for connection when hit "Try Again"
But, when I try to put this in a while loop the loop doesn't wait/show the dialog to the user.
What is the right way to do this? and why it is not working now?
while (netInfo == null || !netInfo.isConnected()) {
new AlertDialog.Builder(this)
.setTitle("title")
.setMessage("message")
.setPositiveButton("Try Again", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
netInfo = cm.getActiveNetworkInfo();
System.out.println("cm: "+cm+ " netinfo: "+ netInfo);
}
})
.show();
}
try this code call getDATA() method while onCreate() in actvity , it may help
private void getDATA() {
boolean isProcess;
try {
isProcess = Utils.isNetworkConnected(class.this) || Utils.hasActiveInternetConnection(); //method to check internet connection
} catch (Exception e) {
isProcess = false;
e.printStackTrace();
}
if (isProcess) {
try {
AlertDialog.Builder builder =
new AlertDialog.Builder(class.this, R.style.AppCompatAlertDialogStyle);
builder.setTitle(getResources().getString(R.string.app_name));
builder.setMessage("Internet not available?");
builder.setPositiveButton("Try Again", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
getDATA();
}
});
builder.setCancelable(false);
builder.show();
} catch (Exception e) {
e.printStackTrace();
}
} else {
Crouton.makeText(class.this, MessageConstant.MsgWiFi, Style.ALERT).show();
}
}
Related
I have connected my Android device to the wifi shared by my laptop. After I input the IP address and click "OK" in the Android app, I can not find any packets to/from the address in Wireshark (packet sniffer)
I have added this to the manifest of the Android Project:
<uses-permission android:name="android.permission.INTERNET"/>
Android Code:
private boolean attemptOpenDoor(){
// Store values at the time of the login attempt.
String studentId = mStudentIdView.getText().toString();
String password = mPasswordView.getText().toString();
final EditText et = new EditText(this);
new AlertDialog.Builder(this).setTitle("please input IP address")
.setIcon(android.R.drawable.ic_dialog_info).setView(et)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface arg0, int arg1) {
IPAddr = et.getText().toString();
}
}).setNegativeButton("cancel", null).show();
try {
Socket socket = new Socket();
socket.connect(new InetSocketAddress(IPAddr, 8866), 5000);
OutputStream ou = socket.getOutputStream();
ou.write((studentId+password).getBytes("UTF-8"));
ou.close();
socket.close();
}catch (SocketTimeoutException aa) {
//连接超时 在UI界面显示消息
AlertDialog alertDialog = new AlertDialog.Builder(LoginActivity.this).create();
alertDialog.setMessage("服务器连接失败!请检查网络是否打开");
alertDialog.setButton(DialogInterface.BUTTON_POSITIVE, "确定", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
}
});
alertDialog.show();
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
The program doesn't work because at the time that you're trying to open the socket using:
socket.connect(new InetSocketAddress(IPAddr, 8866), 5000);
the dialog is still up and value of IPAddr has not yet been set. Make sure that you only start connecting once the user has entered a valid input in the field.
Also, beware that the method above will block whichever thread it's running on until a connection is established or 5 seconds go by, meaning that it'd be unwise to call it directly inside of the OnClickListener. You should probably use an AsyncTask or similar to avoid blocking the UI thread while the connection is taking place.
You should move your connect codes after "onClick".
new AlertDialog.Builder(this).setTitle("please input IP address")
.setIcon(android.R.drawable.ic_dialog_info).setView(et)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface arg0, int arg1) {
IPAddr = et.getText().toString();
try {
Socket socket = new Socket();
socket.connect(new InetSocketAddress(IPAddr, 8866), 5000);
OutputStream ou = socket.getOutputStream();
ou.write((studentId+password).getBytes("UTF-8"));
ou.close();
socket.close();
}catch (SocketTimeoutException aa) {
//连接超时 在UI界面显示消息
AlertDialog alertDialog = new AlertDialog.Builder(LoginActivity.this).create();
alertDialog.setMessage("服务器连接失败!请检查网络是否打开");
alertDialog.setButton(DialogInterface.BUTTON_POSITIVE, "确定", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
}
});
alertDialog.show();
} catch (Exception e) {
e.printStackTrace();
}
}
}).setNegativeButton("cancel", null).show();
I am trying to open location settings in android using WebIntent plugin for phonegap. I use GPSDetector plugin for phonegap to detect if location is active and if it is not active i want to open Location Settings. After activate the location press Back button and go to index.html.
window.plugins.webintent.startActivity({
action: 'android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS'},
function() {},
function() {alert('Failed to open URL via Android Intent')}
);
In this case I don`t know which is the action, I have tried like this but did not work.
I have made an activity and there i added in onCreate method :
startActivityForResult(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS), 0);
But in this way i don`t know how to send the user back to index.html after he turns on the Location(Gps).
Please help and Thanks a lot
I didn't use any available plugins. I wrote my own plugin and this is the java code of that plugin. Check if this is helpful. It works as your requirement for me.
if (CHECK_LOCATION_SERVICES_ENABLED.equals(action))
{
try
{ boolean locationServicesEnabled=false;
if(this.ctx.getContext()!=null)
{
//Location services not enabled
final Context context = this.ctx.getContext();
(new Thread(new Runnable() {
#Override
public void run() {
Looper.prepare();
final Handler innerHandler = new Handler() {
#Override
public void handleMessage(Message message) {
/*Toast.makeText(myContext,android.os.Build.VERSION.RELEASE,
Toast.LENGTH_LONG).show();*/
LocationManager lm = null;
boolean gps_enabled=false,network_enabled=false;
if(lm==null)
lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
try{
gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
}catch(Exception ex){}
try{
network_enabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
}catch(Exception ex){}
if(!gps_enabled && !network_enabled){
AlertDialog.Builder alertDialog = new AlertDialog.Builder(
context);
alertDialog.setTitle("FindMe");
alertDialog
.setMessage("You must enable Location Services for using FindMe.\nDo you want to go to Location Sources Settings?");
alertDialog.setPositiveButton("Settings",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(
Settings.ACTION_LOCATION_SOURCE_SETTINGS);
context.startActivity(intent);
}
});
alertDialog.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
alertDialog.show();
}
}
#Override
public void dispatchMessage(Message message) {
handleMessage(message);
}
};
Message message = innerHandler.obtainMessage();
innerHandler.dispatchMessage(message);
Looper.loop();
}
})).start();
}
return new PluginResult(PluginResult.Status.OK,"success ");
}
catch (Exception ex)
{
Log.d("FindMePlugin", ex.toString());
return new PluginResult(PluginResult.Status.ERROR, "error"+ex.toString());
}
}
I created this method to handle 2 different way of creating alert dialog, depending on internet status. Do you know a better way to get the same result? Using .equals() on strings in if-else block do not seem a best-practices way... Am i right?
public void noInternetAlertDialog(String errorMsg) {
String title = null;
String msg = null;
if (errorMsg.equals("none")) {
title = "Connection failded";
msg = "Please check internet connection";
} else if (errorMsg.equals("slow")) {
title = "Connection timeout";
msg = "Connection is slow";
}
AlertDialog.Builder builder;
builder = new AlertDialog.Builder(Main.this);
builder.setCancelable(false);
builder.setTitle(title);
builder.setMessage(msg);
builder.setPositiveButton("Retry", new DialogInterface.OnClickListener(){
#Override
public void onClick(DialogInterface dialog, int which)
{
dialog.dismiss();
downloadDialog();
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
finish();
}
});
AlertDialog dialog = builder.create();
dialog.show();
}
Use strings.xml for your strings to allow localization (Retry, Cancel, "Connection failded", "Please check internet connection", "Connection timeout", "Connection is slow")
If your values represent something create a data type for them. I mean: if your string will report if internet is available or slow, why keep it as String? A String can be everything and convert to something which says directly what values it can assume will improve your code a lot.
public enum InternetStatus {
Offline,
Slow
}
And a == will be faster than a equals call.
If you don't want to use the enum, consider using "none".equals(errorMessage)
String title = "Connection failded";
String msg = "Please check internet connection";
if ("slow".equals(errorMsg)) {
title = "Connection timeout";
msg = "Connection is slow";
}
You can chain calls to the builder and remove the variable dialog because you can call show() directly (If you still need the reference to the AlertDialog, show() still returns it).
You can go with your fantasy and do something like this
.setTitle(errorMsg == InternetStatus.Slow ? "Connection timeout" : "Please check internet connection")
.setMessage(errorMsg == InternetStatus.Slow ? "Connection failded" : "Connection is slow")
but it will make your code a mess if you want to add more InternetStatus.
You could create a method inside InternetStatus which returns the message (if it will be needed in other places too). But it highly depends on the project you are working with. You could an "extension" method which does it for you just where you need it without put it in the enum code (enums can have methods). You should consider every opportunity.
Maybe?
public enum InternetStatus {
Offline,
Slow
}
public void noInternetAlertDialog(InternetStatus errorMsg) {
String title = getString(R.string.internetfailed);
String msg = getString(R.string.checkyourinternet);
if (errorMsg == InternetStatus.Slow) {
title = getString(R.string.connectiontimeout);
msg = getString(R.string.slowinternet);
}
new AlertDialog.Builder(Main.this)
.setCancelable(false)
.setTitle(title)
.setMessage(msg)
.setPositiveButton(R.string.retry, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
downloadDialog();
}
})
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
finish();
}
})
.show();
}
It really is not a good idea to identify a state/result with a string! you should use an enum instead.
enum NoInternetResult {
slow, none
}
and then:
public void noInternetAlertDialog(NoInternetResult result) {
String title = "Connection failded";
String msg = "Please check internet connection";
if (result==NoInternetResult.slow) {
title = "Connection timeout";
msg = "Connection is slow";
}
btw. use strings.xml for you strings like "retry" and "Cancel" (http://developer.android.com/guide/topics/resources/string-resource.html)
This app searches for places of interest around you when you click a button. The flow is like this:
you click on the button Search
it checks for internet connection, if not, you get a dialog asking
you to enable internet
you click on the button Search
it checks for location services, if not, you get a dialog asking you
to enable location tracking and takes you to the Gps settings screen
then you go back, click on the button Search and an asynctask starts
doing the job (searching and displaying)
What I need to do is eliminate the button Search, so it does everything automatically step by step. So it would be like:
start the app
it checks for internet connection, if not, you get a dialog asking
you to enable internet
when internet enabled, it checks for location services, if not, you get a dialog asking you to enable location tracking and takes you to the Gps settings screen
then it starts the asynctask
I though that an alert dialog would make the activity paused and I could check all the conditions, but it looks like it doesn't. How should I solve this? Feel free to ask for any more details.
Forgot to mention that I only want this done once, the first time the app is started.
Here's my code:
public class MainActivity extends Activity {
//variables
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv = (ListView) findViewById(R.id.list);
button = (Button) findViewById(R.id.btn_show_map);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
cd = new ConnectionDetector(MainActivity.this);
// Check if Internet present
isInternetPresent = cd.isConnectingToInternet();
if (!isInternetPresent) {
// Internet Connection is not present
alert.showAlertDialog(MainActivity.this, "Internet Connection Error", "Please connect to a working Internet connection", false);
return;
}
// creating GPS Class object
gps = new GPSTracker(MainActivity.this);
// check if GPS location can get
if (gps.canGetLocation()) {
Log.d("Your Location", "latitude:" + gps.getLatitude() + ", longitude: " + gps.getLongitude());
} else {
// Can't get user's current location
gps.showSettingsAlert();
return;
}
new LoadPlaces().execute();
}
});
}
class LoadPlaces extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Dialog
* */
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(MainActivity.this);
pDialog.setMessage(Html.fromHtml("<b>Search</b><br/>Loading Places..."));
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
protected String doInBackground(String... args) {
Long t = Calendar.getInstance().getTimeInMillis();
while (!gps.hasLocation && Calendar.getInstance().getTimeInMillis() - t < 60000) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// get the places
return null;
}
protected void onPostExecute(String file_url) {
// dismiss the dialog after getting all products
pDialog.dismiss();
gps.stopUsingGPS();
// display the results
}
}
}
update: I was thinking there might be a better option with a different thread, along the lines of what i wrote below. Or maybe with a service or a receiver.. Any ideas?
Thread th = new Thread() {
boolean allEnabled = false;
#Override
public void run() {
Long t = Calendar.getInstance().getTimeInMillis();
while (!allEnabled && Calendar.getInstance().getTimeInMillis() - t < 120000) {
try {
isInternetPresent = cd.isConnectingToInternet();
if (!isInternetPresent) {
runOnUiThread(new Runnable() {
#Override
public void run() {
alert.showAlertDialog(MainActivity.this, "Internet Connection Error", "Please connect to a working Internet connection", false);
}
});
} else if (!gps.canGetLocation()) {
runOnUiThread(new Runnable() {
#Override
public void run() {
gps.showSettingsAlert();
}
});
} else {
allEnabled = true;
runOnUiThread(new Runnable() {
#Override
public void run() {
new LoadPlaces().execute();
}
});
}
Thread.sleep(20000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
th.start();
This version is of course not ok, since it spams one dialog after another.
Usually something like this is solved through several callbacks/entrypoints in your activity. In order to do this you need to build your own AltertDialogs - one to prompt the user to enable internet and one to prompt the user to enable GPS. For the dialogs you will have to set the actions for the NegativeButton and the PositiveButton.
The logic would look something like this:
NegativeButton -> Exit App
Disabled -> Prompt user to enable {
OnCreate -> Check internet { PositiveButton -> Go to Check GPS
|
| NegativeButton -> Exit App
| Disabled -> Prompt user to enable {
*-Enabled -> Check GPS { PositiveButton -> Start AsyncTask
Enabled -> Start AsyncTask
You can implement the "Go to"'s as functions that are called in the OnClickListener of the PositiveButtons.
This is what makes Android a Callback-hell, but I have yet to find a better solution for stuff like this. I hope you can wrap your head around the concept!
One way to do it, is to set the positive button of the alert dialog.
Put each into the positive button click of the alert dialog, such as follows:
new AlertDialog.Builder(this)
.setTitle("Problem")
.setMessage(
"Please Check your *whatever is wrong* ")
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
//Do the next activity
dialog.dismiss();
}
}).show();
If you want detailed code, then I will. Cheers!
My dialog gets open and ask for code but when user switches to message box of mobile phone to see the code by minimizing the app.Then after resumes the app the dialog box disappears.
My app is unable to restore last UI State.
AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.setTitle("Enter Your Registeration Code");
alert.setMessage("Registeration code has been delivered on your registered number via sms");
// Set an EditText view to get user input
final EditText input = new EditText(this);
alert.setView(input);
alert.setCancelable(false);
alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int whichButton) {
String value = input.getText().toString().trim();
String regsCode2 = etFake.getText().toString().trim();
if (value.compareToIgnoreCase(regsCode2) == 0) {
validCodeMatch = objCommonServices.sendEvalidCode(String.valueOf(mobileNo), password, "OK", regsCode2);
if (validCodeMatch.contains("Code Match")) {
showDialog(2);
}
} else {
try {
removeDialog(3);
showDialog(3);
} catch (Exception e) {
}
}
}
});