0

I have created an android application using Android studio, that tries to check if there is an updated version of the file used by the application, which is stored in the assets directory. I have checked that the file is available and accessible, but as I cannot share the file location i'll be using the following text file for this example: http://www.w3.org/TR/PNG/iso_8859-1.txt

I have kept in mind to include the followings in my code:

1- add uses-permissions in the manifest.xml file as the following:

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

2- Created AsyncTask to perform the read of the file in the background:

import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

public class CheckUpdate extends AsyncTask<Void,Void,Boolean>
{

String filename = "http://www.w3.org/TR/PNG/iso_8859-1.txt";

private Context ctx;

public CheckUpdate(Context myContext) {
    this.ctx = myContext;
    doInBackground();

}

@Override
protected Boolean doInBackground(Void... voids) {
    try {
        URL url = new URL(filename);
        File LocalFile = new File("file:///android_asset/test.txt");

        HttpURLConnection ucon = (HttpURLConnection) url.openConnection();
ucon.setReadTimeout(5000);
ucon.setConnectTimeout(10000);
ucon.setDoInput(true);
        ucon.setDoOutput(true);
        ucon.connect();
        if (ucon.getResponseCode() == 200) {
            InputStream isURL = ucon.getInputStream();
            BufferedInputStream inStream = new BufferedInputStream(isURL);

            long LocalFileModifiedDate = LocalFile.lastModified();
            long ExFileModifiedDate = ucon.getLastModified();

            if (LocalFile.exists()) {
                LocalFile.delete();
            }

            if (LocalFileModifiedDate < ExFileModifiedDate) {
                LocalFile.createNewFile();

                FileOutputStream outStream = new FileOutputStream(LocalFile);
                byte[] buff = new byte[5 * 1024];

                int len;
                while ((len = inStream.read(buff)) != -1) {
                    outStream.write(buff, 0, len);
                }

                outStream.flush();
                outStream.close();
            }
            inStream.close();
        } else {
            return false;
        }
    }catch (MalformedURLException e1) {
        e1.printStackTrace();
        return false;
    } catch (IOException e1) {
        e1.printStackTrace();
        return false;
    }catch (Exception e)
        {
            e.printStackTrace();
            return false;
        }

        return true;
    }

}    

3- Check Wireless connectivity in the MainActivity:

ConnectivityManager connManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    @SuppressLint("MissingPermission") NetworkInfo mWifi = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);

    if (mWifi.isConnected()) {
        CheckUpdate checkUpdate = new CheckUpdate(getApplicationContext());
    }

But unfortunately I'm getting the following error message:

W/System.err: android.os.NetworkOnMainThreadException
              at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1513)
W/System.err:     at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:117)
W/System.err:     at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:105)
              at java.net.InetAddress.getAllByName(InetAddress.java:1154)
              at com.android.okhttp.Dns$1.lookup(Dns.java:39)
W/System.err:     at com.android.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:175)
W/System.err:     at com.android.okhttp.internal.http.RouteSelector.nextProxy(RouteSelector.java:141)
              at com.android.okhttp.internal.http.RouteSelector.next(RouteSelector.java:83)
W/System.err:     at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:174)
              at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:126)
 W/System.err:     at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:95)
              at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:281)
              at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:224)
 W/System.err:     at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:461)
              at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:127)
 W/System.err:     at **com.Project.CheckUpdate.doInBackground(CheckUpdate.java:40)**
              at com.Project.CheckUpdate.<init>(CheckUpdate.java:25)
 W/System.err:     at com.Project.MainActivity.onCreate(MainActivity.java:124)
              at android.app.Activity.performCreate(Activity.java:7136)
              at android.app.Activity.performCreate(Activity.java:7127)
 W/System.err:     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
              at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2893)
 W/System.err:     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
 W/System.err:     at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
              at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
              at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
 W/System.err:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
              at android.os.Handler.dispatchMessage(Handler.java:106)
              at android.os.Looper.loop(Looper.java:193)
              at android.app.ActivityThread.main(ActivityThread.java:6669)
W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
              at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
              at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)    

Many Thanks in Advance ...

Jawad AlZaabi
  • 75
  • 1
  • 7
  • The first thing you need to check if is you can hit that URL from e.g. a browser from the same Android phone or WiFi connection. If you _can't_ hit that URL from a browser, then obviously your async task might not work. – Tim Biegeleisen Aug 12 '18 at 04:33

1 Answers1

1

You should not call doInBackground() method in a constructor of your CheckUpdate class. You are calling the constructor in the main thread, so doInBackground() invoked in the main thread too. It leads to NetworkOnMainThreadException. Here are some links how to use AsyncTask: link, link.

You need to refactor a constructor of a CheckUpdate.java like this:

public CheckUpdate(Context myContext) {
    this.ctx = myContext;
}

and use it like this:

if (mWifi.isConnected()) {
    CheckUpdate checkUpdate = new CheckUpdate(getApplicationContext());
    checkUpdate.execute();
}
Oleg Sokolov
  • 1,134
  • 1
  • 12
  • 19