Java tutorial
/* * </summary> * Source File : PlayerService.java * Project : Sarigama * Owner : Kasun * </summary> * * <license> * Copyright 2016 Kasun Gunathilaka * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http:www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * </license> */ package com.kasungunathilaka.sarigama.service; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.media.MediaPlayer; import android.os.Binder; import android.os.Build; import android.os.IBinder; import android.support.v4.app.NotificationCompat; import android.support.v4.content.LocalBroadcastManager; import android.widget.RemoteViews; import android.widget.Toast; import com.kasungunathilaka.sarigama.R; import com.kasungunathilaka.sarigama.business.URLBusiness; import com.kasungunathilaka.sarigama.domain.Song; import com.kasungunathilaka.sarigama.domain.URLDomain; import com.kasungunathilaka.sarigama.ui.HomeActivity; import com.kasungunathilaka.sarigama.util.PlayerQueue; import com.loopj.android.http.AsyncHttpClient; import com.loopj.android.http.AsyncHttpResponseHandler; import java.io.IOException; import java.io.InputStream; import java.net.URL; import cz.msebera.android.httpclient.Header; public class PlayerService extends Service implements MediaPlayer.OnCompletionListener, MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener { private static final int NOTIFICATION_ID = 9999; private static final int REQUEST_CODE = 100; private final IBinder playerBinder = new PlayerBinder(); //region private members private MediaPlayer mainPlayer, slavePlayer; private LocalBroadcastManager localBroadcastManager; private PlayerQueue playerQueue = PlayerQueue.getInstance(this); private URLBusiness uRLBusiness; //endregion private boolean parentLoop = false; private boolean random = false; private PendingIntent startIntent; private PendingIntent playIntent; private PendingIntent previousIntent; private PendingIntent nextIntent; private NotificationIntentReceiver notificationIntentReceiver; private static void startIntent(Context context, Class<?> cls) { Intent intent = new Intent(context, cls); intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(intent); } //region overridden method @Override public IBinder onBind(Intent intent) { return playerBinder; } @Override public void onCreate() { localBroadcastManager = LocalBroadcastManager.getInstance(this); startIntent = PendingIntent.getBroadcast(PlayerService.this, REQUEST_CODE, new Intent(HomeActivity.ACTION_BRING_FRONT), PendingIntent.FLAG_UPDATE_CURRENT); playIntent = PendingIntent.getBroadcast(PlayerService.this, REQUEST_CODE, new Intent(HomeActivity.ACTION_PLAY), PendingIntent.FLAG_UPDATE_CURRENT); previousIntent = PendingIntent.getBroadcast(PlayerService.this, REQUEST_CODE, new Intent(HomeActivity.ACTION_PREV), PendingIntent.FLAG_UPDATE_CURRENT); nextIntent = PendingIntent.getBroadcast(PlayerService.this, REQUEST_CODE, new Intent(HomeActivity.ACTION_NEXT), PendingIntent.FLAG_UPDATE_CURRENT); notificationIntentReceiver = new NotificationIntentReceiver(); registerReceiver(notificationIntentReceiver, new IntentFilter(HomeActivity.ACTION_PLAY)); registerReceiver(notificationIntentReceiver, new IntentFilter(HomeActivity.ACTION_BRING_FRONT)); registerReceiver(notificationIntentReceiver, new IntentFilter(HomeActivity.ACTION_NEXT)); registerReceiver(notificationIntentReceiver, new IntentFilter(HomeActivity.ACTION_PREV)); } @Override public void onPrepared(MediaPlayer mp) { if (mainPlayer != null) { mainPlayer.stop(); mainPlayer.release(); } mainPlayer = slavePlayer; localBroadcastManager.sendBroadcast(new Intent(HomeActivity.ON_PREPARED)); slavePlayer = null; mainPlayer.start(); int position = playerQueue.getCurrentPosition(); Song currentSong = playerQueue.getSongByPosition(position); setupNotification(currentSong, HomeActivity.NOTIFICATION_TYPE_PLAY); localBroadcastManager.sendBroadcast(new Intent(HomeActivity.ON_PLAY)); } public void onCompletion(MediaPlayer mp) { localBroadcastManager.sendBroadcast(new Intent(HomeActivity.ON_COMPLETED)); this.seekTo(0); if (mp.isLooping()) { setPlayPause(); localBroadcastManager.sendBroadcast(new Intent(HomeActivity.ON_PREPARED)); } else { next(); } } @Override public boolean onError(MediaPlayer mp, int what, int extra) { localBroadcastManager.sendBroadcast(new Intent(HomeActivity.ON_PREPARE_ERROR)); mp = null; next(); return true; } //endregion public void onDestroy() { if (mainPlayer.isPlaying()) { mainPlayer.stop(); } mainPlayer.release(); } //region public methods public void startPlayer(int position) { try { localBroadcastManager.sendBroadcast(new Intent(HomeActivity.ON_PREPARING)); slavePlayer = new MediaPlayer(); slavePlayer.setOnPreparedListener(this); slavePlayer.setOnErrorListener(this); slavePlayer.setOnCompletionListener(this); getSongData(position); } catch (Exception e) { e.printStackTrace(); } } public void stopPlayerQueue() { if (mainPlayer != null) { if (mainPlayer.isPlaying()) { mainPlayer.stop(); mainPlayer.release(); slavePlayer = null; mainPlayer = null; } else { mainPlayer.release(); slavePlayer = null; mainPlayer = null; } } else { slavePlayer = null; } } public void setPlayPause() { if (mainPlayer != null) { if (mainPlayer.isPlaying()) { int position = playerQueue.getCurrentPosition(); Song currentSong = playerQueue.getSongByPosition(position); setupNotification(currentSong, HomeActivity.NOTIFICATION_TYPE_PAUSE); localBroadcastManager.sendBroadcast(new Intent(HomeActivity.ON_PAUSE)); mainPlayer.pause(); } else { int position = playerQueue.getCurrentPosition(); Song currentSong = playerQueue.getSongByPosition(position); setupNotification(currentSong, HomeActivity.NOTIFICATION_TYPE_PLAY); localBroadcastManager.sendBroadcast(new Intent(HomeActivity.ON_PLAY)); mainPlayer.start(); } } else { int position = playerQueue.getCurrentPosition(); startPlayer(position); } } public boolean isPlaying() { if (mainPlayer == null) { return false; } else { return mainPlayer.isPlaying(); } } public void seekTo(int progress) { if (mainPlayer != null) { mainPlayer.seekTo(progress); } } public void next() { try { setupNotification(null, HomeActivity.NOTIFICATION_TYPE_DISMISS); int position = playerQueue.getCurrentPosition(); slavePlayer = new MediaPlayer(); slavePlayer.setOnPreparedListener(this); slavePlayer.setOnErrorListener(this); slavePlayer.setOnCompletionListener(this); if (playerQueue.hasPosition((position + 1))) { localBroadcastManager.sendBroadcast(new Intent(HomeActivity.ON_PREPARING)); playerQueue.setCurrentPosition((position + 1)); Song currentSong = playerQueue.getSongByPosition((position + 1)); if (currentSong.getSongSource() == null) { getSongData(playerQueue.getCurrentPosition()); } else { slavePlayer.setDataSource(currentSong.getSongSource()); slavePlayer.prepareAsync(); } } else if (parentLoop) { localBroadcastManager.sendBroadcast(new Intent(HomeActivity.ON_PREPARING)); playerQueue.setCurrentPosition(0); Song currentSong = playerQueue.getSongByPosition(0); if (currentSong.getSongSource() == null) { getSongData(playerQueue.getCurrentPosition()); } else { slavePlayer.setDataSource(currentSong.getSongSource()); slavePlayer.prepareAsync(); } } else { localBroadcastManager.sendBroadcast(new Intent(HomeActivity.ON_COMPLETED)); localBroadcastManager.sendBroadcast(new Intent(HomeActivity.ON_QUEUE_COMPLETED)); this.seekTo(0); mainPlayer.stop(); mainPlayer.release(); mainPlayer = null; slavePlayer = null; playerQueue.setCurrentPosition(0); Toast.makeText(PlayerService.this, "Song queue end reached", Toast.LENGTH_SHORT).show(); } } catch (Exception e) { e.printStackTrace(); } } public void previous() { try { int position = playerQueue.getCurrentPosition(); slavePlayer = new MediaPlayer(); slavePlayer.setOnPreparedListener(this); slavePlayer.setOnErrorListener(this); slavePlayer.setOnCompletionListener(this); if (playerQueue.hasPosition((position - 1))) { localBroadcastManager.sendBroadcast(new Intent(HomeActivity.ON_PREPARING)); playerQueue.setCurrentPosition((position - 1)); Song currentSong = playerQueue.getSongByPosition((position - 1)); if (currentSong.getSongSource() == null) { getSongData(playerQueue.getCurrentPosition()); } else { slavePlayer.setDataSource(currentSong.getSongSource()); slavePlayer.prepareAsync(); } } else { localBroadcastManager.sendBroadcast(new Intent(HomeActivity.ON_COMPLETED)); this.seekTo(0); mainPlayer.stop(); mainPlayer.release(); mainPlayer = null; slavePlayer = null; playerQueue.setCurrentPosition(0); } } catch (Exception e) { e.printStackTrace(); } } public int getDuration() { if (mainPlayer == null) { return 0; } else { return mainPlayer.getDuration(); } } public int getCurrentPosition() { if (mainPlayer == null) { return 0; } else { return mainPlayer.getCurrentPosition(); } } public boolean isQueueOnLoop() { return parentLoop; } public void setQueueOnLoop(boolean loop) { this.parentLoop = loop; } public boolean isSongOnLoop() { if (mainPlayer != null) { return mainPlayer.isLooping(); } else { return false; } } public void setSongOnLoop(boolean loop) { if (mainPlayer != null) { mainPlayer.setLooping(loop); } } public boolean isPlayerNull() { return mainPlayer != null; } public boolean isRandom() { return random; } //endregion public void setRandom(boolean random) { this.random = random; } //region private methods private void getSongData(final int position) { try { uRLBusiness = new URLBusiness(PlayerService.this); if (uRLBusiness.Exist(playerQueue.getSongByPosition(position).getSongItem())) { getSongDetail(uRLBusiness.SelectSingle(playerQueue.getSongByPosition(position).getSongItem()) .getUrlContent(), position); uRLBusiness.Close(); } else { AsyncHttpClient asyncHttpClient = new AsyncHttpClient(); asyncHttpClient.post(PlayerService.this, playerQueue.getSongByPosition(position).getSongItem(), null, new AsyncHttpResponseHandler() { @Override public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) { try { URLDomain uRLDomain = new URLDomain(); uRLDomain.setUrlAddress(playerQueue.getSongByPosition(position).getSongItem()); uRLDomain.setUrlContent(new String(responseBody)); uRLBusiness.Save(uRLDomain); uRLBusiness.Close(); getSongDetail(new String(responseBody), position); } catch (Exception e) { e.printStackTrace(); } } @Override public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) { Toast.makeText(PlayerService.this, "Song added failed", Toast.LENGTH_SHORT).show(); } }); } } catch (Exception e) { e.printStackTrace(); } } private void getSongDetail(String body, int position) { try { int startIndex = body.indexOf("profile-pic"); startIndex = startIndex + 18; int endIndex = body.indexOf("alt", startIndex + 1); endIndex = endIndex - 2; String imageUrl = body.substring(startIndex, endIndex).trim(); System.out.println(imageUrl); startIndex = body.indexOf("<source"); startIndex = startIndex + 13; endIndex = body.indexOf("type", startIndex + 1); endIndex = endIndex - 2; String url = body.substring(startIndex, endIndex).trim(); System.out.println(url); url = url.replace(" ", "%20"); playerQueue.getSongByPosition(position).setSongSource(url); playerQueue.getSongByPosition(position).setSongImage(imageUrl); slavePlayer .setDataSource(playerQueue.getSongByPosition(playerQueue.getCurrentPosition()).getSongSource()); slavePlayer.prepareAsync(); } catch (IOException e) { e.printStackTrace(); } } private void setupNotification(Song song, String notificationType) { Bitmap remote_picture = null; RemoteViews smallNotification; RemoteViews bigNotification; Notification notification; NotificationManager notificationManager = (NotificationManager) getSystemService( Context.NOTIFICATION_SERVICE); if (song != null) { if (song.getSongImage().contentEquals("http://sarigama.lk/img/songs/default.jpg")) { remote_picture = BitmapFactory.decodeResource(PlayerService.this.getResources(), R.drawable.default_song_art); } else { try { remote_picture = BitmapFactory .decodeStream((InputStream) new URL(song.getSongImage()).getContent()); } catch (Exception e) { remote_picture = BitmapFactory.decodeResource(PlayerService.this.getResources(), R.drawable.default_song_art); e.printStackTrace(); } } } switch (notificationType) { case HomeActivity.NOTIFICATION_TYPE_PLAY: try { smallNotification = new RemoteViews(getPackageName(), R.layout.notification_layout_small); smallNotification.setImageViewBitmap(R.id.ivSmallNotificationSongImage, remote_picture); smallNotification.setTextViewText(R.id.tvSmallNotificationSong, song.getSongTitle()); smallNotification.setTextViewText(R.id.tvSmallNotificationArtist, song.getSongArtist()); smallNotification.setImageViewResource(R.id.ibSmallPlay, R.drawable.ic_pause_white); smallNotification.setOnClickPendingIntent(R.id.flSmallPlay, playIntent); smallNotification.setOnClickPendingIntent(R.id.ivSmallNext, nextIntent); bigNotification = new RemoteViews(getPackageName(), R.layout.notification_layout_big); bigNotification.setImageViewBitmap(R.id.ivBigNotificationSongImage, remote_picture); bigNotification.setTextViewText(R.id.tvBigNotificationSong, song.getSongTitle()); bigNotification.setTextViewText(R.id.tvBigNotificationArtist, song.getSongArtist()); bigNotification.setImageViewResource(R.id.ibBigPlay, R.drawable.ic_pause_white); bigNotification.setOnClickPendingIntent(R.id.ibBigNext, nextIntent); bigNotification.setOnClickPendingIntent(R.id.ibBigPlay, playIntent); bigNotification.setOnClickPendingIntent(R.id.ibBigPrevious, previousIntent); notification = new NotificationCompat.Builder(this).setSmallIcon(R.drawable.ic_play_white) .setAutoCancel(false).setOngoing(true).setContent(smallNotification) .setContentIntent(startIntent).build(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { notification.bigContentView = bigNotification; } notificationManager.notify(NOTIFICATION_ID, notification); } catch (Exception e) { e.printStackTrace(); } break; case HomeActivity.NOTIFICATION_TYPE_PAUSE: try { smallNotification = new RemoteViews(getPackageName(), R.layout.notification_layout_small); smallNotification.setImageViewResource(R.id.ibSmallPlay, R.drawable.ic_play_white); bigNotification = new RemoteViews(getPackageName(), R.layout.notification_layout_big); bigNotification.setImageViewBitmap(R.id.ivBigNotificationSongImage, remote_picture); bigNotification.setTextViewText(R.id.tvBigNotificationSong, song.getSongTitle()); bigNotification.setTextViewText(R.id.tvBigNotificationArtist, song.getSongArtist()); bigNotification.setImageViewResource(R.id.ibBigPlay, R.drawable.ic_play_white); bigNotification.setOnClickPendingIntent(R.id.ibBigNext, nextIntent); bigNotification.setOnClickPendingIntent(R.id.ibBigPlay, playIntent); bigNotification.setOnClickPendingIntent(R.id.ibBigPrevious, previousIntent); notification = new NotificationCompat.Builder(this).setSmallIcon(R.drawable.ic_pause_white) .setOngoing(false).setAutoCancel(false).setContent(smallNotification) .setContentIntent(startIntent).build(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { notification.bigContentView = bigNotification; } notificationManager.notify(NOTIFICATION_ID, notification); } catch (Exception e) { e.printStackTrace(); } break; case HomeActivity.NOTIFICATION_TYPE_DISMISS: notificationManager.cancel(NOTIFICATION_ID); break; } } //endregion //region public sub class public class PlayerBinder extends Binder { public PlayerService getService() { return PlayerService.this; } } private class NotificationIntentReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { switch (intent.getAction()) { case HomeActivity.ACTION_NEXT: next(); break; case HomeActivity.ACTION_PREV: previous(); break; case HomeActivity.ACTION_PLAY: setPlayPause(); break; case HomeActivity.ACTION_BRING_FRONT: startIntent(getBaseContext(), HomeActivity.class); break; } } } //endregion }