在Google Play:
上查看我的应用 Â代ç 已更新为使用ç”案æ供的建议,但ä»ç„¶é‡åˆ°ä¸€äº›é—®é¢˜......
我在æœåŠ¡ä¸ä½¿ç”¨BroadCast Receiver从Spotify(外部应用程åºï¼‰èŽ·å–元数æ®ã€‚但是,Spotify的独特之处在于它å‘é€äº†ä»¥ä¸‹æ„图æ“作:
但是,我é‡åˆ°äº†ä¸€äº›é—®é¢˜ã€‚我写了以下代ç :
public class BackgroundService extends Service {
AudioManager am;
int positionInMs;
double eps = 5000;
String trackId = null;
String lastTrackId = null;
int lastPlayTime = 0;
int addSeconds = 0;
int trackLengthInSec = 0;
boolean playing = false;
boolean timerStarted = false;
void startTimer(){
timerStarted = true;
new Timer(true).scheduleAtFixedRate(
new TimerTask() {
@Override
public void run() {
if(playing) {
if(lastTrackId == null) {
lastTrackId = trackId;
}else if (!lastTrackId.equals(trackId)) {
addSeconds = 1;
playing = true;
lastPlayTime = positionInMs;
// Track changed. Reset counter.
}else{
addSeconds++; // Increment counter.
}
checkMuteStatus(trackLengthInSec, lastPlayTime + addSeconds * 1000 // multiply by 1000 as we're counting in seconds
);
}
Log.e("-------:", "Last Play Time: " + String.valueOf(lastPlayTime));
Log.e("-------:", "Track Length: " + String.valueOf(trackLengthInSec));
Log.e("-------:", "Current Position: " + String.valueOf(lastPlayTime + addSeconds * 1000));
}
},
1000, // Wait a second before first run
1000 // Runs every second
);
}
@Override
public void onCreate() {
super.onCreate();
am = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
IntentFilter filter;
filter = new IntentFilter();
filter.addAction("com.spotify.music.playbackstatechanged");
filter.addAction("com.spotify.music.metadatachanged");
filter.addAction("com.spotify.music.queuechanged");
Notification notification = new Notification();
startForeground(1, notification);
registerReceiver(receiver, filter);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
private final BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) throws NullPointerException {
long timeSentInMs = intent.getLongExtra("timeSent", 0L);
String action = intent.getAction();
if (action.equals(BroadcastTypes.METADATA_CHANGED)) {
trackId = intent.getStringExtra("id");
String artistName = intent.getStringExtra("artist");
String albumName = intent.getStringExtra("album");
String trackName = intent.getStringExtra("track");
trackLengthInSec = intent.getIntExtra("length", 0);
Log.e("STATUS:", trackName);
Log.e("STATUS:", artistName);
Log.e("STATUS:", albumName);
Log.e("STATUS:", "TRACK LENGTH: " + String.valueOf(trackLengthInSec));
Log.e("STATUS:", trackId);
Log.e("STATUS:", "POSITION: " + String.valueOf(positionInMs));
if(!timerStarted) {
startTimer();
}
//---------------------- IF PAUSED OR SONG CHANGED---------------------
} else if (action.equals(BroadcastTypes.PLAYBACK_STATE_CHANGED)) {
playing = intent.getBooleanExtra("playing", false);
positionInMs = intent.getIntExtra("playbackPosition", 0);
lastPlayTime = positionInMs;
addSeconds = 0; // Reset counter as we've now got the current position.
if(!timerStarted) {
startTimer();
}
}
}
};
void checkMuteStatus(double trackLength, double currentTime) {
if (Math.abs(trackLength - currentTime) < eps) {
mute(am);
Log.e("STATUS:", "MUTED");
addSeconds = 0;
lastPlayTime = 0;
} else {
unMute(am);
Log.e("STATUS:", "NOT MUTED");
}
}
@Override
public void onDestroy() {
super.onDestroy();
Log.e("STATUS:", "In onDestroy");
unregisterReceiver(receiver);
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
static final class BroadcastTypes {
static final String SPOTIFY_PACKAGE = "com.spotify.music";
static final String PLAYBACK_STATE_CHANGED = SPOTIFY_PACKAGE + ".playbackstatechanged";
static final String METADATA_CHANGED = SPOTIFY_PACKAGE + ".metadatachanged";
}
public void mute(AudioManager audioManager){
audioManager.setStreamMute(audioManager.STREAM_SYSTEM, true);
audioManager.setStreamMute(AudioManager.STREAM_NOTIFICATION, true);
audioManager.setStreamMute(AudioManager.STREAM_ALARM, true);
audioManager.setStreamMute(AudioManager.STREAM_MUSIC, true);
audioManager.setStreamMute(AudioManager.STREAM_RING, true);
}
public void unMute(AudioManager audioManager){
audioManager.setStreamMute(audioManager.STREAM_SYSTEM,false);
audioManager.setStreamMute(AudioManager.STREAM_NOTIFICATION, false);
audioManager.setStreamMute(AudioManager.STREAM_ALARM, false);
audioManager.setStreamMute(AudioManager.STREAM_MUSIC, false);
audioManager.setStreamMute(AudioManager.STREAM_RING, false);
}
}
这一切在获å–æ•°æ®ç‰æ–¹é¢éƒ½éžå¸¸æœ‰æ•ˆã€‚
基本上,当从æŒæ›²ä¸å½“å‰æ’放时间å‡åŽ»çš„æŒæ›²é•¿åº¦å°äºŽæŸä¸ªæ•°å—时,我试图将用户的手机é™éŸ³ã€‚这基本上å…许我在广告æ’放时将设备é™éŸ³ï¼Œå¹¶åœ¨å¯åŠ¨æ–°æŒæ—¶å–消é™éŸ³ã€‚我é‡åˆ°çš„唯一问题是我åªèƒ½åœ¨æ’放状æ€æ”¹å˜æ—¶è®¿é—®æŒæ›²ä¸çš„当å‰ä½ç½®ã€‚这实际上æ„味ç€ä¸ºäº†è®©æˆ‘的应用程åºæ£€æŸ¥æ˜¯å¦åº”该é™éŸ³è®¾å¤‡ï¼Œå¿…须首先暂åœSpotify,以便更新当å‰æ’放时间。
所以我的问题是,如何让我当å‰çš„æ’放时间ä¿æŒæœ€æ–°ï¼Œä»¥ä¾¿æˆ‘çš„é™éŸ³åŠŸèƒ½èƒ½å¤Ÿæ£å¸¸å·¥ä½œï¼Ÿæœ‰æ²¡æœ‰åŠžæ³•å¯ä»¥å®žçŽ°ä¸€ç§â€œå®šæ—¶å™¨â€ï¼Œå®ƒåœ¨æˆ‘收到当å‰æ’放时间的值åŽå¼€å§‹æ’放,然åŽå¢žåŠ 时间直到下一次更新?
ç”案 0 :(得分:1)
ä½ å¯ä»¥å¼€å§‹æ’放æŒæ›²æ—¶æ¯ç§’执行的timer,然åŽç”¨å®ƒæ¥è·Ÿè¸ªè‡ªé‚£ä»¥åŽç»è¿‡çš„秒数。
private final BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) throws NullPointerException {
long timeSentInMs = intent.getLongExtra("timeSent", 0L);
String action = intent.getAction();
if (action.equals(BroadcastTypes.METADATA_CHANGED)) {
trackId = intent.getStringExtra("id");
String artistName = intent.getStringExtra("artist");
String albumName = intent.getStringExtra("album");
String trackName = intent.getStringExtra("track");
trackLengthInSec = intent.getIntExtra("length", 0);
Log.e("STATUS:", trackName);
Log.e("STATUS:", artistName);
Log.e("STATUS:", albumName);
Log.e("STATUS:", "TRACK LENGTH: " + String.valueOf(trackLengthInSec));
Log.e("STATUS:", trackId);
Log.e("STATUS:", "POSITION: " + String.valueOf(positionInMs));
// the new track id is always updated just before the next song is played
// so we can safely assume that the ad has finished playing and it's time to unmute
unMute(am);
// reset & resume the timer
lastPlayTime = 0;
addSeconds = 0;
currentlyAdPlaying = false;
if(!timerStarted)
startTimer();
//---------------------- IF PAUSED OR SONG CHANGED---------------------
} else if (action.equals(BroadcastTypes.PLAYBACK_STATE_CHANGED)) {
playing = intent.getBooleanExtra("playing", false);
positionInMs = intent.getIntExtra("playbackPosition", 0);
// this is just needed to correct an eventually existing offset from the real time.
lastPlayTime = positionInMs;
addSeconds = 0; // Reset counter as we've now got the current position.
checkMuteStatus(trackLengthInSec, positionInMs);
}
}
};
String trackId = null;
String lastTrackId = null;
int lastPlayTime = 0;
int addSeconds = 0;
int trackLengthInSec = 0;
boolean playing = false;
boolean timerStarted = false;
boolean currentlyAdPlaying = true;
void startTimer(){
timerStarted = true;
new Timer(true).scheduleAtFixedRate(
new TimerTask() {
@Override
public void run() {
if(playing && !currentlyAdPlaying) {
if(lastTrackId == null)
lastTrackId = trackId;
if(lastTrackId != trackId){
lastTrackId = trackId;
addSeconds = 1; // Track changed. Reset counter.
} else {
addSeconds++; // Increment counter.
}
checkMuteStatus(
trackLengthInSec,
lastPlayTime + addSeconds * 1000
);
}
}
},
1000, // Wait a second before first run
1000 // Runs every second
);
}
void checkMuteStatus(double trackLength, double currentTime) {
// trackLength is in seconds, but currentTime in MS.
// So we should be changing trackLength to MS as well, right?
trackLength *= 1000;
if (Math.abs(trackLength - currentTime) < eps) {
mute(am);
Log.e("STATUS:", "MUTED");
// pause the timer, for an ad is playing.
currentlyAdPlaying = true;
} else {
unMute(am);
Log.e("STATUS:", "NOT MUTED");
}
}
基本上,计时器æ¯ç§’è¿è¡Œä¸€æ¬¡ï¼ˆä»Žå¹¿å‘Šæ’放完毕开始),然åŽåªè¦æŒæ›²æ²¡æœ‰æš‚åœå°±é€’增计数器。在到达æŒæ›²ç»“æŸæ—¶ï¼Œè®¡æ—¶å™¨æš‚åœï¼Œå› 为下一个广告将æ’放。广告æ’放完毕åŽï¼Œè®¡æ—¶å™¨å°†é‡ç½®å¹¶å†æ¬¡æ¢å¤ã€‚ 使用这ç§æ–¹æ³•ï¼Œæ‚¨å¯èƒ½ä¼šåœ¨åŠç§’å·¦å³çš„时间内关é—,如果需è¦ï¼Œå¯ä»¥è€ƒè™‘å‡å°‘计时器间隔以获得更高的分辨率(ä¸è¦å¿˜è®°è°ƒæ•´ä¹˜æ•°ï¼‰ã€‚
<å°æ—¶/> 修改强>FLAG_NO_CLEAR
å’ŒFLAG_ONGOING_EVENT
结åˆä½¿ç”¨ã€‚)