Error inserting an image of a url in an imageview

3

Good morning,

I would like in my application to be able to change the image of an ImageView without having to be updating the app so often. I have thought about saving the image in a web server and having the image downloaded every time the app is opened. So when I change the image on the server, it will be changed in the app.

The problem is that when I try to change the image it gives me an error.

The code is as follows:

    public class FragmentInicio extends Fragment {

    private static URL imgurl;

    public FragmentInicio() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_inicio, container, false);
        ImageView logo = (ImageView) v.findViewById(R.id.imageEccaInicio);
        try {
            imgurl = new URL("https://s-media-cache-ak0.pinimg.com/236x/22/c8/9e/22c89e308d734b5daa9f383419b1bdc5.jpg");
            Bitmap mIcon_val = BitmapFactory.decodeStream(imgurl.openConnection().getInputStream());
            logo.setImageBitmap(mIcon_val);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }catch (IOException e) {
            e.printStackTrace();
        }

        logo.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View view){
                //Toast.makeText(view.getContext(), "Se ha tocado la imagen", Toast.LENGTH_LONG).show();
                //Llama al método openDrawer de la actividad principal para abrir el menú lateral.
                ((MainActivity)getActivity()).openDrawer();
            }
        });
        return v;
    }

}

If I comment everything that is inside the try, the application takes by default the image of the layout and does not give an error. But I'm interested in the image being taken from the URL that happened to it.

This is the error it gives:

E/AndroidRuntime: FATAL EXCEPTION: main
                  Process: ecca.radio, PID: 2839
                  java.lang.RuntimeException: Unable to start activity ComponentInfo{ecca.radio/ecca.radio.MainActivity}: android.os.NetworkOnMainThreadException
                      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
                      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
                      at android.app.ActivityThread.-wrap11(ActivityThread.java)
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
                      at android.os.Handler.dispatchMessage(Handler.java:102)
                      at android.os.Looper.loop(Looper.java:148)
                      at android.app.ActivityThread.main(ActivityThread.java:5417)
                      at java.lang.reflect.Method.invoke(Native Method)
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
                   Caused by: android.os.NetworkOnMainThreadException
                      at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1273)
                      at java.net.InetAddress.lookupHostByName(InetAddress.java:431)
                      at java.net.InetAddress.getAllByNameImpl(InetAddress.java:252)
                      at java.net.InetAddress.getAllByName(InetAddress.java:215)
                      at com.android.okhttp.internal.Network$1.resolveInetAddresses(Network.java:29)
                      at com.android.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:188)
                      at com.android.okhttp.internal.http.RouteSelector.nextProxy(RouteSelector.java:157)
                      at com.android.okhttp.internal.http.RouteSelector.next(RouteSelector.java:100)
                      at com.android.okhttp.internal.http.HttpEngine.createNextConnection(HttpEngine.java:357)
                      at com.android.okhttp.internal.http.HttpEngine.nextConnection(HttpEngine.java:340)
                      at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:330)
                      at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:248)
                      at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:433)
                      at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:384)
                      at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:231)
                      at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getInputStream(DelegatingHttpsURLConnection.java:210)
                      at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java)
                      at ecca.radio.navigationDrawer.FragmentInicio.onCreateView(FragmentInicio.java:43)
                      at android.support.v4.app.Fragment.performCreateView(Fragment.java:1962)
                      at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067)
                      at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1248)
                      at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:738)
                      at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1613)
                      at android.support.v4.app.FragmentController.execPendingActions(FragmentController.java:330)
                      at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:547)
                      at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1237)
                      at android.app.Activity.performStart(Activity.java:6253)
                      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2379)
                      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476) 
                      at android.app.ActivityThread.-wrap11(ActivityThread.java) 
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344) 
                      at android.os.Handler.dispatchMessage(Handler.java:102) 
                      at android.os.Looper.loop(Looper.java:148) 
                      at android.app.ActivityThread.main(ActivityThread.java:5417) 
                      at java.lang.reflect.Method.invoke(Native Method) 
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 

Thank you very much for your help, I am learning a lot.

    
asked by Natlum 14.12.2016 в 12:27
source

3 answers

1

The error apparently is because the internet connection tries this

try {
    URL url = new URL("https://s-media-cache-ak0.pinimg.com/236x/22/c8/9e/22c89e308d734b5daa9f383419b1bdc5.jpg");
    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
    connection.setDoInput(true);
    connection.connect();
    InputStream input = connection.getInputStream();
    Bitmap myBitmap = BitmapFactory.decodeStream(input);
    return myBitMap;
} catch (IOException e) {
    // Log exception
    return null;
}

EDIT

As commented @ Error404, this task should be called from an asynchronous task, since you are trying to execute an operation request from the internet in the main thread, adding to this idea you could try something like this

private class GetImageToURL extends AsyncTask < String, Void, Bitmap > {

    @Override
    protected Bitmap doInBackground(String... params) {
        try {
            URL url = new URL(params[0]);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setDoInput(true);
            connection.connect();
            InputStream input = connection.getInputStream();
            Bitmap myBitmap = BitmapFactory.decodeStream(input);
            return myBitmap;
        } catch (IOException e) {
            // Log exception
            return null;
        }
    }

    @Override
    protected void onPostExecute(Bitmap myBitMap) {
        logo.setImageBitmap(myBitMap);
    }
}

And you call her

new GetImageToURL().execute("https://s-media-cache-ak0.pinimg.com/236x/22/c8/9e/22c89e308d734b5daa9f383419b1bdc5.jpg");

EDIT 2

public class FragmentInicio extends Fragment {

    private static URL imgurl;
    public ImageView logo;
    public FragmentInicio() {}

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_inicio, container, false);
        logo = (ImageView) v.findViewById(R.id.imageEccaInicio);
        new GetImageToURL().execute("https://s-media-cache-ak0.pinimg.com/236x/22/c8/9e/22c89e308d734b5daa9f383419b1bdc5.jpg");
        return v;
    }

    private class GetImageToURL extends AsyncTask < String, Void, Bitmap > {

        @Override
        protected Bitmap doInBackground(String...params) {
            try {
                URL url = new URL(params[0]);
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                connection.setDoInput(true);
                connection.connect();
                InputStream input = connection.getInputStream();
                Bitmap myBitmap = BitmapFactory.decodeStream(input);
                return myBitmap;
            } catch (IOException e) {
                // Log exception
                return null;
            }
        }

        @Override
        protected void onPostExecute(Bitmap myBitMap) {
            logo.setImageBitmap(myBitMap);
        }
    }
}
    
answered by 14.12.2016 / 12:35
source
1

As the documentation says, if you are using a version equal to or greater than Honeycomb , this error occurs because you are trying to execute the network operation on the main thread.

  

The exception that is thrown when an application attempts to perform a networking operation on its main thread.   This is only thrown for applications targeting the Honeycomb SDK or higher.

Therefore, what you could do would be to include your code in the doInBackground method of a AsyncTask , which is executed as an asynchronous task.

    
answered by 14.12.2016 в 12:35
1

The error NetworkOnMainThreadException :

  

Caused by: android.os.NetworkOnMainThreadException

indicates that operations are being performed on the main thread, which is incorrect.

To avoid this you can use runOnUiThread ( ) , Asynctask or Handler.post () .

example runOnUiThread() :

    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            try {  
               proceso(); //Realizar aquí tu proceso!                    

            } catch (Exception e) {
                Log.e("Error", "Exception: " + e.getMessage());
            }
        }
    });

example to use in your code:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.fragment_inicio, container, false);
    ImageView logo = (ImageView) v.findViewById(R.id.imageEccaInicio);

            runOnUiThread(new Runnable() {
            @Override
            public void run() {
                try {  

                imgurl = new URL("https://s-media-cache-ak0.pinimg.com/236x/22/c8/9e/22c89e308d734b5daa9f383419b1bdc5.jpg");
                Bitmap mIcon_val = BitmapFactory.decodeStream(imgurl.openConnection().getInputStream());
               logo.setImageBitmap(mIcon_val);


               logo.setOnClickListener(new View.OnClickListener(){
               @Override
               public void onClick(View view){
               //Toast.makeText(view.getContext(), "Se ha tocado la imagen", Toast.LENGTH_LONG).show();
              //Llama al método openDrawer de la actividad principal para abrir el menú lateral.
              ((MainActivity)getActivity()).openDrawer();
                }
              });


                } catch (Exception e) {
                    Log.e("Error", "Exception: " + e.getMessage());
                } catch (MalformedURLException e) {
                   e.printStackTrace();
                }catch (IOException e) {
                  e.printStackTrace();
               }
    }
});


    return v;
}

You have a similar question in SO:

Error android.os.NetworkOnMainThreadException to use Android HttpURLConnection

    
answered by 14.12.2016 в 17:36