Search code examples
javaandroidsdkbufferedreader

Android - InputStreamReader not working


I want to get a String from a website, and convert it to a Array. It is working in eclipse, but if I want to use it in an Android-App it wont work. I know, it must be a stupid mistake but I dont know where it is.

InternetHandler:

package de.blender4me.einkaufsliste;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.regex.Pattern;

public class internetHandler {

//Einkaufsplaner-API aufrufen
    public static String[] getList(){

        InputStream is = null;

        try
        {
          URL url = new URL("https://einkaufsplaner.blender4me.de/api.php?name=Username&pass=SuperSecretPass&addValue=&removeValue=");
          BufferedReader in = new BufferedReader(
          new InputStreamReader(url.openStream()));

          String Values = null;

          for(int i = 0; i < 4; ++i){
              Values = in.readLine();
          }
          in.close();

          String[] List = Values.split( Pattern.quote( ";" ) );
          return List;

        }
        catch ( Exception e ) {
          e.printStackTrace();
        }
        finally {
          if ( is != null )
            try { is.close(); } catch ( IOException e ) { }
        }
        String[] error = {"error"};
        return error;
    }
}

Main

package de.blender4me.einkaufsliste;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;


public class MainActivity extends Activity {

//Widgets
Button addItem;



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //listView
        populateListView();

        //register Widgets
        addItem =(Button) findViewById(R.id.addItem);

        addItem.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                openDialog();
            }
        });
    }

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();
    if (id == R.id.action_settings) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}

//Alert
public void openDialog(){
    AlertDialog.Builder alert = new AlertDialog.Builder(this);

    alert.setTitle("Zur Einkaufsliste hinzufügen");
    alert.setMessage(" ");

    // Set an EditText view to get user input 
    final EditText input = new EditText(this);
    alert.setView(input);

    alert.setPositiveButton("Bestätigen", new DialogInterface.OnClickListener() {
    public void onClick(DialogInterface dialog, int whichButton) {
      String value = input.getText().toString();
      // Do something with value!
      }
    });

    alert.setNegativeButton("Abbrechen", new DialogInterface.OnClickListener() {
      public void onClick(DialogInterface dialog, int whichButton) {
        // Canceled.
      }
    });

    alert.show();
}

//listView erstellen
private void populateListView() {
        // Liste auslesen
        String[] values = internetHandler.getList();

        //Liste konvertieren
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, 
                R.layout.listview_item, //Genutztes Layout
                values); //Genutzter Array

        //listView einstellen
        ListView list = (ListView) findViewById(R.id.listView);
        list.setAdapter(adapter);
    }
}

Manifest

<uses-sdk
    android:minSdkVersion="14"
    android:targetSdkVersion="19" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>


<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@android:style/Theme.Holo.Light.NoActionBar.Fullscreen"

>

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

It always returns the error-array, but idk why :C

logcat:

11-07 15:18:24.425: E/Trace(642): error opening trace file: No such file or directory (2) 11-07 15:18:24.925: W/System.err(642): android.os.NetworkOnMainThreadException 11-07 15:18:24.925: W/System.err(642): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1117) 11-07 15:18:24.935: W/System.err(642): at java.net.InetAddress.lookupHostByName(InetAddress.java:385) 11-07 15:18:24.935: W/System.err(642): at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236) 11-07 15:18:24.935: W/System.err(642): at java.net.InetAddress.getAllByName(InetAddress.java:214) 11-07 15:18:24.935: W/System.err(642): at libcore.net.http.HttpConnection.(HttpConnection.java:70) 11-07 15:18:24.935: W/System.err(642): at libcore.net.http.HttpConnection.(HttpConnection.java:50) 11-07 15:18:24.935: W/System.err(642): at libcore.net.http.HttpConnection$Address.connect(HttpConnection.java:341) 11-07 15:18:24.935: W/System.err(642): at libcore.net.http.HttpConnectionPool.get(HttpConnectionPool.java:87) 11-07 15:18:24.935: W/System.err(642): at libcore.net.http.HttpConnection.connect(HttpConnection.java:128) 11-07 15:18:24.935: W/System.err(642): at libcore.net.http.HttpEngine.openSocketConnection(HttpEngine.java:315) 11-07 15:18:24.945: W/System.err(642): at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.makeSslConnection(HttpsURLConnectionImpl.java:461) 11-07 15:18:24.945: W/System.err(642): at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnectionImpl.java:433) 11-07 15:18:24.945: W/System.err(642): at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:289) 11-07 15:18:24.945: W/System.err(642): at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:239) 11-07 15:18:24.945: W/System.err(642): at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:273) 11-07 15:18:24.945: W/System.err(642): at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:168) 11-07 15:18:24.945: W/System.err(642): at libcore.net.http.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:271) 11-07 15:18:24.955: W/System.err(642): at java.net.URL.openStream(URL.java:462) 11-07 15:18:24.955: W/System.err(642): at de.blender4me.einkaufsliste.internetHandler.getList(internetHandler.java:21) 11-07 15:18:24.955: W/System.err(642): at de.blender4me.einkaufsliste.MainActivity.populateListView(MainActivity.java:100) 11-07 15:18:24.955: W/System.err(642): at de.blender4me.einkaufsliste.MainActivity.onCreate(MainActivity.java:37) 11-07 15:18:24.955: W/System.err(642): at android.app.Activity.performCreate(Activity.java:5008) 11-07 15:18:24.955: W/System.err(642): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079) 11-07 15:18:24.955: W/System.err(642): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023) 11-07 15:18:24.965: W/System.err(642): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084) 11-07 15:18:24.965: W/System.err(642): at android.app.ActivityThread.access$600(ActivityThread.java:130) 11-07 15:18:24.965: W/System.err(642): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195) 11-07 15:18:24.965: W/System.err(642): at android.os.Handler.dispatchMessage(Handler.java:99) 11-07 15:18:24.965: W/System.err(642): at android.os.Looper.loop(Looper.java:137) 11-07 15:18:24.965: W/System.err(642): at android.app.ActivityThread.main(ActivityThread.java:4745) 11-07 15:18:24.965: W/System.err(642): at java.lang.reflect.Method.invokeNative(Native Method) 11-07 15:18:24.965: W/System.err(642): at java.lang.reflect.Method.invoke(Method.java:511) 11-07 15:18:24.975: W/System.err(642): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) 11-07 15:18:24.975: W/System.err(642): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 11-07 15:18:24.975: W/System.err(642): at dalvik.system.NativeStart.main(Native Method) 11-07 15:18:26.455: D/gralloc_goldfish(642): Emulator without GPU emulation detected.


Solution

  • Your problem is here (in the stacktrace) :

    android.os.NetworkOnMainThreadException

    You're making a request in the MainThread which is forbiden with Android to avoid heavy treatments on UI (making this will block the UI).

    Use an AsyncTask instead.

    An example of AsyncTask to start from something :

    private class LongOperation extends AsyncTask<Void, Void, String> {
    
        @Override
        protected String doInBackground(Void... params) {
            InternetHandler ih = new InternetHandler();
            String[] values = ih.getList();
        }
    
        @Override
        protected void onPostExecute(String result) {
            //Liste konvertieren
            ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, 
                R.layout.listview_item, //Genutztes Layout
                values); //Genutzter Array
    
            //listView einstellen
            ListView list = (ListView) findViewById(R.id.listView);
            list.setAdapter(adapter);
        }
    
        @Override
        protected void onPreExecute() {}
    
        @Override
        protected void onProgressUpdate(Void... values) {}
    }
    

    Call it with :

    LongOperation lo = new LongOperation();
    lo.execute();