RSS

Most votes on android questions 10

Most votes on android questions 10. #91 How do I get the current GPS location programmatically in Android? #92 Best practice for instantiating a new Android Fragment #93 Can I underline text in an Android layout? #94 decompiling DEX into Java sourcecode #95 "cannot resolve symbol R" in Android Studio #96 Cannot inline bytecode built with JVM target 1.8 into bytecode that is being built with JVM target 1.6 #97 What are the best practices for SQLite on Android? #98 Detect whether there is an Internet connection available on Android #99 Using context in a fragment #100 AsyncTask Android example

Read all the top votes questions and answers in a single page.

#91: How do I get the current GPS location programmatically in Android? (Score: 736)

Created: 2009-10-03 Last updated: 2016-07-18

Tags: android, geolocation, gps, location

I need to get my current location using GPS programmatically. How can i achieve it?

#91 Best answer 1 of How do I get the current GPS location programmatically in Android? (Score: 443)

Created: 2012-06-06 Last updated: 2016-01-06

I have created a small application with step by step description to get current location’s GPS coordinates.

Complete example source code is in Get Current Location coordinates , City name - in Android.


See how it works:

  • All we need to do is add this permission in the manifest file:

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    
  • And create a LocationManager instance like this:

     LocationManager locationManager = (LocationManager)
     getSystemService(Context.LOCATION_SERVICE);
    
  • Check if GPS is enabled or not.

  • And then implement LocationListener and get coordinates:

     LocationListener locationListener = new MyLocationListener();
     locationManager.requestLocationUpdates(
     LocationManager.GPS_PROVIDER, 5000, 10, locationListener);
    
  • Here is the sample code to do so


/*---------- Listener class to get coordinates ------------- */
private class MyLocationListener implements LocationListener {

    @Override
    public void onLocationChanged(Location loc) {
        editLocation.setText("");
        pb.setVisibility(View.INVISIBLE);
        Toast.makeText(
                getBaseContext(),
                "Location changed: Lat: " + loc.getLatitude() + " Lng: "
                    + loc.getLongitude(), Toast.LENGTH_SHORT).show();
        String longitude = "Longitude: " + loc.getLongitude();
        Log.v(TAG, longitude);
        String latitude = "Latitude: " + loc.getLatitude();
        Log.v(TAG, latitude);

        /*------- To get city name from coordinates -------- */
        String cityName = null;
        Geocoder gcd = new Geocoder(getBaseContext(), Locale.getDefault());
        List<Address> addresses;
        try {
            addresses = gcd.getFromLocation(loc.getLatitude(),
                    loc.getLongitude(), 1);
            if (addresses.size() > 0) {
                System.out.println(addresses.get(0).getLocality());
                cityName = addresses.get(0).getLocality();
            }
        }
        catch (IOException e) {
            e.printStackTrace();
        }
        String s = longitude + "\n" + latitude + "\n\nMy Current City is: "
            + cityName;
        editLocation.setText(s);
    }

    @Override
    public void onProviderDisabled(String provider) {}

    @Override
    public void onProviderEnabled(String provider) {}

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {}
}

#91 Best answer 2 of How do I get the current GPS location programmatically in Android?(Score: 146)

Created: 2012-10-18 Last updated: 2019-03-28

Here is additional information for other answers.

Since Android has

GPS_PROVIDER and NETWORK_PROVIDER

you can register to both and start fetch events from onLocationChanged(Location location) from two at the same time. So far so good. Now the question do we need two results or we should take the best. As I know GPS_PROVIDER results have better accuracy than NETWORK_PROVIDER.

Let’s define Location field:

private Location currentBestLocation = null;

Before we start listen on Location change we will implement the following method. This method returns the last known location, between the GPS and the network one. For this method newer is best.

/**
 * @return the last know best location
 */
private Location getLastBestLocation() {
    Location locationGPS = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
    Location locationNet = mLocationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);

    long GPSLocationTime = 0;
    if (null != locationGPS) { GPSLocationTime = locationGPS.getTime(); }

    long NetLocationTime = 0;

    if (null != locationNet) {
        NetLocationTime = locationNet.getTime();
    }

    if ( 0 < GPSLocationTime - NetLocationTime ) {
        return locationGPS;
    }
    else {
        return locationNet;
    }
}

Each time when we retrieve a new location we will compare it with our previous result.

...
static final int TWO_MINUTES = 1000 * 60 * 2;
...

I add a new method to onLocationChanged:

@Override
public void onLocationChanged(Location location) {

    makeUseOfNewLocation(location);

    if(currentBestLocation == null){
        currentBestLocation = location;
    }

    ....
}


/**
 * This method modify the last know good location according to the arguments.
 *
 * @param location The possible new location.
 */
void makeUseOfNewLocation(Location location) {
    if ( isBetterLocation(location, currentBestLocation) ) {
        currentBestLocation = location;
    }
}

....

/** Determines whether one location reading is better than the current location fix
 * @param location  The new location that you want to evaluate
 * @param currentBestLocation  The current location fix, to which you want to compare the new one.
 */
protected boolean isBetterLocation(Location location, Location currentBestLocation) {
    if (currentBestLocation == null) {
        // A new location is always better than no location
        return true;
    }

    // Check whether the new location fix is newer or older
    long timeDelta = location.getTime() - currentBestLocation.getTime();
    boolean isSignificantlyNewer = timeDelta > TWO_MINUTES;
    boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;
    boolean isNewer = timeDelta > 0;

    // If it's been more than two minutes since the current location, use the new location,
    // because the user has likely moved.
    if (isSignificantlyNewer) {
        return true;
        // If the new location is more than two minutes older, it must be worse.
    } else if (isSignificantlyOlder) {
        return false;
    }

    // Check whether the new location fix is more or less accurate
    int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy());
    boolean isLessAccurate = accuracyDelta > 0;
    boolean isMoreAccurate = accuracyDelta < 0;
    boolean isSignificantlyLessAccurate = accuracyDelta > 200;

    // Check if the old and new location are from the same provider
    boolean isFromSameProvider = isSameProvider(location.getProvider(),
                                                currentBestLocation.getProvider());

    // Determine location quality using a combination of timeliness and accuracy
    if (isMoreAccurate) {
        return true;
    } else if (isNewer && !isLessAccurate) {
        return true;
    } else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) {
        return true;
    }
    return false;
}

// Checks whether two providers are the same
private boolean isSameProvider(String provider1, String provider2) {
    if (provider1 == null) {
        return provider2 == null;
    }
    return provider1.equals(provider2);
}

....

See also original question in stackoverflow

#92: Best practice for instantiating a new Android Fragment (Score: 735)

Created: 2012-02-12 Last updated: 2016-04-19

Tags: android, android-fragments

I have seen two general practices to instantiate a new Fragment in an application:

Fragment newFragment = new MyFragment();

and

Fragment newFragment = MyFragment.newInstance();

The second option makes use of a static method newInstance() and generally contains the following method.

public static Fragment newInstance() 
{
    MyFragment myFragment = new MyFragment();
    return myFragment;
}

At first, I thought the main benefit was the fact that I could overload the newInstance() method to give flexibility when creating new instances of a Fragment - but I could also do this by creating an overloaded constructor for the Fragment.

Did I miss something?

What are the benefits of one approach over the other? Or is it just good practice?

#92 Best answer 1 of Best practice for instantiating a new Android Fragment (Score: 1197)

Created: 2012-02-12 Last updated: 2016-08-14

If Android decides to recreate your Fragment later, it’s going to call the no-argument constructor of your fragment. So overloading the constructor is not a solution.

With that being said, the way to pass stuff to your Fragment so that they are available after a Fragment is recreated by Android is to pass a bundle to the setArguments method.

So, for example, if we wanted to pass an integer to the fragment we would use something like:

public static MyFragment newInstance(int someInt) {
    MyFragment myFragment = new MyFragment();

    Bundle args = new Bundle();
    args.putInt("someInt", someInt);
    myFragment.setArguments(args);

    return myFragment;
}

And later in the Fragment onCreate() you can access that integer by using:

getArguments().getInt("someInt", 0);

This Bundle will be available even if the Fragment is somehow recreated by Android.

Also note: setArguments can only be called before the Fragment is attached to the Activity.

This approach is also documented in the android developer reference: https://developer.android.com/reference/android/app/Fragment.html

#92 Best answer 2 of Best practice for instantiating a new Android Fragment(Score: 98)

Created: 2012-02-12 Last updated: 2014-12-19

The only benefit in using the newInstance() that I see are the following:

  1. You will have a single place where all the arguments used by the fragment could be bundled up and you don’t have to write the code below everytime you instantiate a fragment.

     Bundle args = new Bundle();
     args.putInt("someInt", someInt);
     args.putString("someString", someString);
     // Put any other arguments
     myFragment.setArguments(args);
    
  2. Its a good way to tell other classes what arguments it expects to work faithfully(though you should be able to handle cases if no arguments are bundled in the fragment instance).

So, my take is that using a static newInstance() to instantiate a fragment is a good practice.

See also original question in stackoverflow

#93: Can I underline text in an Android layout? (Score: 734)

Created: 2010-03-07 Last updated: 2018-10-11

Tags: android, android-layout, fonts

How can I define underlined text in an Android layout xml file?

#93 Best answer 1 of Can I underline text in an Android layout? (Score: 1224)

Created: 2010-03-07 Last updated: 2017-10-25

It can be achieved if you are using a string resource xml file, which supports HTML tags like <b></b>, <i></i> and <u></u>.

<resources>
    <string name="your_string_here">This is an <u>underline</u>.</string>
</resources>

If you want to underline something from code use:

TextView textView = (TextView) view.findViewById(R.id.textview);
SpannableString content = new SpannableString("Content");
content.setSpan(new UnderlineSpan(), 0, content.length(), 0);
textView.setText(content);

#93 Best answer 2 of Can I underline text in an Android layout?(Score: 564)

Created: 2012-06-08 Last updated: 2012-06-28

You can try with

textview.setPaintFlags(textview.getPaintFlags() |   Paint.UNDERLINE_TEXT_FLAG);

See also original question in stackoverflow

#94: decompiling DEX into Java sourcecode (Score: 733)

Created: 2009-08-08 Last updated: 2014-06-21

Tags: java, android, reverse-engineering, decompiler, dex

How can one decompile Android DEX (VM bytecode) files into corresponding Java sourcecode?

#94 Best answer 1 of decompiling DEX into Java sourcecode (Score: 909)

Created: 2010-11-14 Last updated: 2020-08-27

It’s easy

Get these tools:

  1. dex2jar to translate dex files to jar files

  2. jd-gui to view the java files in the jar

The source code is quite readable as dex2jar makes some optimizations.

Procedure:

And here’s the procedure on how to decompile:

Step 1:

Convert classes.dex in test_apk-debug.apk to test_apk-debug_dex2jar.jar

d2j-dex2jar.sh -f -o output_jar.jar apk_to_decompile.apk
d2j-dex2jar.sh -f -o output_jar.jar dex_to_decompile.dex

Note 1: In the Windows machines all the .sh scripts are replaced by .bat scripts

Note 2: On linux/mac don’t forget about sh or bash. The full command should be:

sh d2j-dex2jar.sh -f -o output_jar.jar apk_to_decompile.apk 

Note 3: Also, remember to add execute permission to dex2jar-X.X directory e.g. sudo chmod -R +x dex2jar-2.0

dex2jar documentation

Step 2:

Open the jar in JD-GUI

The decompiled source

#94 Best answer 2 of decompiling DEX into Java sourcecode(Score: 142)

Created: 2011-11-04 Last updated: 2017-05-23

To clarify somewhat, there are two major paths you might take here depending on what you want to accomplish:

Decompile the Dalvik bytecode (dex) into readable Java source. You can do this easily with dex2jar and jd-gui, as fred mentions. The resulting source is useful to read and understand the functionality of an app, but will likely not produce 100% usable code. In other words, you can read the source, but you can’t really modify and repackage it. Note that if the source has been obfuscated with proguard, the resulting source code will be substantially more difficult to untangle.

The other major alternative is to disassemble the bytecode to smali, an assembly language designed for precisely this purpose. I’ve found that the easiest way to do this is with apktool. Once you’ve got apktool installed, you can just point it at an apk file, and you’ll get back a smali file for each class contained in the application. You can read and modify the smali or even replace classes entirely by generating smali from new Java source (to do this, you could compile your .java source to .class files with javac, then convert your .class files to .dex files with Android’s dx compiler, and then use baksmali (smali disassembler) to convert the .dex to .smali files, as described in this question. There might be a shortcut here). Once you’re done, you can easily package the apk back up with apktool again. Note that apktool does not sign the resulting apk, so you’ll need to take care of that just like any other Android application.

If you go the smali route, you might want to try APK Studio, an IDE that automates some of the above steps to assist you with decompiling and recompiling an apk and installing it on a device.

In short, your choices are pretty much either to decompile into Java, which is more readable but likely irreversible, or to disassemble to smali, which is harder to read but much more flexible to make changes and repackage a modified app. Which approach you choose would depend on what you’re looking to achieve.

Lastly, the suggestion of dare is also of note. It’s a retargeting tool to convert .dex and .apk files to java .class files, so that they can be analyzed using typical java static analysis tools.

See also original question in stackoverflow

#95: "cannot resolve symbol R" in Android Studio (Score: 732)

Created: 2013-06-11 Last updated: 2018-11-07

Tags: android, android-studio, r.java-file

In every instance in all of my classes where I reference R.id.something, the R is in red and it says “cannot resolve symbol R”. Also every time there is R.layout.something it is underlined in red and says “cannot resolve method setContentView(?)”. The project always builds fine. It is annoying to see this all the time. I have read many other questions on here about something similar but most involved importing projects from Eclipse. I am using what I believe to be the most recent version of Android Studio and the project was created with Android Studio and worked without any “cannot resolve R” problems. I would like to know what causes this if anyone knows.

#95 Best answer 1 of "cannot resolve symbol R" in Android Studio (Score: 725)

Created: 2013-08-12 Last updated: 2015-02-23

I had this this issue too. A simple ‘gradlew clean’ and ‘gradlew build’ did the trick.


Click on Build->Clean Project and that will perform a gradle clean

#95 Best answer 2 of "cannot resolve symbol R" in Android Studio(Score: 231)

Created: 2013-11-19 Last updated: 2018-07-31

In the latest versions of Android Studio, at least for me, the following works:

“Tools” -> “Android” -> “Sync Project with Gradle Files”

In latest Android Studio 3.1.3 (July 2018), “Sync Project with Gradle Files” is available in main menu bar.

enter image description here

See also original question in stackoverflow

#96: Cannot inline bytecode built with JVM target 1.8 into bytecode that is being built with JVM target 1.6 (Score: 709)

Created: 2018-02-26 Last updated: 2020-07-23

Tags: android, intellij-idea, kotlin, jvm, corda

When trying to run the Example CorDapp (GitHub CorDapp) via IntelliJ, I receive the following error:

Cannot inline bytecode built with JVM target 1.8 into bytecode that is being built with JVM target 1.6

How can I modify the IntelliJ settings so that all the bytecode is built with the same JVM target?

#96 Best answer 1 of Cannot inline bytecode built with JVM target 1.8 into bytecode that is being built with JVM target 1.6 (Score: 1474)

Created: 2019-07-11 Last updated: 2020-02-17

app/build.gradle

android {
    ...
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    kotlinOptions {
        jvmTarget = JavaVersion.VERSION_1_8.toString()
    }
}

GL

Use Java 8 language features

#96 Best answer 2 of Cannot inline bytecode built with JVM target 1.8 into bytecode that is being built with JVM target 1.6(Score: 278)

Created: 2018-02-26 Last updated: 2019-07-17

You can fix this issue as follows:

  • Open the IntelliJ preferences
  • Go to Build, Execution, Deployment > Compiler > Kotlin Compiler BUT Other Settings > Kotlin compiler if Android Studio > 3.4
  • Change the Target JVM version to 1.8
  • Click Apply

See also original question in stackoverflow

#97: What are the best practices for SQLite on Android? (Score: 709)

Created: 2010-03-22 Last updated: 2016-04-19

Tags: android, database, sqlite

What would be considered the best practices when executing queries on an SQLite database within an Android app?

Is it safe to run inserts, deletes and select queries from an AsyncTask’s doInBackground? Or should I use the UI Thread? I suppose that database queries can be “heavy” and should not use the UI thread as it can lock up the app - resulting in an Application Not Responding (ANR).

If I have several AsyncTasks, should they share a connection or should they open a connection each?

Are there any best practices for these scenarios?

#97 Best answer 1 of What are the best practices for SQLite on Android? (Score: 636)

Created: 2010-09-11 Last updated: 2018-04-17

Inserts, updates, deletes and reads are generally OK from multiple threads, but Brad’s answer is not correct. You have to be careful with how you create your connections and use them. There are situations where your update calls will fail, even if your database doesn’t get corrupted.

The basic answer.

The SqliteOpenHelper object holds on to one database connection. It appears to offer you a read and write connection, but it really doesn’t. Call the read-only, and you’ll get the write database connection regardless.

So, one helper instance, one db connection. Even if you use it from multiple threads, one connection at a time. The SqliteDatabase object uses java locks to keep access serialized. So, if 100 threads have one db instance, calls to the actual on-disk database are serialized.

So, one helper, one db connection, which is serialized in java code. One thread, 1000 threads, if you use one helper instance shared between them, all of your db access code is serial. And life is good (ish).

If you try to write to the database from actual distinct connections at the same time, one will fail. It will not wait till the first is done and then write. It will simply not write your change. Worse, if you don’t call the right version of insert/update on the SQLiteDatabase, you won’t get an exception. You’ll just get a message in your LogCat, and that will be it.

So, multiple threads? Use one helper. Period. If you KNOW only one thread will be writing, you MAY be able to use multiple connections, and your reads will be faster, but buyer beware. I haven’t tested that much.

Here’s a blog post with far more detail and an example app.

Gray and I are actually wrapping up an ORM tool, based off of his Ormlite, that works natively with Android database implementations, and follows the safe creation/calling structure I describe in the blog post. That should be out very soon. Take a look.


In the meantime, there is a follow up blog post:

Also checkout the fork by 2point0 of the previously mentioned locking example:

#97 Best answer 2 of What are the best practices for SQLite on Android?(Score: 193)

Created: 2013-11-15 Last updated: 2019-02-01

Concurrent Database Access

Same article on my blog(I like formatting more)

I wrote small article which describe how to make access to your android database thread safe.


Assuming you have your own SQLiteOpenHelper.

public class DatabaseHelper extends SQLiteOpenHelper { ... }

Now you want to write data to database in separate threads.

 // Thread 1
 Context context = getApplicationContext();
 DatabaseHelper helper = new DatabaseHelper(context);
 SQLiteDatabase database = helper.getWritableDatabase();
 database.insert(…);
 database.close();

 // Thread 2
 Context context = getApplicationContext();
 DatabaseHelper helper = new DatabaseHelper(context);
 SQLiteDatabase database = helper.getWritableDatabase();
 database.insert(…);
 database.close();

You will get following message in your logcat and one of your changes will not be written.

android.database.sqlite.SQLiteDatabaseLockedException: database is locked (code 5)

This is happening because every time you create new SQLiteOpenHelper object you are actually making new database connection. If you try to write to the database from actual distinct connections at the same time, one will fail. (from answer above)

To use database with multiple threads we need to make sure we are using one database connection.

Let’s make singleton class Database Manager which will hold and return single SQLiteOpenHelper object.

public class DatabaseManager {

    private static DatabaseManager instance;
    private static SQLiteOpenHelper mDatabaseHelper;

    public static synchronized void initializeInstance(SQLiteOpenHelper helper) {
        if (instance == null) {
            instance = new DatabaseManager();
            mDatabaseHelper = helper;
        }
    }

    public static synchronized DatabaseManager getInstance() {
        if (instance == null) {
            throw new IllegalStateException(DatabaseManager.class.getSimpleName() +
                    " is not initialized, call initialize(..) method first.");
        }

        return instance;
    }

    public SQLiteDatabase getDatabase() {
        return new mDatabaseHelper.getWritableDatabase();
    }

}

Updated code which write data to database in separate threads will look like this.

 // In your application class
 DatabaseManager.initializeInstance(new MySQLiteOpenHelper());
 // Thread 1
 DatabaseManager manager = DatabaseManager.getInstance();
 SQLiteDatabase database = manager.getDatabase()
 database.insert(…);
 database.close();

 // Thread 2
 DatabaseManager manager = DatabaseManager.getInstance();
 SQLiteDatabase database = manager.getDatabase()
 database.insert(…);
 database.close();

This will bring you another crash.

java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase

Since we are using only one database connection, method getDatabase() return same instance of SQLiteDatabase object for Thread1 and Thread2. What is happening, Thread1 may close database, while Thread2 is still using it. That’s why we have IllegalStateException crash.

We need to make sure no-one is using database and only then close it. Some folks on stackoveflow recommended to never close your SQLiteDatabase. This will result in following logcat message.

Leak found
Caused by: java.lang.IllegalStateException: SQLiteDatabase created and never closed

Working sample

public class DatabaseManager {

    private int mOpenCounter;

    private static DatabaseManager instance;
    private static SQLiteOpenHelper mDatabaseHelper;
    private SQLiteDatabase mDatabase;

    public static synchronized void initializeInstance(SQLiteOpenHelper helper) {
        if (instance == null) {
            instance = new DatabaseManager();
            mDatabaseHelper = helper;
        }
    }

    public static synchronized DatabaseManager getInstance() {
        if (instance == null) {
            throw new IllegalStateException(DatabaseManager.class.getSimpleName() +
                    " is not initialized, call initializeInstance(..) method first.");
        }

        return instance;
    }

    public synchronized SQLiteDatabase openDatabase() {
        mOpenCounter++;
        if(mOpenCounter == 1) {
            // Opening new database
            mDatabase = mDatabaseHelper.getWritableDatabase();
        }
        return mDatabase;
    }

    public synchronized void closeDatabase() {
        mOpenCounter--;
        if(mOpenCounter == 0) {
            // Closing database
            mDatabase.close();
            
        }
    }

}

Use it as follows.

SQLiteDatabase database = DatabaseManager.getInstance().openDatabase();
database.insert(...);
// database.close(); Don't close it directly!
DatabaseManager.getInstance().closeDatabase(); // correct way

Every time you need database you should call openDatabase() method of DatabaseManager class. Inside this method, we have a counter, which indicate how many times database is opened. If it equals to one, it means we need to create new database connection, if not, database connection is already created.

The same happens in closeDatabase() method. Every time we call this method, counter is decreased, whenever it goes to zero, we are closing database connection.


Now you should be able to use your database and be sure it’s thread safe.

See also original question in stackoverflow

#98: Detect whether there is an Internet connection available on Android (Score: 707)

Created: 2010-11-21 Last updated: 2020-10-09

Tags: android, internet-connection, android-internet

Possible Duplicate:
How to check internet access on Android? InetAddress never timeouts

I need to detect whether the Android device is connected to the Internet.

The NetworkInfo class provides a non-static method isAvailable() that sounds perfect.

Problem is that:

NetworkInfo ni = new NetworkInfo();
if (!ni.isAvailable()) {
    // do something
}

throws this error:

The constructor NetworkInfo is not visible.

Safe bet is there is another class that returns a NetworkInfo object. But I don’t know which.

  1. How to get the above snippet of code to work?
  2. How could I have found myself the information I needed in the online documentation?
  3. Can you suggest a better way for this type of detection?

#98 Best answer 1 of Detect whether there is an Internet connection available on Android (Score: 1452)

Created: 2010-11-21 Last updated: 2015-08-24

The getActiveNetworkInfo() method of ConnectivityManager returns a NetworkInfo instance representing the first connected network interface it can find or null if none of the interfaces are connected. Checking if this method returns null should be enough to tell if an internet connection is available or not.

private boolean isNetworkAvailable() {
    ConnectivityManager connectivityManager 
          = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
    return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}

You will also need:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

in your android manifest.

Edit:

Note that having an active network interface doesn’t guarantee that a particular networked service is available. Network issues, server downtime, low signal, captive portals, content filters and the like can all prevent your app from reaching a server. For instance you can’t tell for sure if your app can reach Twitter until you receive a valid response from the Twitter service.

#98 Best answer 2 of Detect whether there is an Internet connection available on Android(Score: 251)

Created: 2010-11-21 Last updated: 2011-11-25

I check for both Wi-fi and Mobile internet as follows…

private boolean haveNetworkConnection() {
    boolean haveConnectedWifi = false;
    boolean haveConnectedMobile = false;

    ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo[] netInfo = cm.getAllNetworkInfo();
    for (NetworkInfo ni : netInfo) {
        if (ni.getTypeName().equalsIgnoreCase("WIFI"))
            if (ni.isConnected())
                haveConnectedWifi = true;
        if (ni.getTypeName().equalsIgnoreCase("MOBILE"))
            if (ni.isConnected())
                haveConnectedMobile = true;
    }
    return haveConnectedWifi || haveConnectedMobile;
}

Obviously, It could easily be modified to check for individual specific connection types, e.g., if your app needs the potentially higher speeds of Wi-fi to work correctly etc.

See also original question in stackoverflow

#99: Using context in a fragment (Score: 702)

Created: 2011-11-21 Last updated: 2018-10-17

Tags: java, android, android-fragments, android-context

How can I get the context in a fragment?

I need to use my database whose constructor takes in the context, but getApplicationContext() and FragmentClass.this don’t work so what can I do?

Database constructor

public Database(Context ctx)
{
    this.context = ctx;
    DBHelper = new DatabaseHelper(context);
}

#99 Best answer 1 of Using context in a fragment (Score: 1371)

Created: 2011-11-21 Last updated: 2019-02-19

You can use getActivity(), which returns the activity associated with a fragment.
The activity is a context (since Activity extends Context).

#99 Best answer 2 of Using context in a fragment(Score: 134)

Created: 2012-10-25 Last updated: 2017-07-29

To do as the answer above, you can override the onAttach method of fragment:

public static class DummySectionFragment extends Fragment{
...
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        DBHelper = new DatabaseHelper(activity);
    }
}

See also original question in stackoverflow

#100: AsyncTask Android example (Score: 691)

Created: 2012-03-12 Last updated: 2019-01-24

Tags: android, android-asynctask

I was reading about AsyncTask, and I tried the simple program below. But it does not seem to work. How can I make it work?

public class AsyncTaskActivity extends Activity {

    Button btn;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        btn = (Button) findViewById(R.id.button1);
        btn.setOnClickListener((OnClickListener) this);
    }

    public void onClick(View view){
        new LongOperation().execute("");
    }

    private class LongOperation extends AsyncTask<String, Void, String> {
        @Override
        protected String doInBackground(String... params) {
            for(int i=0;i<5;i++) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            TextView txt = (TextView) findViewById(R.id.output);
            txt.setText("Executed");
            return null;
        }

        @Override
        protected void onPostExecute(String result) {
        }

        @Override
        protected void onPreExecute() {
        }

        @Override
        protected void onProgressUpdate(Void... values) {
        }
    }
}

I am just trying to change the label after 5 seconds in the background process.

This is my main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
              android:orientation="vertical" >
    <ProgressBar
        android:id="@+id/progressBar"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:indeterminate="false"
        android:max="10"
        android:padding="10dip">
    </ProgressBar>
    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Start Progress" >
    </Button>
    <TextView android:id="@+id/output"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Replace"/>
</LinearLayout>

#100 Best answer 1 of AsyncTask Android example (Score: 818)

Created: 2015-04-10 Last updated: 2019-11-25

My full answer is here, but here is an explanatory image to supplement the other answers on this page. For me, understanding where all the variables were going was the most confusing part in the beginning.

enter image description here

#100 Best answer 2 of AsyncTask Android example(Score: 707)

Created: 2012-03-12 Last updated: 2019-11-25

Ok, you are trying to access the GUI via another thread. This, in the main, is not good practice.

The AsyncTask executes everything in doInBackground() inside of another thread, which does not have access to the GUI where your views are.

preExecute() and postExecute() offer you access to the GUI before and after the heavy lifting occurs in this new thread, and you can even pass the result of the long operation to postExecute() to then show any results of processing.

See these lines where you are later updating your TextView:

TextView txt = findViewById(R.id.output);
txt.setText("Executed");

Put them in onPostExecute().

You will then see your TextView text updated after the doInBackground completes.

I noticed that your onClick listener does not check to see which View has been selected. I find the easiest way to do this is via switch statements. I have a complete class edited below with all suggestions to save confusion.

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.Settings.System;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.view.View.OnClickListener;

public class AsyncTaskActivity extends Activity implements OnClickListener {

    Button btn;
    AsyncTask<?, ?, ?> runningTask;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        btn = findViewById(R.id.button1);

        // Because we implement OnClickListener, we only
        // have to pass "this" (much easier)
        btn.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        // Detect the view that was "clicked"
        switch (view.getId()) {
        case R.id.button1:
            if (runningTask != null)
                runningTask.cancel(true);
            runningTask = new LongOperation();
            runningTask.execute();
            break;
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // Cancel running task(s) to avoid memory leaks
        if (runningTask != null)
            runningTask.cancel(true);
    }

    private final class LongOperation extends AsyncTask<Void, Void, String> {

        @Override
        protected String doInBackground(Void... params) {
            for (int i = 0; i < 5; i++) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // We were cancelled; stop sleeping!
                }
            }
            return "Executed";
        }

        @Override
        protected void onPostExecute(String result) {
            TextView txt = (TextView) findViewById(R.id.output);
            txt.setText("Executed"); // txt.setText(result);
            // You might want to change "executed" for the returned string
            // passed into onPostExecute(), but that is up to you
        }
    }
}

See also original question in stackoverflow


Notes:
  1. This page use API to get the relevant data from stackoverflow community.
  2. Content license on this page is CC BY-SA 3.0.
  3. score = up votes - down votes.