1

У меня есть служба, которая передается набор переменных (песня, альбом исполнителя и т. Д.) И включает в себя MediaPlayer и множество методов для этого MediaPlayer (воспроизведение следующий, предыдущий и т. д.).Передача переменных между сервисом и действиями и наоборот

У меня также есть активность, которая отображает пользовательский интерфейс пользователя, включая следующие/предыдущие кнопки, Seekbar и отображение исполнителя/альбома/песни.

То, что я хотел бы знать, как получить активность пользовательского интерфейса, чтобы внести изменения в сервис, а сервис для обновления активности в зависимости от выбранной песни ..

Например: художник/композиция альбома/песни отправляется на службу. Служба сообщает MediaPlayer, чтобы начать воспроизведение этой песни. Название композиции/альбом/исполнитель отображается в действии, и пользователь может нажать воспроизведение/паузу и т. Д. В пользовательском интерфейсе. При щелчке служба будет действовать соответствующим образом.

Я не знаю, как все это происходит, и я догоняю трансляции, намерения и статику. Я бы очень признателен за четкое руководство и хороший пример того, как это можно сделать ,

Благодарим за ваше терпение. & help.

Вы можете найти код ниже:

MusicService.java:

package awesome.music.player; 

import java.io.IOException; 
import java.util.ArrayList; 

import android.app.Service; 
import android.content.BroadcastReceiver; 
import android.content.ContentUris; 
import android.content.Context; 
import android.content.Intent; 
import android.content.IntentFilter; 
import android.media.MediaPlayer; 
import android.media.MediaPlayer.OnCompletionListener; 
import android.media.MediaPlayer.OnSeekCompleteListener; 
import android.net.Uri; 
import android.os.Bundle; 
import android.os.Handler; 
import android.os.IBinder; 

public class MusicService extends Service implements OnCompletionListener, 
     OnSeekCompleteListener { 

    Intent intent; 

    MediaPlayer mediaPlayer = new MediaPlayer(); 

    String isComplete; 
    String serviceStatus; 
    String sntSeekPos; 
    String artist; 
    String selection; 
    String album; 
    String numSongs; 
    int albumId; 
    String currentSongPath; 

    String[] selectionArgs; 

    Uri currentSongUri; 

    int songEnded; 
    int currentSongIndex; 
    int totalSongDuration; 

    int intSeekPos; 
    int mediaPosition; 
    int mediaMax; 

    ArrayList<String> pathList; 
    ArrayList<String> artistList; 
    ArrayList<String> albumList; 
    ArrayList<String> titleList; 
    ArrayList<String> idList; 
    ArrayList<String> durationList; 

    private final Handler handler = new Handler(); 

    public final String BROADCAST_ACTION = "awesome.music.player.seekprogress"; 
    public final String BROADCAST_OTHER = "awesome.music.player.displaysong"; 
    Intent seekIntent; 
    Intent displayIntent; 
    Utilities utils; 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     this.intent = intent; 

     Bundle extras = intent.getExtras(); 

     artist = extras.getString("artist"); 
     selection = extras.getString("selection"); 
     selectionArgs = extras.getStringArray("selectionArgs"); 
     album = extras.getString("album"); 
     albumId = extras.getInt("albumId"); 
     numSongs = extras.getString("numSongs"); 
     currentSongIndex = extras.getInt("currentSongIndex"); 
     currentSongPath = extras.getString("currentSongPath"); 
     totalSongDuration = extras.getInt("totalSongDuration"); 

     pathList = extras.getStringArrayList("pathList"); 
     artistList = extras.getStringArrayList("artistList"); 
     albumList = extras.getStringArrayList("albumList"); 
     titleList = extras.getStringArrayList("titleList"); 
     idList = extras.getStringArrayList("idList"); 
     durationList = extras.getStringArrayList("durationList"); 

     prepareSong(currentSongPath); 
     playSong(); 
     displaySong(); 
     utils = new Utilities(); 
     seekIntent = new Intent(BROADCAST_ACTION); 
     displayIntent = new Intent(BROADCAST_ACTION); 
     setupHandler(); 

     return START_STICKY; 

    } 

    /* 
    * @Override public void onCreate() { super.onCreate(); 
    * 
    * utils = new Utilities(); 
    * 
    * seekIntent = new Intent(BROADCAST_ACTION); 
    * 
    * setupHandler(); 
    * 
    * prepareSong(currentSongPath); playSong(); } 
    */ 

    public void prepareSong(String currentSongPath) { 
     try { 
      mediaPlayer.reset(); 
      mediaPlayer.setDataSource(currentSongPath); 
      mediaPlayer.prepare(); 

     } catch (IllegalArgumentException e) { 
      e.printStackTrace(); 
     } catch (IllegalStateException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

    } 

    public void playSong() { 

     try { 
      mediaPlayer.start(); 

     } catch (IllegalArgumentException e) { 
      e.printStackTrace(); 
     } catch (IllegalStateException e) { 
      e.printStackTrace(); 
     } 

    } 

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

    public void onCompletion(MediaPlayer mediaPlayer) { 
     playNext(); 

    } 

    @Override 
    public void onStart(Intent intent, int startId) { 

     registerReceiver(broadcastReceiver, new IntentFilter(
       MusicPlayer.BROADCAST_SEEKBAR)); 
     super.onCreate(); 
     prepareSong(currentSongPath); 
     playSong(); 
    } 

    private void setupHandler() { 
     handler.removeCallbacks(sendUpdatesToUI); 
     handler.postDelayed(sendUpdatesToUI, 1000); 

    } 

    private Runnable sendUpdatesToUI = new Runnable() { 
     public void run() { 

      LogMediaPosition(); 

      handler.postDelayed(this, 1000); 

     } 

    }; 

    private void LogMediaPosition() { 
     if (mediaPlayer.isPlaying()) { 
      mediaPosition = mediaPlayer.getCurrentPosition(); 

      MusicPlayer.currentDurationLabel.setText("" 
        + utils.milliSecondsToTimer(mediaPosition)); 

      mediaMax = mediaPlayer.getDuration(); 
      seekIntent.putExtra("counter", String.valueOf(mediaPosition)); 
      seekIntent.putExtra("mediamax", String.valueOf(mediaMax)); 
      seekIntent.putExtra("song_ended", String.valueOf(songEnded)); 
      sendBroadcast(seekIntent); 
     } 
    } 

    private void displaySong() { 

     utils = new Utilities(); 

     String title = titleList.get(currentSongIndex); 
     String artist = artistList.get(currentSongIndex); 
     String album = albumList.get(currentSongIndex); 

     Uri sArtworkUri = Uri.parse("content://media/external/audio/albumart"); 

     Uri currentSongUri = ContentUris.withAppendedId(sArtworkUri, albumId); 

     String totalDuration = utils.milliSecondsToTimer(totalSongDuration); 

     mediaPosition = mediaPlayer.getCurrentPosition(); 

     MusicPlayer.currentDurationLabel.setText("" 
       + utils.milliSecondsToTimer(mediaPosition)); 

     displayIntent.putExtra("title", title); 
     displayIntent.putExtra("artist", artist); 
     displayIntent.putExtra("album", album); 
     displayIntent.putExtra("totalDuration", totalDuration); 
     displayIntent.putExtra("currentSongUri", currentSongUri); 
     sendBroadcast(displayIntent); 

    } 

    // receive seekbar position 

    private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { 
     @Override 
     public void onReceive(Context context, Intent intent) { 
      updateSeekPos(intent); 

     } 
    }; 

    // Update seek position from Activity 
    public void updateSeekPos(Intent intent) { 
     int seekPos = intent.getIntExtra("seekpos", 0); 
     if (mediaPlayer.isPlaying()) { 
      handler.removeCallbacks(sendUpdatesToUI); 
      mediaPlayer.seekTo(seekPos); 
      setupHandler(); 

     } 
    } 

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
     mediaPlayer.stop(); 
     handler.removeCallbacks(sendUpdatesToUI); 
     // Unregister seek receiver 
     unregisterReceiver(broadcastReceiver); 
    } 

    public void onSeekComplete(MediaPlayer mediaPlayer) { 
     if (!mediaPlayer.isPlaying()) { 
      mediaPlayer.start(); 
     } 

    } 

    public void playNext() { 

     if (mediaPlayer.isPlaying()) { 

      if (currentSongIndex < (pathList.size() - 1)) { 
       currentSongIndex = currentSongIndex + 1; 
       currentSongPath = pathList.get(currentSongIndex); 

       prepareSong(currentSongPath); 
       playSong(); 
      } else { 
       currentSongIndex = 0; 
       currentSongPath = pathList.get(currentSongIndex); 
       prepareSong(currentSongPath); 
       playSong(); 
      } 
     } else { 
      if (currentSongIndex < (pathList.size() - 1)) { 
       currentSongIndex = currentSongIndex + 1; 
       currentSongPath = pathList.get(currentSongIndex); 

       prepareSong(currentSongPath); 
      } else { 
       currentSongIndex = 0; 
       prepareSong(currentSongPath); 
      } 
     } 

     displaySong(); 
    } 

    void playPrevious() { 

     if (mediaPlayer.isPlaying()) { 

      if (currentSongIndex > 0) { 
       currentSongIndex = currentSongIndex - 1; 
       currentSongPath = pathList.get(currentSongIndex); 

       prepareSong(currentSongPath); 
       playSong(); 
      } else { 
       currentSongIndex = pathList.size() - 1; 
       currentSongPath = pathList.get(currentSongIndex); 

       prepareSong(currentSongPath); 
       playSong(); 
      } 
     } else { 
      if (currentSongIndex > 0) { 
       currentSongIndex = currentSongIndex - 1; 
       currentSongPath = pathList.get(Playlist.currentSongIndex); 

       prepareSong(currentSongPath); 
      } else { 
       currentSongIndex = pathList.size() - 1; 
       currentSongPath = pathList.get(currentSongIndex); 

       prepareSong(currentSongPath); 
      } 
     } 
     displaySong(); 
    } 

} 

MusicPlayer.java:

package awesome.music.player; 

import android.app.Activity; 
import android.content.BroadcastReceiver; 
import android.content.Context; 
import android.content.Intent; 
import android.content.IntentFilter; 
import android.os.Bundle; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.ImageButton; 
import android.widget.ImageView; 
import android.widget.SeekBar; 
import android.widget.SeekBar.OnSeekBarChangeListener; 
import android.widget.TextView; 

public class MusicPlayer extends Activity implements OnSeekBarChangeListener { 

    public ImageButton play; 
    public ImageButton next; 
    public ImageButton previous; 

    public static ImageView albumArt; 

    static TextView songArtistAlbumLabel; 
    static TextView songTitleLabel; 
    static TextView currentDurationLabel; 
    static TextView totalDurationLabel; 

    static String serviceStatus; 

    private SeekBar seekBar; 

    private int seekMax; 

    boolean mBroadcastIsRegistered; 

    public static Utilities utils; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.playing); 

     play = (ImageButton) findViewById(R.id.playButton); 
     next = (ImageButton) findViewById(R.id.nextButton); 
     previous = (ImageButton) findViewById(R.id.previousButton); 
     albumArt = (ImageView) findViewById(R.id.imageView1); 

     songArtistAlbumLabel = (TextView) findViewById(R.id.songArtistAlbumLabel); 
     songTitleLabel = (TextView) findViewById(R.id.songTitleLabel); 
     totalDurationLabel = (TextView) findViewById(R.id.totalDurationLabel); 
     songArtistAlbumLabel = (TextView) findViewById(R.id.songArtistAlbumLabel); 

     play.setOnClickListener(playListener); 
     next.setOnClickListener(nextListener); 
     previous.setOnClickListener(previousListener); 

     seekBar = (SeekBar) findViewById(R.id.seekBar); 
     seekBar.setOnSeekBarChangeListener(this); 

     intent = new Intent(BROADCAST_SEEKBAR); 

     if (mBroadcastIsRegistered != true) { 
      registerReceiver(broadcastReceiver, new IntentFilter(
        MusicService.BROADCAST_ACTION)); 
      ; 

      mBroadcastIsRegistered = true; 
     } 

    } 

    private OnClickListener playListener = new OnClickListener() { 
     public void onClick(View v) { 
      MusicService.playSong(); 

     } 
    }; 

    private OnClickListener nextListener = new OnClickListener() { 
     public void onClick(View v) { 
      MusicService.playNext(); 
     } 
    }; 

    private OnClickListener previousListener = new OnClickListener() { 
     public void onClick(View v) { 
      MusicService.playPrevious(); 
     } 
    }; 

    public static final String BROADCAST_SEEKBAR = "awesome.music.player.sendseekbar"; 
    Intent intent; 

    private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { 
     @Override 
     public void onReceive(Context context, Intent serviceIntent) { 
      updateUI(serviceIntent); 
     } 
    }; 

    private void updateUI(Intent serviceIntent) { 
     String counter = serviceIntent.getStringExtra("counter"); 
     String mediamax = serviceIntent.getStringExtra("mediamax"); 
     String strSongEnded = serviceIntent.getStringExtra("song_ended"); 
     int seekProgress = Integer.parseInt(counter); 
     seekMax = Integer.parseInt(mediamax); 
     Integer.parseInt(strSongEnded); 
     seekBar.setMax(seekMax); 
     seekBar.setProgress(seekProgress); 
    } 

    public void onProgressChanged(SeekBar seekBar, int progress, 
      boolean fromUser) { 
     if (fromUser) { 
      int seekPos = seekBar.getProgress(); 
      intent.putExtra("seekpos", seekPos); 
      sendBroadcast(intent); 
     } 

    } 

    public void onStartTrackingTouch(SeekBar seekBar) { 
     // TODO Auto-generated method stub 

    } 

    public void onStopTrackingTouch(SeekBar seekBar) { 
     // TODO Auto-generated method stub 

    } 

} 

playing.xml:

<?xml version="1.0" encoding="utf-8"?> 
<AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" > 

    <SeekBar 
     android:id="@+id/seekBar" 
     android:layout_width="296dp" 
     android:layout_height="wrap_content" 
     android:layout_marginBottom="20dp" 
     android:layout_marginLeft="20dp" 
     android:layout_marginRight="20dp" 
     android:layout_x="10dp" 
     android:layout_y="446dp" 
     android:paddingLeft="6dp" 
     android:paddingRight="6dp" 
     android:progressDrawable="@drawable/seekbar_progress" 
     android:thumb="@drawable/seek_handler" /> 

    <ImageView 
     android:id="@+id/imageView2" 
     android:layout_width="37dp" 
     android:layout_height="37dp" 
     android:layout_x="6dp" 
     android:layout_y="397dp" 
     android:src="@drawable/ic_tab_albums_white" /> 

    <TextView 
     android:id="@+id/songTitleLabel" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_x="55dp" 
     android:layout_y="395dp" 
     android:text="Song Label" 
     android:textSize="20sp" /> 

    <TextView 
     android:id="@+id/songArtistAlbumLabel" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_x="55dp" 
     android:layout_y="417dp" 
     android:text="Artist - Album Label" 
     android:textSize="15sp" /> 

    <TextView 
     android:id="@+id/currentDurationLabel" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_x="10dp" 
     android:layout_y="481dp" 
     android:text="0:00" /> 

    <TextView 
     android:id="@+id/totalDurationLabel" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_x="281dp" 
     android:layout_y="477dp" 
     android:text="3:30" /> 

    <LinearLayout 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_x="41dp" 
     android:layout_y="312dp" 
     android:gravity="center_horizontal" > 

     <ImageButton 
      android:id="@+id/previousButton" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_x="132dp" 
      android:layout_y="308dp" 
      android:src="@drawable/ic_previous" /> 

     <ImageButton 
      android:id="@+id/playButton" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_marginLeft="50sp" 
      android:layout_marginRight="50sp" 
      android:src="@drawable/ic_pause" /> 

     <ImageButton 
      android:id="@+id/nextButton" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:src="@drawable/ic_next" /> 
    </LinearLayout> 

    <ImageView 
     android:id="@+id/imageView1" 
     android:layout_width="287dp" 
     android:layout_height="272dp" 
     android:layout_x="16dp" 
     android:layout_y="13dp" 
     android:background="@drawable/dummy_album_art" 
     android:scaleType="fitXY" /> 

</AbsoluteLayout> 

ответ

2

в целом там три основных способа commnicate службами

1-Binder (в привязки службы) 2-посланцев 3-AIDL

На Android, один процесс не может нормально доступа к памяти другого процесса. Поэтому, чтобы говорить, им нужно разложить свои объекты на примитивы, которые операционная система может понимать и маршаллировать объекты по этой границе для вас. Код для этого marshalling - это утомительно писать, поэтому Android обрабатывает его для вас с помощью AIDL.

Using AIDL is necessary only if 

1- вы позволяете клиентам из различных приложений, чтобы получить доступ к вашим услугам для IPC 2- вы хотите обрабатывать многопоточности в службе. Если вам не нужно выполнять параллельную IPC в различных приложениях,

Using Binder 

вы должны создать свой интерфейс, реализовав подшивку или, если вы хотите выполнить IPC, но не нужен

Using Messenger 

для обработки многопоточности, реализовать свой интерфейс с помощью Messenger.

http://developer.android.com/guide/developing/tools/aidl.html

http://java.dzone.com/articles/android-aidl-and-remote-client

другой, то это может использовать

1- Broadcasting умысел службы

2 -

+0

Спасибо за ваши комментарии. Это много, чтобы спросить, но мне бы хотелось посмотреть, как вы примените «Binder» к этому конкретному приложению. –

+0

yes В общем случае служба привязки запускается до активации запуска компонентов и в вашей службе приложений выглядит так, что она должна запускаться даже после приложения закрыт ... но я думаю, что есть способ использовать службу связи даже в этом случае ... –

+0

Мне нравится идея использования трансляции, но я чувствую, что мне нужно другое намерение для каждого действия, в котором действие влияет службы и наоборот. –

1
  1. Вы должны сделать услугу воспроизведения, который начинается, когда вы можете запустить наш сервис из класса, расширяющего приложение.

  2. Вы можете использовать helpl для связи службы с активностью. Поскольку деятельность уже запущена, не может быть убита, когда действие прекратится.

  3. Вы можете использовать Mediastore распознаватель контента, чтобы получить данные о треках там художников альбомы и т.д ..

MediaStore.Audio.Media. * Столбцы вы хотите предоставить все данные, а также путь к песне

4.I утра и в настоящее время в процессе строительства плеера ....... но все это работает, как я использую его

Смежные вопросы