0

I'm working on a big program for Android and I'm trying to get the currency converter part of the program to work. For full disclosure: I found it from http://firstamong.com/building-android-currency-converter/, and it's a tutorial on how to build a real-time currency converter. I'll post the code in question followed by the logcat. The error that occurs is when I try to convert from one currency to another, the application says it was forced to stop. However, the "Invalid" portion works (the case where both currency fields are the same.) Any help would truly be appreciated:

Code:

public class currency_converter extends Activity {

public int to;
public int from;
public String [] val;
public String s;
public Handler handler;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_currency_converter);
    Spinner s1 = (Spinner) findViewById(R.id.spinner1);
    Spinner s2 = (Spinner) findViewById(R.id.spinner2);
    ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
            this, R.array.name, android.R.layout.simple_spinner_item);
    adapter.setDropDownViewResource(android.R.layout.select_dialog_singlechoice);
    val  = getResources().getStringArray(R.array.value);
    s1.setAdapter(adapter);
    s2.setAdapter(adapter);
    s1.setOnItemSelectedListener(new spinOne(1));
    s2.setOnItemSelectedListener(new spinOne(2));
    Button b = (Button) findViewById(R.id.button1);
    b.setOnClickListener(new OnClickListener(){
        public void onClick(View v) {
            TextView t = (TextView) findViewById(R.id.textView4);
            if(from == to)
            {
                Toast.makeText(getApplicationContext(), "Invalid", 4000).show();
            }
            else
            {
                try {
                    s = getJson("http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.xchange%20where%20pair%20in%20(%22"+val[from]+val[to]+"%22)&format=json&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=");
                    JSONObject jObj;
                    jObj = new JSONObject(s);
                    String exResult = jObj.getJSONObject("query").getJSONObject("results").getJSONObject("rate").getString("Rate");
                    t.setText(exResult);
                } catch (JSONException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                catch (ClientProtocolException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    });
}
public String getJson(String url)throws ClientProtocolException, IOException {

    StringBuilder build = new StringBuilder();
    HttpClient client = new DefaultHttpClient();
    HttpGet httpGet = new HttpGet(url);
    HttpResponse response = client.execute(httpGet);
    HttpEntity entity = response.getEntity();
    InputStream content = entity.getContent();
    BufferedReader reader = new BufferedReader(new InputStreamReader(content));
    String con;
    while ((con = reader.readLine()) != null) {
        build.append(con);
    }
    return build.toString();
}
private class spinOne implements OnItemSelectedListener
{
    int ide;
    spinOne(int i)
    {
        ide =i;
    }
    public void onItemSelected(AdapterView<?> parent, View view,
                               int index, long id) {
        if(ide == 1)
            from = index;
        else if(ide == 2)
            to = index;

    }

    public void onNothingSelected(AdapterView<?> arg0) {
        // TODO Auto-generated method stub
    }
class GetResponseData extends AsyncTask<String, String, String> {
        private ProgressDialog dialog;
        private ArrayList<String> titleList;
        private TextView textView;

        public GetResponseData(TextView textView) {
            this.textView = textView;
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            dialog = ProgressDialog.show(currency_converter.this, "", "Loading",
                    false);
        }

        @Override
        protected String doInBackground(String... params) {

            try {
                String s = getJson("http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.xchange%20where%20pair%20in%20(%22" + val[from] + val[to] + "%22)&format=json&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=");
                JSONObject jObj;
                jObj = new JSONObject(s);
                String exResult = jObj.getJSONObject("query").getJSONObject("results").getJSONObject("rate").getString("Rate");
                return exResult;
            } catch (JSONException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                return null;
            } catch (ClientProtocolException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                return null;
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                return null;
            }
        }

        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);
            if (dialog != null)
                dialog.dismiss();
            if (result != null) {
                textView.setText(result);
            }
        }

    }
}

}

Logcat:

10-30 00:59:48.164  20591-20591/com.example.travelapplication E/AndroidRuntime﹕ FATAL EXCEPTION: main
android.os.NetworkOnMainThreadException
        at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1128)
        at java.net.InetAddress.lookupHostByName(InetAddress.java:385)
        at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
        at java.net.InetAddress.getAllByName(InetAddress.java:214)
        at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:137)
        at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
        at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
        at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:365)
        at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:587)
        at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:511)
        at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:489)
        at com.example.travelapplication.currency_converter.getJson(currency_converter.java:93)
        at com.example.travelapplication.currency_converter$1.onClick(currency_converter.java:68)
        at android.view.View.performClick(View.java:4222)
        at android.view.View$PerformClick.run(View.java:17620)
        at android.os.Handler.handleCallback(Handler.java:800)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:194)
        at android.app.ActivityThread.main(ActivityThread.java:5391)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:525)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
        at dalvik.system.NativeStart.main(Native Method)
user2827137
  • 51
  • 2
  • 8
  • Does this answer your question? [How can I fix 'android.os.NetworkOnMainThreadException'?](https://stackoverflow.com/questions/6343166/how-can-i-fix-android-os-networkonmainthreadexception) – Joachim Sauer Nov 09 '21 at 08:52

4 Answers4

1

Try this,,

Your performing a networking operation on its main thread. That why your getting NetworkOnMainThreadException

b.setOnClickListener(new OnClickListener(){
        public void onClick(View v) {
            TextView t = (TextView) findViewById(R.id.textView4);
            if(from == to)
            {
                Toast.makeText(getApplicationContext(), "Invalid", 4000).show();
            }
            else
            {
                GetResponseData abcd = GetResponseData(t);
                abcd.execute();
            }
        }
    });
Hariharan
  • 28,756
  • 7
  • 51
  • 55
1

It looks like you have strict mode on in your android manifest. Strict mode will complain when you are doing network calls on you main thread. You can just disable strict mode or a better approach is to put your network call into an async task. The network call in question is

HttpResponse response = client.execute(httpGet);

inside public String getJson(String url)

The async task you need is already there you just need to use it

Change this else statement

else
        {
            try {
                s = getJson("http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.xchange%20where%20pair%20in%20(%22"+val[from]+val[to]+"%22)&format=json&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=");
                JSONObject jObj;
                jObj = new JSONObject(s);
                String exResult = jObj.getJSONObject("query").getJSONObject("results").getJSONObject("rate").getString("Rate");
                t.setText(exResult);
            } catch (JSONException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            catch (ClientProtocolException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

To this

else {
    new GetResponseData().execute("http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.xchange%20where%20pair%20in%20(%22"+val[from]+val[to]+"%22)&format=json&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=");
}
Cody Gray
  • 230,875
  • 49
  • 477
  • 553
doubleA
  • 2,416
  • 21
  • 45
  • I tried this but I'm getting a "Cannot resolve symbol 'GetResponseData'" error. Is there any reason why it's not finding the GetResponseData class that I can't see? – user2827137 Oct 30 '14 at 14:00
  • After looking at the code that you posted i noticed that `GetResponseData` is an inner class of spinOne. Trying to access it from `currency_converter` will fail. You either need to move it to `currency_converter` or into its own .java file. Or access it with `new spinOne.GetResponseData().execute("blah.blah.com");` I would move it to be an inner class of `currency_converter` that way you do not have classes nested so deep. Right now you have an async task class inside an inner private class inside another class. – doubleA Oct 30 '14 at 16:56
1

You are getting:

NetworkOnMainThreadException

Issue is that you are calling your function getJson() in your Activity.

Use AsyncTask:

public class ProcessTask extends AsyncTask<Void, Integer, String>{

    public ProcessTask() {
        // TODO Auto-generated constructor stub

    }

    @Override
    protected void onPreExecute() {
        // TODO Auto-generated method stub
        super.onPreExecute();
    }

    @Override
    protected String doInBackground(Void... params) {
        // TODO Auto-generated method stub

        //your code of parsing
        StringBuilder build = new StringBuilder();
        HttpClient client = new DefaultHttpClient();
        HttpGet httpGet = new HttpGet(url);  //your yahooapi url goes here
        HttpResponse response = client.execute(httpGet);
        HttpEntity entity = response.getEntity();
        InputStream content = entity.getContent();
        BufferedReader reader = new BufferedReader(new InputStreamReader(content));
        String con;
        while ((con = reader.readLine()) != null) {
            build.append(con);
        }
        return build.toString();
    }

    @Override
    protected void onPostExecute(String result) {
        // TODO Auto-generated method stub

        super.onPostExecute(result);
    }
}
MysticMagicϡ
  • 28,305
  • 16
  • 71
  • 119
  • Just to clear up this would replace my GetResponse data class or be added additionally? Just been very confused – user2827137 Oct 30 '14 at 13:30
0

It will help use this :

public class CurrencyConverter extends Fragment {
    public CurrencyConverter() {
    }
    TextView t;
    public int to;
    public int from;
    public String[] val;
    public String s;
    String exResult;
    public Handler handler;


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {


         View rootView = inflater.inflate(R.layout.currency_converter, container, false);
        t= (TextView) rootView.findViewById(R.id.textView4);
        Spinner s1 = (Spinner) rootView.findViewById(R.id.spinner1);
        Spinner s2 = (Spinner) rootView.findViewById(R.id.spinner2);
        ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
                this.getActivity(), R.array.name, android.R.layout.simple_spinner_item);
        adapter.setDropDownViewResource(android.R.layout.select_dialog_singlechoice);
        val = getResources().getStringArray(R.array.value);
        s1.setAdapter(adapter);
        s2.setAdapter(adapter);
        s1.setOnItemSelectedListener(new spinOne(1));
        s2.setOnItemSelectedListener(new spinOne(2));

        Button b = (Button) rootView.findViewById(R.id.button1);
        b.setOnClickListener(new View.OnClickListener() {
            public void onClick(View View) {



                if (from == to) {
                    Toast.makeText(getActivity().getApplicationContext(), "Invalid", 4000).show();
                } else {
                    new calculate().execute();

                }
            }

        });
        return rootView;
    }

    public class calculate extends AsyncTask<String, String, String> {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();

        }

        @Override
        protected String doInBackground(String... args) {

            try {

                s = getJson("http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.xchange%20where%20pair%20in%20(%22"+val[from]+val[to]+"%22)&format=json&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=");
                JSONObject jObj;
                jObj = new JSONObject(s);
                 exResult = jObj.getJSONObject("query").getJSONObject("results").getJSONObject("rate").getString("Rate");


            } catch (JSONException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (ClientProtocolException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return exResult;

        }
        @Override
        protected void onPostExecute(String exResult) {

           t.setText(exResult);
        }



       }

    public String getJson(String url)throws  IOException {

        StringBuilder build = new StringBuilder();
        HttpClient client = new DefaultHttpClient();
        HttpGet httpGet = new HttpGet(url);
        HttpResponse response = client.execute(httpGet);
        HttpEntity entity = response.getEntity();
        InputStream content = entity.getContent();
        BufferedReader reader = new BufferedReader(new InputStreamReader(content));
        String con;
        while ((con = reader.readLine()) != null) {
            build.append(con);
        }
        return build.toString();
    }

        public class spinOne implements AdapterView.OnItemSelectedListener
        {
            int ide;
            spinOne(int i)
            {
                ide =i;
            }
            public void onItemSelected(AdapterView<?> parent, View view,
                                       int index, long id) {
                if(ide == 1)
                    from = index;
                else if(ide == 2)
                    to = index;

            }

            public void onNothingSelected(AdapterView<?> arg0) {
                // TODO Auto-generated method stub
            }

    }
}
Neeraj
  • 89
  • 1
  • 10