0

I got a List View in my application in which I am displaying the data through Base Adapter. Their is two problems I am facing and referred few posts like but all suggested same procedure i followed.

Issues are

  1. I am trying to download the image from the URL given from JSON. everything is working smoothly but the image never get set to Image View.

  2. I bound Text to Speech on click event of button in Base Adapter class and freed it in onDestroy of of the java class but still I get a error in Log for it stating this and application crashes. Here in log erroe line no 55 is the first statement of onDestroy.

Here is my code

Java File

public class DisplayWeather extends Activity {

    String city, date, maximumTemp, minimumTemp, description, weatherImageUrl;
    ListView weatherList;
    List <Bean> bean;
    Bitmap myBitmap, newBitmap;
    CustomBaseAdapter baseAdapter;

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

        bean = new ArrayList<Bean>();
        weatherList = (ListView) findViewById(R.id.lvWeather);

        for(int i=0; i<WeatherHome.arrayList.size(); i++)
        {
            .
                    .

        }


        weatherList.setAdapter(new CustomBaseAdapter(this, bean));
    }


    @Override
    protected void onDestroy() {
        // TODO Auto-generated method stub
        if (baseAdapter.tts != null)
        {
            baseAdapter.tts.stop();
            baseAdapter.tts.shutdown();
        }
        super.onDestroy();
    }

Base Adapter class

public class CustomBaseAdapter extends BaseAdapter implements OnInitListener {
    Context context;
    List<Bean> bean;
    ImageView weatherImage;
    TextView weatherDate, weatherCity, weatherMinimum, weatherMaximum, weatherDescription;
    Button buttonSpeak;
    String citySpeak, dateSpeak, descriptionSpeak, maximumSpeak, minimumSpeak, weatherURL;
    TextToSpeech tts;
    Bean userBean;
    Bitmap myBitmap;

    public CustomBaseAdapter(Context context, List<Bean> bean) {
        // TODO Auto-generated constructor stub
        this.context = context;
        this.bean = bean;
        tts = new TextToSpeech(context, null);
    }

    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return bean.size();
    }

    @Override
    public Object getItem(int position) {
        // TODO Auto-generated method stub
        return bean.get(position);
    }

    @Override
    public long getItemId(int position) {
        // TODO Auto-generated method stub
        return bean.indexOf(getItem(position));
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // TODO Auto-generated method stub
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);

        if(convertView == null)
        {
            convertView = inflater.inflate(R.layout.custom_base_adapter, null);
            weatherImage = (ImageView) convertView.findViewById(R.id.displayImage);
convertView.findViewById(R.id.displayDate);
            buttonSpeak = (Button) convertView.findViewById(R.id.Speak);


        }

        weatherURL = userBean.getImageUrl();

        new ImageDownload().execute();

        Log.i("Executing Rest Line>>>", "Skippedddddd");
        buttonSpeak.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
            String cityName = weatherCity.getText().toString(); 
            String dateValue = weatherDate.getText().toString();
            String maximumValue = weatherMaximum.getText().toString();
            String minimumValue = weatherMinimum.getText().toString();
            String descriptionValue = weatherDescription.getText().toString();

            citySpeak = "Temprature for city "+cityName+"";
            dateSpeak = " on Date "+dateValue+"";
            maximumSpeak = "will be Maximum upto "+maximumValue+" degree ";
            minimumSpeak = " and Minimum upto"+minimumValue+" degree ";
            descriptionSpeak = "and The atmosphere seems to be "+descriptionValue+"";

            speakTempratureValues();
            }
        });

        return convertView;
    }

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

        protected Bitmap doInBackground(String... arg0){

            try{
                Log.e("src",weatherURL);
                URL url = new URL(weatherURL);
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                connection.setDoInput(true);
                connection.connect();
                InputStream input = connection.getInputStream();
                myBitmap = BitmapFactory.decodeStream(input);       
                Log.e("Bitmap","returned");
                return myBitmap;
            }
            catch(Exception e){
                e.printStackTrace();
                return null;
            }

        }

        protected void onPostExecute(Bitmap result){
             if(result!=null)
             {
                Log.i("OnPost>>>", ""+result);
                weatherImage.setImageBitmap(result);
             }

        }
    }

    protected void speakTempratureValues() {
        // TODO Auto-generated method stub
        tts.setSpeechRate(-4);
        tts.speak(citySpeak, TextToSpeech.QUEUE_FLUSH, null);
        tts.speak(dateSpeak, TextToSpeech.QUEUE_ADD, null);
        tts.speak(maximumSpeak, TextToSpeech.QUEUE_ADD, null);
        tts.speak(minimumSpeak, TextToSpeech.QUEUE_ADD, null);
        tts.speak(descriptionSpeak, TextToSpeech.QUEUE_ADD, null);
        tts.speak("Thank You", TextToSpeech.QUEUE_ADD, null);
    }


    @Override
    public void onInit(int status) {
        // TODO Auto-generated method stub
        if(status==TextToSpeech.SUCCESS){
            int result = tts.setLanguage(Locale.getDefault());

            if (result == TextToSpeech.LANG_MISSING_DATA
                    || result == TextToSpeech.LANG_NOT_SUPPORTED) {
                Log.e("TTS", "This Language is not supported");
            }
            else{

                speakTempratureValues();
            }
        }
        else{
            Log.e("TTS", "Initialization Failed");
        }
    }

}
SDroid
  • 33
  • 6
  • Welcome to StackOverflow. You'll have to reduce pretty much your code and focus actually in the problem, with that much code it's hard for prople to understand the real problem. – nKn Apr 17 '14 at 19:57
  • Thanks @nKn I hope its fine now. – SDroid Apr 17 '14 at 20:03
  • Trying setting the downloaded bitmap in the getView(..) method instead. How: Initialize a Bitmap variable and set the bitmap to it in the onPostExecute(..) method and then set the image. – Aashir Apr 17 '14 at 20:18
  • @JRowan I did that initially but that leads to [this](http://pastie.org/9088268) – SDroid Apr 17 '14 at 20:18
  • @Aashir Sorry brother didn't get your point. I guess I did the same way. – SDroid Apr 17 '14 at 20:21

2 Answers2

1

It looks like maybe you're returning your convertView in the getView method before your AsyncTask is finished downloading the image. Can you use a thread instead, and use the Thread join method so that your app waits for the image to be downloaded? For an AsyncTask you usually use a progress dialog until the task is finished, but I don't think you can do that inside of an adapter.

How about replacing this:

new ImageDownload().execute();

with this:

new Thread(new Runnable() {
public void run() {
  try{
            Log.e("src",weatherURL);
            URL url = new URL(weatherURL);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setDoInput(true);
            connection.connect();
            InputStream input = connection.getInputStream();
            myBitmap = BitmapFactory.decodeStream(input);       
            Log.e("Bitmap","returned");
            return myBitmap;
        }
        catch(Exception e){
            e.printStackTrace();
            return null;
        }}
}).join();

and then obviously get rid of the ImageDownload class. I'm just throwing this at you, didn't test it or anything. I think that should get you closer.

Lou Morda
  • 5,078
  • 2
  • 44
  • 49
  • You might be right. I tried using `if(new ImageDownload().getStatus()==AsyncTask.Status.FINISHED) { return convertView; } return null;` instead Thread but it didn't worked. – SDroid Apr 17 '14 at 21:06
  • yeah that's why I usually avoid AsyncTasks and just use Threads. AsyncTask's are like listening to your wife talk. You're usually doing something useful like playing video games or watching TV, and there's this background chatter going on, but you keep doing what you're doing anyways. And then when she's almost done, you stop what you're doing and listen to the last sentence so that you can pretend like you were listening the whole time... – Lou Morda Apr 17 '14 at 22:10
  • ok i just added new code to the original answer, give that a try. – Lou Morda Apr 17 '14 at 22:18
  • Nice example of AsyncTask. Anyways, I tried using Thread like you suggested but that too ends up with no change. – SDroid Apr 18 '14 at 07:54
0

What Louis suggested is the correct way. I am sure this will work. The reason why it's not working for you is not sure but try this way:

Runnable runnable = new Runnable() {

                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    try{
                        Log.e("src",weatherURL);
                        URL url = new URL(weatherURL);
                        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                        connection.setDoInput(true);
                        connection.connect();
                        InputStream input = connection.getInputStream();
                        myBitmap = BitmapFactory.decodeStream(input);       
                        Log.e("Bitmap","returned"+myBitmap);

                        if(myBitmap!=null)
                     {
                        Log.i("OnPost>>>", ""+myBitmap);
                        weatherImage.setImageBitmap(myBitmap);
                     }
                    }
                    catch(Exception e){
                        e.printStackTrace();

                    }

                }
            };

            Thread t = new Thread(runnable);
            t.start();
            try {
                t.join();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

Probably, the start method was missing for you and you might not have called it. I hope this work.

Saggy
  • 624
  • 8
  • 23
  • 1
    I would have accepted that as he showed me an other way to work but I guess the answer should be only that which solves your query or finally leads to it. So I accepted your answer :) – SDroid Apr 18 '14 at 10:08