Skip to content

Commit

Permalink
Merge pull request #5 from R-a-dio/musicplayer_service
Browse files Browse the repository at this point in the history
Musicplayer service
  • Loading branch information
CaptainJet authored Jan 4, 2017
2 parents 43a95ef + 21ed924 commit f8c536f
Show file tree
Hide file tree
Showing 8 changed files with 195 additions and 83 deletions.
12 changes: 7 additions & 5 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,19 @@
<activity
android:name=".ActivityMain"
android:screenOrientation="portrait"
android:configChanges="orientation|keyboardHidden">
android:configChanges="orientation|keyboardHidden"
android:launchMode="singleInstance">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".ActivitySlided"
android:label="@string/title_activity_slided"
android:theme="@style/AppTheme.NoActionBar"></activity>
<service
android:name="io.r_a_d.radio.RadioService"
android:enabled="true"
android:exported="true" >
</service>
</application>

</manifest>
105 changes: 33 additions & 72 deletions app/src/main/java/io/r_a_d/radio/ActivityMain.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,9 @@
import android.content.Intent;
import android.graphics.Rect;
import android.net.Uri;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.PowerManager;
import android.support.design.widget.TabLayout;
import android.support.v4.content.res.ResourcesCompat;
import android.support.v4.graphics.drawable.RoundedBitmapDrawable;
Expand All @@ -27,44 +25,23 @@
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.w3c.dom.Text;

import com.google.android.exoplayer2.DefaultLoadControl;
import com.google.android.exoplayer2.ExoPlayerFactory;
import com.google.android.exoplayer2.LoadControl;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory;
import com.google.android.exoplayer2.extractor.ExtractorsFactory;
import com.google.android.exoplayer2.source.ExtractorMediaSource;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelector;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
import com.google.android.exoplayer2.util.Util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;

public class ActivityMain extends AppCompatActivity implements ViewPager.OnPageChangeListener{

private boolean playing = false;
private boolean songChanged = false;
private boolean firstSearchClick = true;
private SimpleExoPlayer sep;
private Integer api_update_delay = 10000;
private final Integer UPDATE_INTERVAL = 500;
private ViewPager viewPager;
private JSONScraperTask jsonTask = new JSONScraperTask(this, 0);
private Integer ui_page_to_update = 0;
private DJImageTask djimageTask = new DJImageTask(this);
private String radio_url = "https://stream.r-a-d.io/main.mp3";
private String api_url = "https://r-a-d.io/api";
private String djimage_api = "https://r-a-d.io/api/dj-image/";
private String news_api_url = "https://r-a-d.io/api/news/";
Expand All @@ -76,10 +53,7 @@ public class ActivityMain extends AppCompatActivity implements ViewPager.OnPageC
private HashMap<String, Integer> songTimes;
private Requestor mRequestor;

private PowerManager powerManager;
private PowerManager.WakeLock wakeLock;
private WifiManager wifiManager;
private WifiManager.WifiLock wifiLock;
private boolean playing = false;

private Handler handler = new Handler(){
@Override
Expand All @@ -94,11 +68,6 @@ public void handleMessage(Message msg){
protected void onCreate(Bundle savedInstanceState) {
setTheme(R.style.AppTheme);
super.onCreate(savedInstanceState);

powerManager = (PowerManager) getSystemService(POWER_SERVICE);
wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "KilimDankLock");
wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
wifiLock = wifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "KilimDankWifiLock");
setContentView(R.layout.homescreen);
songTimes = new HashMap<>();

Expand All @@ -113,7 +82,6 @@ protected void onCreate(Bundle savedInstanceState) {

scrapeNews(news_api_url);
scrapeJSON(api_url);
createMediaPlayer();

handler.postDelayed(new Runnable(){
public void run(){
Expand All @@ -130,21 +98,20 @@ public void run() {
});
songCalcThread.setDaemon(true);
songCalcThread.start();

mRequestor = new Requestor(this);
}

@Override
protected void onDestroy() {
super.onDestroy();
sep.stop();
sep.release();
sep = null;
releaseWakeLocks();

if(songCalcThread.isAlive() && !songCalcThread.isInterrupted())
songCalcThread.interrupt();
}
@Override
protected void onResume() {
super.onResume();
}

@Override
public void onPageSelected(int position) {
Expand Down Expand Up @@ -183,21 +150,6 @@ public void onPageScrollStateChanged(int state) {
return;
}

public void createMediaPlayer() {
TrackSelector tSelector = new DefaultTrackSelector();
LoadControl lc = new DefaultLoadControl();
sep = ExoPlayerFactory.newSimpleInstance(this, tSelector, lc);
}

public void setupMediaPlayer() {
DataSource.Factory dsf = new DefaultDataSourceFactory(this,
Util.getUserAgent(this, "R/a/dio-Android-App"));
ExtractorsFactory extractors = new DefaultExtractorsFactory();
MediaSource audioSource = new ExtractorMediaSource(Uri.parse(radio_url), dsf, extractors, null, null);

sep.prepare(audioSource);
}

public void openThread(View v) {
try {
if (current_ui_json != null) {
Expand Down Expand Up @@ -331,6 +283,16 @@ public void updateUI(){
}
}

// Fix for syncing play/pause button by taking advantage of the fact that this code gets
// called after the JSON gets scraped everything the main activity is instantiated.
// I don't know where else it could/should go.
ImageButton img = (ImageButton)now_playing.findViewById(R.id.play_pause);
if(PlayerState.CURRENTLY_PLAYING){
img.setImageResource(R.drawable.pause_small);
} else {
img.setImageResource(R.drawable.arrow_small);
}

} catch (JSONException e) {
e.printStackTrace();
}
Expand Down Expand Up @@ -553,16 +515,6 @@ public void run() {
catch(InterruptedException ex) {}
}

public void acquireWakeLocks() {
wakeLock.acquire();
wifiLock.acquire();
}

public void releaseWakeLocks() {
if(wakeLock.isHeld()) wakeLock.release();
if(wifiLock.isHeld()) wifiLock.release();
}

private boolean isDrawerVisible(View view) {

Rect scrollBounds = new Rect();
Expand All @@ -574,20 +526,29 @@ private boolean isDrawerVisible(View view) {
}
}

private void playPlayerService() {
Intent i = new Intent(this, RadioService.class);
i.putExtra("action", "io.r_a_d.radio.PLAY");
startService(i);
}

private void pausePlayerService() {
Intent i = new Intent(this, RadioService.class);
i.putExtra("action", "io.r_a_d.radio.PAUSE");
startService(i);
}

public void togglePlayPause(View v) {
if(isDrawerVisible(findViewById(android.R.id.content))) return;
ImageButton img = (ImageButton)v.findViewById(R.id.play_pause);
if(!playing){
if(!PlayerState.CURRENTLY_PLAYING){
img.setImageResource(R.drawable.pause_small);
playing = true;
setupMediaPlayer();
sep.setPlayWhenReady(playing);
acquireWakeLocks();
playPlayerService();
PlayerState.CURRENTLY_PLAYING = true;
} else {
img.setImageResource(R.drawable.arrow_small);
playing = false;
sep.stop();
releaseWakeLocks();
pausePlayerService();
PlayerState.CURRENTLY_PLAYING = false;
}
}
}
9 changes: 9 additions & 0 deletions app/src/main/java/io/r_a_d/radio/PlayerState.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package io.r_a_d.radio;

/**
* Created by resttime on 1/3/2017.
*/

public final class PlayerState {
public static boolean CURRENTLY_PLAYING = false;
}
145 changes: 145 additions & 0 deletions app/src/main/java/io/r_a_d/radio/RadioService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
package io.r_a_d.radio;

import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.IBinder;
import android.os.PowerManager;
import android.support.annotation.Nullable;

import com.google.android.exoplayer2.DefaultLoadControl;
import com.google.android.exoplayer2.ExoPlayerFactory;
import com.google.android.exoplayer2.LoadControl;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory;
import com.google.android.exoplayer2.extractor.ExtractorsFactory;
import com.google.android.exoplayer2.source.ExtractorMediaSource;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelector;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
import com.google.android.exoplayer2.util.Util;

public class RadioService extends Service {

private static final String ACTION_PLAY = "io.r_a_d.radio.PLAY";
private static final String ACTION_PAUSE = "io.r_a_d.radio.PAUSE";



private PowerManager powerManager;
private PowerManager.WakeLock wakeLock;
private WifiManager wifiManager;
private WifiManager.WifiLock wifiLock;
private SimpleExoPlayer sep;
private Notification notification;


private String radio_url = "https://stream.r-a-d.io/main.mp3";

public RadioService() {
}

@Override
public void onCreate() {
super.onCreate();

powerManager = (PowerManager) getSystemService(POWER_SERVICE);
wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "KilimDankLock");
wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
wifiLock = wifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "KilimDankWifiLock");
createMediaPlayer();

Intent notificationIntent = new Intent(this, ActivityMain.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
notificationIntent, 0);

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

builder.setContentTitle("R/a/dio is streaming");
builder.setContentText("Touch to return to app");
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
builder.setSmallIcon(R.drawable.lollipop_logo);
builder.setColor(0xFFDF4C3A);
} else {
builder.setSmallIcon(R.drawable.normal_logo);
}
builder.setContentIntent(pendingIntent);
notification = builder.build();

}



public void setupMediaPlayer() {
DataSource.Factory dsf = new DefaultDataSourceFactory(this,
Util.getUserAgent(this, "R/a/dio-Android-App"));
ExtractorsFactory extractors = new DefaultExtractorsFactory();
MediaSource audioSource = new ExtractorMediaSource(Uri.parse(radio_url), dsf, extractors, null, null);

sep.prepare(audioSource);
}


@Override
public int onStartCommand(Intent intent, int flags, int startId) {

if (intent.getStringExtra("action").equals(ACTION_PLAY)) {
setupMediaPlayer();
sep.setPlayWhenReady(true);
acquireWakeLocks();
startForeground(1, notification);
} else if (intent.getStringExtra("action").equals(ACTION_PAUSE)){
sep.stop();
releaseWakeLocks();
stopForeground(true);
}

return super.onStartCommand(intent, flags, startId);
}

@Override
public void onDestroy() {
super.onDestroy();
sep.stop();
sep.release();
sep = null;
releaseWakeLocks();
}

@Override
public void onTaskRemoved(Intent rootIntent) {
if(!PlayerState.CURRENTLY_PLAYING) {
stopSelf();
}
super.onTaskRemoved(rootIntent);
}

@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}

public void acquireWakeLocks() {
wakeLock.acquire();
wifiLock.acquire();
}

public void releaseWakeLocks() {
if(wakeLock.isHeld()) wakeLock.release();
if(wifiLock.isHeld()) wifiLock.release();
}

public void createMediaPlayer() {
TrackSelector tSelector = new DefaultTrackSelector();
LoadControl lc = new DefaultLoadControl();
sep = ExoPlayerFactory.newSimpleInstance(this, tSelector, lc);
}
}
Loading

0 comments on commit f8c536f

Please sign in to comment.