使用动æ€â€œæ—¶é—´â€å€¼

时间:2015-08-21 01:11:55

标签: java

在Google Play:

上查看我的应用
  

代ç å·²æ›´æ–°ä¸ºä½¿ç”¨ç­”案æ供的建议,但ä»ç„¶é‡åˆ°ä¸€äº›é—®é¢˜......

我在æœåŠ¡ä¸­ä½¿ç”¨BroadCast Receiver从Spotify(外部应用程åºï¼‰èŽ·å–元数æ®ã€‚但是,Spotify的独特之处在于它å‘é€äº†ä»¥ä¸‹æ„图æ“作:

  1. metadatachanged ,其中包å«æ­Œæ›²çš„艺术家,曲目,长度等。
  2. playbackstatechanged ,其中包å«â€œæ’­æ”¾â€çš„布尔值和歌曲中当å‰ä½ç½®çš„整数值。
  3. 但是,我é‡åˆ°äº†ä¸€äº›é—®é¢˜ã€‚我写了以下代ç ï¼š

    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,以便更新当å‰æ’­æ”¾æ—¶é—´ã€‚

    所以我的问题是,如何让我当å‰çš„播放时间ä¿æŒæœ€æ–°ï¼Œä»¥ä¾¿æˆ‘çš„é™éŸ³åŠŸèƒ½èƒ½å¤Ÿæ­£å¸¸å·¥ä½œï¼Ÿæœ‰æ²¡æœ‰åŠžæ³•å¯ä»¥å®žçŽ°ä¸€ç§â€œå®šæ—¶å™¨â€ï¼Œå®ƒåœ¨æˆ‘收到当å‰æ’­æ”¾æ—¶é—´çš„值åŽå¼€å§‹æ’­æ”¾ï¼Œç„¶åŽå¢žåŠ æ—¶é—´ç›´åˆ°ä¸‹ä¸€æ¬¡æ›´æ–°ï¼Ÿ

1 个答案:

答案 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");


    }

}

基本上,计时器æ¯ç§’è¿è¡Œä¸€æ¬¡ï¼ˆä»Žå¹¿å‘Šæ’­æ”¾å®Œæ¯•å¼€å§‹ï¼‰ï¼Œç„¶åŽåªè¦æ­Œæ›²æ²¡æœ‰æš‚åœå°±é€’增计数器。在到达歌曲结æŸæ—¶ï¼Œè®¡æ—¶å™¨æš‚åœï¼Œå› ä¸ºä¸‹ä¸€ä¸ªå¹¿å‘Šå°†æ’­æ”¾ã€‚广告播放完毕åŽï¼Œè®¡æ—¶å™¨å°†é‡ç½®å¹¶å†æ¬¡æ¢å¤ã€‚ 使用这ç§æ–¹æ³•ï¼Œæ‚¨å¯èƒ½ä¼šåœ¨åŠç§’å·¦å³çš„时间内关闭,如果需è¦ï¼Œå¯ä»¥è€ƒè™‘å‡å°‘计时器间隔以获得更高的分辨率(ä¸è¦å¿˜è®°è°ƒæ•´ä¹˜æ•°ï¼‰ã€‚

<å°æ—¶/> 修改
上é¢çš„代ç æ²¡æœ‰æ³¨æ„到用户改å˜äº†æ›²ç›®ä¸­æ®µæ­Œæ›²ï¼Œå› ä¸ºåœ¨é‚£ç§æƒ…况下没有å‘é€å¹¿æ’­ã€‚解决方法å¯èƒ½æ˜¯ä½¿ç”¨notifications添加é™éŸ³æŒ‰é’®ï¼ˆä¾‹å¦‚,与FLAG_NO_CLEARå’ŒFLAG_ONGOING_EVENT结åˆä½¿ç”¨ã€‚)