Im having a pretty simple requirement.I have a Login activity. Once user enters login details and clicks on submit button, the application should perform a internet access check. If device is not connected to internet then it should display a toast saying "No internet access". If internet is accessible then the application will perform authentication and navigate to Home page.
I have written the code snippet to perform internet check in a separate class for re usability. The code snippet is as below:
package com.example.rinventory.Common;
import android.content.Context;
import android.net.NetworkInfo;
import android.net.ConnectivityManager;
public class ConnectionDetector
{
private Context _context;
public ConnectionDetector(Context context)
{
this._context = context;
}
public boolean isConnectingToInternet()
{
ConnectivityManager connectivity = (ConnectivityManager) _context.getSystemService(Context.CONNECTIVITY_SERVICE);
//Get all the active networks available.
NetworkInfo info = connectivity.getActiveNetworkInfo();
//If it is connected to available networks return true else false.
if(info != null && info.isConnected())
return true;
else
return false;
}
}
And my Login activity's submit button functionality is as below:
public class RInventoryLogin extends ActionBarActivity
{
boolean isInternetPresent = false;
ConnectionDetector detect;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_rinventory_login);
Button btnLogin = (Button) findViewById(R.id.btnSubmit);
btnLogin.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
//Throws error at this particular line
isInternetPresent = detect.isConnectingToInternet();
if(isInternetPresent)
{
EditText editEmail = (EditText)findViewById(R.id.editEmail);
EditText editPassword = (EditText)findViewById(R.id.editPassword);
LoginData data = new LoginData();
data.setEmail(editEmail.getText().toString());
data.setPassword(editPassword.getText().toString());
new CallJsonParserLogin().execute(data);
}
else
{
Toast.makeText(RInventoryLogin.this, "No Internet Access", Toast.LENGTH_SHORT).show();
}
}
});
}
}
When I try to execute, it loads the activity. However once I enter login details and click on submit the application shuts down with "unexpectedly your application has stopped working"
I have included Internet, Network state parameters in Manifest file.
When I comment the line
isInternetPresent = detect.isConnectingToInternet();
and subsequent if else blocks it just works fine. What might be the issue I'm missing here?
I have tried the same creating a demo application and that works fine.
Please help
you are not initializing detect object.
add this line before setting click listener to your button :
detect = new ConnectionDetector(this);
Related
I have this code for a webview so that it shows when there's no connection in Android Studio it shows a message where there's no connection, then the user press a button to see if there's connection again, and it does it well but just the first time it opens. After the page loads with internet and you are navigating on if you deactivate the internet and enter any url it shows the 404 error again instead of showing the layout and the button to retry to connect to the internet.
Here is the code inside another fail created called NoConnection.java to have more order in the coding. It will be great if you tell me exactly what to put and where in the code because I'm kind of a newbie in Android Studio.
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
public class NoConnection extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_no_connection);
}
public void retry(View view){
if(isNetworkAvailable() == true){
Intent Intent = new Intent(NoConnection.this, SplaceScreen.class);
startActivity(Intent);
}else{
Toast.makeText(this, "No internet connection.", Toast.LENGTH_LONG).show();
}
}
public boolean isNetworkAvailable() {
// Get Connectivity Manager class object from Systems Service
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
// Get Network Info from connectivity Manager
NetworkInfo networkInfo = cm.getActiveNetworkInfo();
// if no network is available networkInfo will be null
// otherwise check if we are connected
if (networkInfo != null && networkInfo.isConnected()) {
return true;
}
return false;
}
}
Now, how can I modify it so that it works after the website loaded and you are navigating on it it shows the message?
Thanks in advance,
The solution here is to check for isNetworkAvailable() every time you tap on a link (i.e, load a webpage). What you need to do is, listen to the urlLoad event in the WebView and before the load, call isNetworkAvailable().
You can do this by doing the following:
Set a WebViewClient to the WebView.
In your WebViewClient, override the shouldOverrideUrlLoading() method. This method will get called every time a url is loaded in the WebView. Call the isNetworkAvailable() inside this callback method. There is another callback method onPageStarted() that's invoked just before the page is loaded. You can try this method as well.
or
You can try overriding the onReceivedError() method. This method will be called, when the url failed to load.
There are many ways to get this done, so see what fits you and go with that.
I am working on a wifi data usage research and want to develop a program like,When user click on a button the device is already connected to wifi will start computing data usage and on same button click it will stop computing data usage and give me total data usage between start and stop event.I have searched many threads related to this but didnt find what i am looking for,Can any one help me for the same,THis is what i have tried a little.
code
public class MainActivity extends AppCompatActivity {
NetworkInfo wifiCheck;
Button btn1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn1 = (Button)findViewById(R.id.btn1);
btn1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
}
});
getDataWifiDataUsageInfo();
ConnectivityManager connectionManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
wifiCheck = connectionManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
if (wifiCheck.isConnected()) {
// Do whatever here
Toast.makeText(MainActivity.this,"WiFi is Connected",Toast.LENGTH_LONG);
} else {
Toast.makeText(MainActivity.this,"WiFi is not Connected",Toast.LENGTH_LONG);
}
}
public void checkWiFi(View view) {
Intent intent = getIntent();
finish();
startActivity(intent);
}
//get data usage info
void getDataWifiDataUsageInfo(){
Log.e("bytes recvd", "" + android.net.TrafficStats.getMobileRxBytes());
Log.e("Total", "Bytes received" + android.net.TrafficStats.getTotalRxBytes());
}
}
I hope someone will definitely help me.Looking for a help.
If you already know that the user is connected to WiFi (as you stated) when clicking the button, all networking (sending and receiving of data) will go through the WiFi connection. Thus, when the user clicks on the button to start:
long startBytes = TrafficStats.getTotalRxBytes() + TrafficStats.getTotalTxBytes();
and when the stop button is clicked:
long stopBytes = TrafficStats.getTotalRxBytes() + TrafficStats.getTotalTxBytes();
Finally, to work out the bytes transferred between start and stop:
long bytesTransferred = stopBytes - startBytes;
For more information check out the TrafficStats methods used here and here.
I am trying to disable a button while a download task is being executed. I have tried using setEnabled, setVisibility and setClickable. I think I tried all combinations of these options. All of them disable the button click events while the task is performing, but the events are still being registered somehow, and when I reactive the button, the handler is called if I clicked the button while it was disabled... even if it was invisible or "gone"! (not sure if it is called a handler, I want to refer to the onClick method).
I have also inserted a counter and a Log to verify what I've stated above. The code is shown below. This piece of code if(counter>1) return; is meant to stop the crash, but I would like to remove it, since I want to re-enable the button, and not disable it forever.
onClick:
public void downloadOnClick(View v) {
counter++;
Log.d(this.getLocalClassName(), "Button was clicked " + counter + " times.");
if(counter>1) return;
ConnectivityManager connMgr = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
//mButton.setVisibility(View.GONE);
mButton.setEnabled(false);
//mButton.setClickable(false);
mTextView.setText("Getting html file...");
// if we use simple http, we will need to handle redirect status code
new DownloadWebpageTask().execute("https://www.google.com/");
} else {
mTextView.setText("No network connection available.");
}
}
AsyncTask:
private class DownloadWebpageTask extends AsyncTask<String, Void, String> {
private HttpURLConnection mConnection;
#Override
protected String doInBackground(String... urls) {
try {
URL url = new URL(urls[0]);
mConnection = (HttpURLConnection) url.openConnection();
mConnection.setReadTimeout(10000 /* milliseconds */);
mConnection.setConnectTimeout(15000 /* milliseconds */);
mConnection.setRequestMethod("GET");
mConnection.setDoInput(true);
mConnection.connect();
int statusCode = mConnection.getResponseCode();
if (statusCode != HttpURLConnection.HTTP_OK) {
return "Error: Failed getting update notes";
}
return readTextFromServer(mConnection);
} catch (IOException e) {
return "Error: " + e.getMessage();
}
}
private String readTextFromServer(HttpURLConnection connection) throws IOException {
InputStreamReader stream = null;
try {
stream = new InputStreamReader(connection.getInputStream());
BufferedReader br = new BufferedReader(stream);
StringBuilder sb = new StringBuilder();
String line = br.readLine();
while (line != null) {
sb.append(line + "\n");
line = br.readLine();
}
return sb.toString();
} finally {
if (stream != null) {
stream.close();
}
}
}
#Override
protected void onPostExecute(String result) {
mTextView.setText(result);
// Can not reactivate button / cancel (pending?) events....
//mButton.setVisibility(View.VISIBLE);
mButton.setEnabled(true);
//mButton.setClickable(true);
}
}
The full project (it is very simple, just a training example) is available to test in this repository that I have just created.
To conclude, from what I have read, there is in fact a problem regarding button disabling. Mostly this is resolved through the use of a flag to call the onClick method only when the flag is true. Although, this does not solve the problem of re-enabling the button. I have also tried mButton.cancelPendingInputEvents(); but it does not work (and I do not know why. Click events are not yet registered? Or they are not pending?
Is there a simple solution to this problem? Any ideas? Am I missing some basic detail? If not, I am considering trying to create a new button programatically to contour the problem. If I do not keep references to old buttons, are they deleted through garbage collection?
Thanks in advance!
[Edit] Clarification:
Since the title could be misleading in this point, I want to clarify that I am able to disable and re-enable the button and all the functionality is ok except when the buttion is disabled. And note that I have added the line if(counter>1) return; just to test but it stops the button from working the way I wanted (that's why I am not using a flag. I don't want this line to be there when I solve the problem!). The log is enough to inform me that the method is being called when the button is re-enabled, because I clicked it when it was disabled!
I found that with your example, the AsyncTask was completing so fast that there was a very short amount of time that the Button was not clickable due to being disabled. So, it's basically a timing issue.
I found that by delaying the re-enabling of the Button by 4 seconds, it works as expected.
Note with this change that visually, the Button is re-enabled a split second after the TextView is populated.
Here is the code change in onPostExecute():
#Override
protected void onPostExecute(String result) {
mTextView.setText(result);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
//re-enable the button
mButton.setEnabled(true);
}
}, 4000);
}
Note that you can remove the counter logic and it should work as expected now:
public void downloadOnClick(View v) {
Log.d(this.getLocalClassName(), "Button was clicked");
ConnectivityManager connMgr = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
mButton.setEnabled(false);
mTextView.setText("Getting html file...");
// if we use simple http, we will need to handle redirect status code
new DownloadWebpageTask().execute("https://www.google.com/");
} else {
mTextView.setText("No network connection available.");
}
}
The error is here:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="DOWNLOAD TEXT"
android:id="#+id/button"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:onClick="downloadOnClick" />
You are missing the concept of OnClickListener! First of all, you have to modify the above xml in this way removing onClick attribute:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="DOWNLOAD TEXT"
android:id="#+id/button"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
Than you have to modify the Activity onCreate method in order to set the OnClickListener on your button:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = (TextView) findViewById(R.id.text);
mButton = (Button) findViewById(R.id.button);
mButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
counter++;
Log.d(this.getLocalClassName(), "Button was clicked " + counter + " times.");
if(counter>1) return;
ConnectivityManager connMgr = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
mButton.setEnabled(false);
mTextView.setText("Getting html file...");
// if we use simple http, we will need to handle redirect status code
new DownloadWebpageTask().execute("https://www.google.com/");
} else {
mTextView.setText("No network connection available.");
}
}
});
}
This is the right way to handle a click.
See more:
Button | Android Developer
Moreover:
The best way from my point of view is implements the OnClickListener() on your Activity:
public class MyActivity extends Activity implements View.OnClickListener {
}
In this way you can write for each button where you need to set the OnClickListener do:
buttonX.setOnClickListener(this);
buttonY.setOnClickListener(this);
buttonZ.setOnClickListener(this);
In your Activity onClick() you must override the OnClickListener methods, so:
#Override
public void onClick(View v) {
if(v.getId() == R.id.ButtonX)){
//do here what u wanna do.
} else if(v.getId() == R.id.ButtonY){
//do here what u wanna do.
} else if(v.getId() == R.id.ButtonZ){
//do here what u wanna do.
}
}
Also in onClick you could use view.getId() to get the resource ID and then use that in a switch/case block to identify each button and perform the relevant action.
I am building an app that gets 3 contacts from CONTACTS ,,
i want a ready made code to do this and to also show to the user in a layout,, which numbers he has choosen. I have heard that this task is to be done in a background thread I was thinking that if i would do this using
extending AsynTask
is it true?? Please give me full code to do that.
My activity in which i have to include this code is like this:
public class Registration extends Activity implements View.OnClickListener {
RegisteredUser user;
EditText name,mobile ;
Button guardian1,guardian2;
#Override
protected void onCreate(Bundle savedInstanceState) {
Button submit;
super.onCreate(savedInstanceState);
setContentView(R.layout.registration);
submit = (Button) findViewById(R.id.register_registration_submit);
submit.setOnClickListener(this);
}
#Override
public void onClick(View view) {
switch(view.getId()){
case R.id.register_registration_submit:
if(isConnected()){
if(inputData())
Log.d("gone","hum");
new SendRegistrationData(getBaseContext(),Registration.this).execute(user);
}
else
Toast.makeText(getBaseContext(), "You are not connected to internet.Please connect yourself and try again.", Toast.LENGTH_LONG).show();
break;
default: Log.d("application","no button match");
}
}
private boolean inputData() {
user = new RegisteredUser();
name = (EditText) findViewById(R.id.registration_name);
mobile = (EditText) findViewById(R.id.registration_mob);
user.setName(name.getText().toString().trim());
user.setMobile(mobile.getText().toString().trim());
//code to input name and mobile and also validation
//** HERE I WANT CODE TO GET 3 CONTACTS .WHEN USER CLICK ON BUTTON.
button.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View arg0) {
new GetContact().execute();
}
});
/*/ also put a validation to check either the user has choosen
all three contacts if not,, return false to input data ,,
so that form can not be submitted */
return true;
}
public boolean isConnected(){
ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Activity.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected())
return true;
else
return false;
}
}
basically what you need to do to retrieve contacts from your phone is to use Content Providers: http://developer.android.com/guide/topics/providers/content-providers.html
You'll have to query your contacts and say what fields you want to retrieve from them, this query will return a Cursor to you and this cursor can be used to iterate through your contacts.
You can get a complete documentation about it on this page: http://developer.android.com/guide/topics/providers/contacts-provider.html
Once you get a hold of it, it's quite simple.
I want in my application this functionality:
When i start my app
-check if there is interne access : if yes {
start LogInActivity { if login is succesfull
dialog:"synced!" for 3second
else
dialog:"no synced!" for 3second
}
}
dialog:"no synced!"
startMainActivity
I want the first activity just to performs checks.Not to be visible and if there is internet
then forward to login Activity else login to Main activity
This is because i want my app to be used without interner.But for the logged users it will download from web service some information to be stored in Shared Preferences.Any help?
The best way is to create a small function which checks both for wifi and mobile net as follows :-
/**
* Function to check whether internet connection is available or not
*
* #return true - if net is available
*/
public boolean haveNetworkConnection() {
mHaveConnectedWifi = false;
mHaveConnectedMobile = false;
mConnectivityManager = (ConnectivityManager) mContext
.getSystemService(Context.CONNECTIVITY_SERVICE);
mNetworkInfo = mConnectivityManager.getAllNetworkInfo();
for (NetworkInfo mNetInfo : mNetworkInfo) {
if (mNetInfo.getTypeName().equalsIgnoreCase("WIFI"))
if (mNetInfo.isConnected())
mHaveConnectedWifi = true;
if (mNetInfo.getTypeName().equalsIgnoreCase("MOBILE"))
if (mNetInfo.isConnected())
mHaveConnectedMobile = true;
}
return mHaveConnectedWifi || mHaveConnectedMobile;
}
Now in your code just do :-
if(haveNetworkConnection){
// do something
}else{
// no internet
}
The advantage is that we are checking for both wifi and mobile net...
Hope the explanation was useful....
Just create a third activity that starts first and on the onCreate of that activity you run your code and call other activity.
Also you could show a splash screen on this third activity, while you decide which activity to show.
You'll want to either use startActivity() or startActivityForResult().
The advantage of startActivityForResult() is that you can receive data back from the activity you started, upon its completion.
To launch your other activity:
if(connection/login fails){
Intent loginfailed = new Intent(MainActivity.this, loginfailedactivity.class);
startActivity(loginfailed);
}
else {.....}
Here is what I did to make sure there was a wifi connection:
private void checkWifiConnection(String menuUrl){
ConnectivityManager connManager = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
NetworkInfo mWifi = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
if(mWifi.isConnected()){
LoadJSON lJs = new LoadJSON();
lJs.execute(menuUrl);
} else {
AlertDialog.Builder ab = new AlertDialog.Builder(context);
ab.setCancelable(true);
ab.setTitle("No Connection");
ab.setMessage("Your device is currently not connected to the Internet, please check your connection and launch the app again.");
ab.setInverseBackgroundForced(true);
ab.setPositiveButton("Okay", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
MainActivity.this.finish();
}
});
AlertDialog alert = ab.create();
alert.show();
}
You could insert an Intent call in the if statement that launches your Activity