0

I'm using AsuncTask for getting JSON from web service. From JSON I get "title" and "fulltext". "title" is simple text, but "fulltext" is HTML text. In this HTML I have some text and URLs with images. I want to show whole HTML in TextView.

My code:

    TextView tvArticleTitle = (TextView) findViewById(R.id.tvArticleTitle);
    TextView tvArticleText = (TextView) findViewById(R.id.tvArticleText);

public class GetArticleTask extends AsyncTask<String, Void, Boolean> {

        private String title;
        private String text;
        private ProgressDialog dialog;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();

            dialog = new ProgressDialog(context);
            dialog.setMessage("Please wait!");
            dialog.setCancelable(false);
            dialog.show();
        }

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

            try {
                DefaultHttpClient httpClient = new DefaultHttpClient();
                HttpPost httpPost = new HttpPost(Variables.URL_ARTICLE);
                httpPost.setEntity(new UrlEncodedFormEntity(pair));

                HttpResponse httpResponse = httpClient.execute(httpPost);
                HttpEntity httpEntity = httpResponse.getEntity();
                String data = EntityUtils.toString(httpEntity);

                int status = httpResponse.getStatusLine().getStatusCode();

                if (status == HttpStatus.SC_OK) {

                    JSONObject jRealObject = new JSONObject(data);

                    title = jRealObject.getString("title").toString();
                    text = jRealObject.getString("fulltext").toString();

                    return true;
                }
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            } catch (ClientProtocolException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (JSONException e) {
                e.printStackTrace();
            }
            return false;
        }

        @Override
        protected void onPostExecute(Boolean result) {
            super.onPostExecute(result);

            if (result == false) {
                Toast.makeText(context, Variables.ERROR_MESSAGE, Toast.LENGTH_SHORT).show();
            } else {

                tvArticleTitle.setText(title);
                tvArticleText.setText(Html.fromHtml(text, new ImageGetter() {

                    @Override
                    public Drawable getDrawable(String source) {

                        Drawable drawable = null;
                        URL sourceURL;

                        try {
                            sourceURL = new URL(source);
                            URLConnection urlConnection = sourceURL.openConnection();
                            urlConnection.connect();
                            InputStream inputStream = urlConnection.getInputStream();
                            BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
                            Bitmap bm = BitmapFactory.decodeStream(bufferedInputStream);

                            // convert Bitmap to Drawable
                            drawable = new BitmapDrawable(getResources(), bm);

                            drawable.setBounds(0, 0, bm.getWidth(), bm.getHeight());
                        } catch (MalformedURLException e) {
                            e.printStackTrace();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }

                        return drawable;
                    }

                }, null));

                if(dialog.isShowing()) {
                    dialog.dismiss();
                }
            }
        }
    }
}

It gives me error: android.os.NetworkOnMainThreadException. I know that I need to make this on AsyncTask again, but I don't know how to split code.

KiKo
  • 1,668
  • 7
  • 27
  • 56
  • you should use image span to show image(before that you need to download image too) – MHP Sep 30 '14 at 13:10
  • I think its more easy to load that image using picasa image library since it handles almost all thing that that you manually need to worry abou..i suggest you go for picasa image loader library – George Thomas Sep 30 '14 at 13:12
  • @GeorgeThomas yeah. In text is whole html, from there I want to show all images, also and the text. – KiKo Sep 30 '14 at 13:15
  • Check out this http://stackoverflow.com/questions/7424512/android-html-imagegetter-as-asynctask/7442725#7442725 – George Thomas Sep 30 '14 at 13:31

1 Answers1

1

If your json is somewhat like this:

{ 
  "text": "some text",
  "html1": "Hi, check out my fb profile picture at <img src = 'http:\/\/abc.com/image1.png'\/> ",
  "html2": "Hi, check out my whatsapp profile picture at <img src = 'http:\/\/abc.com\/image1.png'\/> ",
   .
   .
   .
}
Then :
public class MainActivity extends Activity implements ImageGetter {
    private final static String TAG = "MainActivity";
    private TextView mTv;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        String source = <your source from json here>;

        Spanned spanned = Html.fromHtml(source, this, null);
        mTv = (TextView) findViewById(R.id.text);
        mTv.setText(spanned);
    }

    @Override
    public Drawable getDrawable(String source) {
        LevelListDrawable d = new LevelListDrawable();
        Drawable empty = getResources().getDrawable(R.drawable.ic_launcher);
        d.addLevel(0, 0, empty);
        d.setBounds(0, 0, empty.getIntrinsicWidth(), empty.getIntrinsicHeight());

        new LoadImage().execute(source, d);

        return d;
    }

    class LoadImage extends AsyncTask<Object, Void, Bitmap> {

        private LevelListDrawable mDrawable;

        @Override
        protected Bitmap doInBackground(Object... params) {
            String source = (String) params[0];
            mDrawable = (LevelListDrawable) params[1];
            Log.d(TAG, "doInBackground " + source);
            try {
                InputStream is = new URL(source).openStream();
                return BitmapFactory.decodeStream(is);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(Bitmap bitmap) {
            Log.d(TAG, "onPostExecute drawable " + mDrawable);
            Log.d(TAG, "onPostExecute bitmap " + bitmap);
            if (bitmap != null) {
                BitmapDrawable d = new BitmapDrawable(bitmap);
                mDrawable.addLevel(1, 1, d);
                mDrawable.setBounds(0, 0, bitmap.getWidth(), bitmap.getHeight());
                mDrawable.setLevel(1);
                // i don't know yet a better way to refresh TextView
                // mTv.invalidate() doesn't work as expected
                CharSequence t = mTv.getText();
                mTv.setText(t);
            }
        }
    }
}