Question

I'm developing a shoutcast app (stream quality issues with the default MediaPlayer aside) which uses a listFragment to store the song info as the app is active.

As of right now I have a button on that fragment, which I've added an onClickListener to perform an HTTP Get Request through AysncTask. This is working perfectly. However I obviously don't want to waste the extra space including a button to refresh the list. So I've been trying to implement a timer which can execute the update function for the listFragment no matter which fragment the user is currently viewing.

*The update function does check against duplicates at the top of the list, so I'm not worried about organizing the data.

*As of right now the first fragment which opens has buttons to control a MediaPlayer object, the second is the listFragment.

These are my java files. I'm fairly new to android development so examples of whatever solution would be awesome.

MainActivity.java

import java.io.IOException;
import java.util.Locale;

import android.annotation.SuppressLint;
import android.app.ActionBar;
import android.app.Application;
import android.app.FragmentTransaction;
//import android.app.ListFragment;
import android.os.Bundle;
import android.os.PowerManager;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.ListFragment;
import android.support.v4.app.NavUtils;
import android.support.v4.view.ViewPager;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import android.app.Activity;
import android.content.Context;
import android.content.res.Configuration;
import android.media.AudioManager;
import android.media.AudioManager.OnAudioFocusChangeListener;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnInfoListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.net.Uri;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiManager.WifiLock;
import android.util.Log;
import android.widget.Button;

public class MainActivity extends FragmentActivity implements ActionBar.TabListener {

    /**
     * The {@link android.support.v4.view.PagerAdapter} that will provide
     * fragments for each of the sections. We use a
     * {@link android.support.v4.app.FragmentPagerAdapter} derivative, which
     * will keep every loaded fragment in memory. If this becomes too memory
     * intensive, it may be best to switch to a
     * {@link android.support.v4.app.FragmentStatePagerAdapter}.
     */
    SectionsPagerAdapter mSectionsPagerAdapter;

    /**
     * The {@link ViewPager} that will host the section contents.
     */
    ViewPager mViewPager;
    private MediaPlayer mp;
    int MediaState = 0; //idle

    @SuppressLint("ShowToast")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // Set up the action bar.
        final ActionBar actionBar = getActionBar();
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

        // Create the adapter that will return a fragment for each of the three
        // primary sections of the app.
        mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());

        // Set up the ViewPager with the sections adapter.
        mViewPager = (ViewPager) findViewById(R.id.pager);
        mViewPager.setAdapter(mSectionsPagerAdapter);

        // When swiping between different sections, select the corresponding
        // tab. We can also use ActionBar.Tab#select() to do this if we have
        // a reference to the Tab.
        mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
            @Override
            public void onPageSelected(int position) {
                actionBar.setSelectedNavigationItem(position);
            }
        });

        // For each of the sections in the app, add a tab to the action bar.
        for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
            // Create a tab with text corresponding to the page title defined by
            // the adapter. Also specify this Activity object, which implements
            // the TabListener interface, as the callback (listener) for when
            // this tab is selected.
            actionBar.addTab(
                    actionBar.newTab()
                            .setText(mSectionsPagerAdapter.getPageTitle(i))
                            .setTabListener(this));
        }

        Toast setup = Toast.makeText(getApplicationContext(), "Setting Up", Toast.LENGTH_SHORT);
        setup.show();
        //Audio manager
        if(mp==null) //prevent creation of new media player for new instances of the views
        {
            mp = new MediaPlayer();
            mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
            try{
                mp.setAudioSessionId(0);
                mp.setDataSource("http://130.191.35.35:8000");
                mp.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
                mp.setOnPreparedListener(new OnPreparedListener()
                {
                    @Override
                    public void onPrepared(MediaPlayer arg0) {
                        // TODO Auto-generated method stub
                        //playStream(mViewPager);
                        //mp.start();
                        MediaState = 2; //prepared
                        Toast t = Toast.makeText(getApplicationContext(), "Ready to Go", Toast.LENGTH_SHORT);
                        t.show();
                    }
                });
                //on info listener not catching any of the info through logcat for live stream skipping audio is due to buffer underruns
                //Should fix by using a stream proxy instead...not sure how to set one up
                mp.setOnInfoListener(new OnInfoListener() {
                    @Override
                    public boolean onInfo(MediaPlayer mp, int what, int extra) {
                        if (what == MediaPlayer.MEDIA_INFO_BUFFERING_START) {
                            Toast t = Toast.makeText(getApplicationContext(), "Buffering", Toast.LENGTH_SHORT);
                            t.show();
                        } else if (what == MediaPlayer.MEDIA_INFO_BUFFERING_END) {
                            Toast t = Toast.makeText(getApplicationContext(), "Buffering Stopped", Toast.LENGTH_SHORT);
                            t.show();
                        } else if (what == 703)
                        {
                            Toast t = Toast.makeText(getApplicationContext(), "Problem!", Toast.LENGTH_SHORT);
                            t.show();
                        }
                        return false;
                    }
                });

                MediaState = 1; //initialized // or stopped
                mp.prepareAsync();
                MediaState = 6; //MediaPlayer is preparing pick a state that isn't used so nothing works until its prepared
            }
            catch(IOException ex)
            {
                Toast t = Toast.makeText(getApplicationContext(), "Problem", Toast.LENGTH_SHORT);
                t.show();
            }
        }
    }

    @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 void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
        // When the given tab is selected, switch to the corresponding page in
        // the ViewPager.
        mViewPager.setCurrentItem(tab.getPosition());
    }

    @Override
    public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
    }

    @Override
    public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
    }

    /**
     * A {@link FragmentPagerAdapter} that returns a fragment corresponding to
     * one of the sections/tabs/pages.
     */
    public class SectionsPagerAdapter extends FragmentPagerAdapter {

        public SectionsPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int position) {
            // getItem is called to instantiate the fragment for the given page.
            // Return a DummySectionFragment (defined as a static inner class
            // below) with the page number as its lone argument.
            Fragment fragment;
            if(position==0)
            {
                //returns the main page
                fragment = new DummySectionFragment();
                Bundle args = new Bundle();
                args.putInt(DummySectionFragment.ARG_SECTION_NUMBER, position + 1);
                fragment.setArguments(args);
            }
            else
            {  //returns the listFragment
                    fragment = new SecondSectionFragment();
                    Bundle args = new Bundle();
                    fragment.setArguments(args);
            }
            return fragment;
        }

        @Override
        public int getCount() {
            // Show 3 total pages.
            // Show 2 total pages
            return 2;
        }

        @Override
        public CharSequence getPageTitle(int position) {
            Locale l = Locale.getDefault();
            switch (position) {
                case 0:
                    return getString(R.string.title_section1).toUpperCase(l);
                case 1:
                    return getString(R.string.title_section2).toUpperCase(l);
                case 2:
                    return getString(R.string.title_section3).toUpperCase(l);
            }
            return null;
        }
    }

    /**
     * The main screen's fragment
     */
    public static class DummySectionFragment extends Fragment{
        /**
         * The fragment argument representing the section number for this
         * fragment.
         */
        public static final String ARG_SECTION_NUMBER = "section_number";

        public DummySectionFragment() {
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            View rootView = inflater.inflate(R.layout.fragment_main_dummy, container, false);
            return rootView;
        }
    }

    public void playStream(View view) {
        if(!mp.isPlaying())
        {
            if(MediaState==2)
            {
                mp.start();
                Toast t = Toast.makeText(getApplicationContext(), "Play", Toast.LENGTH_SHORT);
                t.show();
                MediaState=3; // Media is now in started state
            }
            if(MediaState==1)
            {
                try
                {
                    mp.prepare();
                    MediaState = 2; // Media is now prepared
                    mp.start();
                    Toast t = Toast.makeText(getApplicationContext(), "Play", Toast.LENGTH_SHORT);
                    t.show();
                    MediaState = 3; // Media is now in playing or started state
                }
                catch(IOException ex)
                {

                }
            }
        }
    }
    public void pauseStream(View view)
    {
        if(mp.isPlaying())
        {
            mp.pause();
            Toast t = Toast.makeText(getApplicationContext(), "Pause", Toast.LENGTH_SHORT);
            t.show();
            MediaState = 2; // Media is now in paused state
        }
    }
    public void stopStream(View view)
    {
        mp.stop();
        Toast t = Toast.makeText(getApplicationContext(), "Stop", Toast.LENGTH_SHORT);
        t.show();
        MediaState = 1;
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        //prevent odd echoing for media player when screen rotates something to do with the activity being destroyed 
    }
}

SecondSectionFragment.java

import java.io.IOException;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

import android.app.Activity;
import android.content.Context;
import android.net.ParseException;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Looper;
import android.support.v4.app.ListFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;

public class SecondSectionFragment extends ListFragment {
    /**
     * The fragment argument representing the section number for this
     * fragment.
     */
    public static final String ARG_SECTION_NUMBER = "section_number";

    public SecondSectionFragment() {

    }
    String[] values = new String[] {"Welcome!"};
    ArrayAdapter<String> adapter;
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.second_main_dummy, container, false);
        Button refreshButton = (Button)rootView.findViewById(R.id.addBtn);
        refreshButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                findItem();
            }
        });
            adapter = new ArrayAdapter<String>(getActivity(),
                android.R.layout.simple_list_item_1, values);
            setListAdapter(adapter);
        setupTimer();
        return rootView;
    }
    @Override
    public void onListItemClick(ListView l, View v, int position, long id)
    {
        String text = adapter.getItem(position);
        customToast(text);
    }
    public void customToast(String text)
    {
        Toast t = Toast.makeText(this.getActivity().getApplicationContext(), text, Toast.LENGTH_SHORT);
        t.show();
    }

    public void addItem(String[] texts)
    {
        for(int t=0;t<texts.length;t++)
        {
            addItem(texts[t]);
        }
    }
    public void addItem(String text)
    {
        String[] prev = new String[values.length];
        prev = values.clone();
        values = new String[prev.length+1];
        values[0]=text;
        for(int i=1;i<values.length;i++)
        {
            values[i]=prev[i-1];
        }
        adapter = new ArrayAdapter<String>(getActivity(),
                android.R.layout.simple_list_item_1, values);
            setListAdapter(adapter);
        adapter.notifyDataSetChanged();
    }

    class HTTPRequest extends AsyncTask<Void, Void, String> {
        @Override
        protected String doInBackground(Void... params) {
            try {

                HttpGet httpRequest = new HttpGet( "http://_____/___.php?q="+Math.random());
                HttpClient httpclient = new DefaultHttpClient();
                HttpResponse response = httpclient.execute(httpRequest);
                int code = response.getStatusLine().getStatusCode();
                if(code!=404)
                {
                    String responseBody = EntityUtils.toString(response.getEntity());
                    responseBody = responseBody.replace("</body></html>","");
                    return responseBody;
                }
                return "404 Error";
            } catch (Exception e) {
                return "Exception";
            }

        }

        protected void onPostExecute(String text) {
            if(!text.contains(adapter.getItem(0)))
            {
                addItem(text);
            }
            else
            {
                customToast(adapter.getItem(0));
            }
        }

     }
    public void findItem()
    {
        new HTTPRequest().execute();
    }
    public void setupTimer()
    {
       //Not sure if this would be the correct place to start up a timer
    }
}
Was it helpful?

Solution

if this still valid. I do have such solution for live update.

private final Handler mHandler = new Handler();
private final Runnable mRunnable = new Runnable() {
    @Override
    public void run() {
        mHandler.removeCallbacks(mRunnable);
        //  DO here something like your  findItem()
        mHandler.postDelayed(mRunnable, TIMEOUT);
    }
};

 public void setupTimer() {
    if (mHandler != null) {
        mHandler.removeCallbacks(mRunnable);
        mHandler.postDelayed(mRunnable, TIMEOUT);
    }
}

call your setupTimer() from onResume() in your onPause() add

    if (mHandler != null) {
        mHandler.removeCallbacks(mRunnable);
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top