Search code examples
javaandroidandroid-service-binding

Music Service stopped onPressing backbutton


I have a actionbaractivity with one fragment attached with it and one service class which is streaming music from url. below i paste some code for reference

TopTenFragment.java

public class ToptenFragment extends Fragment {

    private ListView TrackList;
    private CustomAdapter songadapter;
    private ArrayList<Song> songList;


    int currentduration;
    ArrayList<Integer> buttonposiotion = new ArrayList<Integer>();
    private int curBtnIndex = -1;
    // private boolean paused = false;
    private int lastpos;
    // service
    private MyService musicSrv;
    private Intent playIntent;
    // binding
    private boolean musicBound = false;
    // activity and playback pause flags
    private boolean paused = false, playbackPaused = false;

    int i = 0;
    int start = 0;
    String urlindex;
    public ImageView imageView;
    private ProgressBar bar;
    private WeakReference<Activity> mainActivityWeakRef;

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        System.out.println("onActivityCreated");
        mainActivityWeakRef = new WeakReference<Activity>(
                (Activity) getActivity());
        if (mainActivityWeakRef.get() != null
                && !mainActivityWeakRef.get().isFinishing()) {
            getData();
        }
        SharedPreferences onStopPf = getActivity().getSharedPreferences(
                "On Stop", 0);
        Editor stEditor = onStopPf.edit();
        curBtnIndex = onStopPf.getInt("btnIndex", -1);
        stEditor.commit();
        System.out.println("curt index from top -> " + curBtnIndex);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        System.out.println("onCreateView");
        View v = inflater.inflate(R.layout.main, container, false);
        initLayout(v);
        return v;
    }

    private void initLayout(View v) {
        TrackList = (ListView) v.findViewById(R.id.songList);
        // get image for ad
        imageView = (ImageView) v.findViewById(R.id.radio_adview);
        bar = (ProgressBar) v.findViewById(R.id.load);
    }

    public void getData() {
        Map<String, String> map = new HashMap<String, String>();
        map.put("url", getActivity().getString(R.string.get_song));
        new GetData(map);
    }

    public class CustomAdapter extends BaseAdapter {
        private ArrayList<Song> songListLocal;
        public Activity context;
        // Song s;

        public LayoutInflater inflater;

        public CustomAdapter(Activity context, ArrayList<Song> arr_calllog_name) {
            super();
            this.context = context;
            this.songListLocal = arr_calllog_name;
            inflater = (LayoutInflater) getActivity().getSystemService(
                    Context.LAYOUT_INFLATER_SERVICE);
        }

        @Override
        public int getCount() {
            return songListLocal.size();
        }

        @Override
        public Object getItem(int arg0) {
            return arg0;
        }

        @Override
        public long getItemId(int arg0) {
            return arg0;
        }

        @Override
        public View getView(final int position, View convertView,
                ViewGroup parent) {
            ImageView song_thumb;
            TextView txtName, songNumTxt;
            final Button playbutton;
            final Button stopbutton;
            final Button pausebutton;

            View view = convertView;
            final Song s = songListLocal.get(position);

            view = inflater.inflate(R.layout.list_item, null);
            song_thumb = (ImageView) view.findViewById(R.id.songthumb);
            txtName = (TextView) view.findViewById(R.id.songname);
            songNumTxt = (TextView) view.findViewById(R.id.songNum);
            playbutton = (Button) view.findViewById(R.id.playbutton);
            stopbutton = (Button) view.findViewById(R.id.stopbutton);
            pausebutton = (Button) view.findViewById(R.id.pausebutton);

            Picasso.with(getActivity()).load(s.getSong_icon()).into(song_thumb);

            txtName.setText(s.getName());
            songNumTxt.setText(String.valueOf(s.getSongNum()));
            playbutton.setOnClickListener(new View.OnClickListener() {

                @Override
                public void onClick(View v) {
                    curBtnIndex = position;

                    songPicked(position);
                    setlistview();
                    playbutton.setVisibility(View.INVISIBLE);
                    pausebutton.setVisibility(View.VISIBLE);
                    stopbutton.setVisibility(View.VISIBLE);
                }
            });
            pausebutton.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    //pause
                }
            });
            stopbutton.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v1) {
                    try {
                        paused = false;
                        playbutton.setVisibility(View.VISIBLE);
                        pausebutton.setVisibility(View.INVISIBLE);
                        stopbutton.setVisibility(View.INVISIBLE);
                    } catch (Exception e) {
                        System.out.println("exception in pause");
                    }
                }
            });
            if (curBtnIndex == position) {
                pausebutton.setVisibility(View.VISIBLE);
                stopbutton.setVisibility(View.VISIBLE);
                playbutton.setVisibility(View.INVISIBLE);
            } else {
                pausebutton.setVisibility(View.INVISIBLE);
                stopbutton.setVisibility(View.INVISIBLE);
            }
            return view;
        }
    }

    // user song select
    public void songPicked(int pos) {
        musicSrv.setSong(pos);
        musicSrv.playSong();
        if (playbackPaused) {
            playbackPaused = false;
        }
    }

    public void setlistview() {
        TrackList.setAdapter(songadapter);
        TrackList.setSelection(curBtnIndex);
    }

    private class GetData {
        private final Map<String, String> map;

        public GetData(Map<String, String> map2) {
            this.map = map2;
            new AsynRequest().execute(map.get("url"));
        }

        class AsynRequest extends AsyncTask<String, Void, String> {

            @Override
            protected void onPreExecute() {
            }

            @Override
            protected String doInBackground(String... urls) {
                map.remove("url");
                HttpPost httppost = new HttpPost(urls[0]);

                try {

                    HttpClient httpclient = new DefaultHttpClient();

                    List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();

                    for (String key : map.keySet()) {
                        System.out.println(key + "  < === >  " + map.get(key));

                        nameValuePairs.add(new BasicNameValuePair(key, map
                                .get(key)));
                    }

                    httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs,
                            "UTF-8"));

                    HttpResponse response = httpclient.execute(httppost);

                    String responseBody = EntityUtils.toString(response
                            .getEntity());

                    return responseBody;
                } catch (UnknownHostException e) {
                    e.printStackTrace();
                } catch (ClientProtocolException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }

                return null;

            }

            @Override
            protected void onPostExecute(String result) {
                // System.out.println("result of songs -> " + result);
                bar.setVisibility(View.GONE);
                if (result != null) {
                    try {
                        JSONObject jObject = new JSONObject(result);
                        String result1 = jObject.getString("result");
                        if (result1.equals("success")) {
                            JSONArray jArray = jObject.getJSONArray("songs");
                            songList = null;
                            songList = new ArrayList<Song>();
                            for (int i = 0; i < jArray.length(); i++) {
                                JSONObject j = jArray.getJSONObject(i);
                                Song s = new Song();
                                String song_icon_path = j
                                        .getString("song_icon");
                                String name = j.getString("name");
                                String song_file_path = j.getString("song_url");

                                s.setSong_icon(song_icon_path);
                                s.setName(name);
                                s.setSong_url(song_file_path);

                                int n = i + 1;
                                s.setSongNum(n);
                                songList.add(s);
                            }
                            if (songList != null) {
                                System.out.println("song list size -> "
                                        + songList.size());
                                mainActivityWeakRef = new WeakReference<Activity>(
                                        (Activity) getActivity());
                                if (mainActivityWeakRef.get() != null
                                        && !mainActivityWeakRef.get()
                                                .isFinishing()) {
                                    songadapter = new CustomAdapter(
                                            getActivity(), songList);
                                    TrackList.setAdapter(songadapter);

                                    if (playIntent == null) {
                                        playIntent = new Intent(getActivity(),
                                                MyService.class);
                                        musicBound = getActivity().bindService(
                                                playIntent, musicConnection,
                                                Context.BIND_AUTO_CREATE);
                                        System.out.println("service bound -> "
                                                + musicBound);
                                        getActivity().startService(playIntent);
                                    }
                                }

                            } else {
                                System.out.println("song list null");
                            }
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                        bar.setVisibility(View.GONE);
                    }
                }
                super.onPostExecute(result);
            }
        }
    }

    @Override
    public void onDestroyView() {
        System.out.println("onDestroyView()");
        boolean s = isMyServiceRunning(MyService.class);
        System.out.println("runnind ? " + s);
        if (musicBound) {
            musicBound = false;
            getActivity().unbindService(musicConnection);
        } else
            System.out.println("not bound");
        super.onDestroyView();
    }

    private boolean isMyServiceRunning(Class<?> serviceClass) {
        ActivityManager manager = (ActivityManager) getActivity()
                .getSystemService(Context.ACTIVITY_SERVICE);
        for (RunningServiceInfo service : manager
                .getRunningServices(Integer.MAX_VALUE)) {
            if (serviceClass.getName().equals(service.service.getClassName())) {
                return true;
            }
        }
        return false;
    }

    // connect to the service
    private ServiceConnection musicConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            MyBinder binder = (MyBinder) service;
            // get service
            musicSrv = binder.getService();
            // pass list
            musicSrv.setList(songList);
            musicBound = true;
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            musicBound = false;
        }
    };

MyService.java

public class MyService extends Service implements OnCompletionListener,
        OnErrorListener, OnPreparedListener {
    // media player
    private MediaPlayer player;
    // song list
    private ArrayList<Song> songs;
    // current position
    private int songPosn;
    // binder
    private final IBinder musicBind = new MyBinder();
    // title of current song
    private String songTitle = "";
    // notification id
    private static final int NOTIFY_ID = 1;

    @Override
    public void onCreate() {
        // create the service
        super.onCreate();
        // initialize position
        songPosn = 0;
        // create player
        player = new MediaPlayer();
        // initialize
        initMusicPlayer();
    }

    public void initMusicPlayer() {
        // set player properties
        player.setWakeMode(getApplicationContext(),
                PowerManager.PARTIAL_WAKE_LOCK);
        player.setAudioStreamType(AudioManager.STREAM_MUSIC);
        // set listeners
        player.setOnPreparedListener(this);
        player.setOnCompletionListener(this);
        player.setOnErrorListener(this);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return START_STICKY;
    }

    // pass song list
    public void setList(ArrayList<Song> theSongs) {
        songs = theSongs;
    }

    // binder
    public class MyBinder extends Binder {
        MyService getService() {
            return MyService.this;
        }
    }

    // activity will bind to service
    @Override
    public IBinder onBind(Intent intent) {
        return musicBind;
    }

    // release resources when unbind
    @Override
    public boolean onUnbind(Intent intent) {
        player.stop();
        player.release();
        return false;
    }

    // play a song
    public void playSong() {
        // play
        player.reset();
        // get song
        Song playSong = songs.get(songPosn);
        // get title
        songTitle = playSong.getName();

        String trackUri = playSong.getSong_url();
        System.out.println("track uri -> " + trackUri);
        // set the data source
        try {
            player.setDataSource(trackUri);
        } catch (Exception e) {
            Log.e("MUSIC SERVICE", "Error setting data source", e);
        }
        player.prepareAsync();
    }

    // set the song
    public void setSong(int songIndex) {
        songPosn = songIndex;
    }

    @Override
    public void onCompletion(MediaPlayer mp) {
        // check if playback has reached the end of a track
        if (player.getCurrentPosition() > 0) {
            mp.reset();
        }
    }

    @Override
    public boolean onError(MediaPlayer mp, int what, int extra) {
        Log.v("MUSIC PLAYER", "Playback Error");
        mp.reset();
        return false;
    }

    @Override
    public void onPrepared(MediaPlayer mp) {
        playMusic();
    }

    @Override
    public void onDestroy() {
        Log.e("MUSIC PLAYER", "onDestroy()");
        stopForeground(true);
    }

    public void playMusic() {
        player.start();
        // notification
        Intent notIntent = new Intent(this, MainActivity.class);
        PendingIntent pendInt = PendingIntent.getActivity(this, 0, notIntent,
                PendingIntent.FLAG_UPDATE_CURRENT);

        Notification.Builder builder = new Notification.Builder(this);

        builder.setContentIntent(pendInt).setSmallIcon(R.drawable.ic_launcher)
                .setTicker(songTitle).setOngoing(true)
                .setContentTitle("Playing").setContentText(songTitle);
        Notification not = builder.build();
        startForeground(NOTIFY_ID, not);
    }

}

music plays well but when i backpress on device its stop music. My Problem is i want to keep playing music in background if user presses hardware backbutton.

Any help will appreciate Thanks


Solution

  • You are unbinding from the service in onDestroyView. When the last ServiceConnection is unbound, the onUnbind method is called on the Service. Your onUnbind implementation stops playback. Instead you should include playback controls in your foreground notification and control playback via PendingIntents that are directed at your Service class.