2016-11-15 8 views
0

[このチュートリアル](http://www.tutorialsface.com/2015/08/android-custom-notification-tutorial)通知に表示されたコントロールが終了しましたが、すべてが応答しません(作成者が含むトーストを表示する以外)。通知内の音楽コントロール

コントロールは音楽サービスにバインドされていないようです。私はブロードキャストの作成を試み、通知内から直接サービスを呼び出して、サービスの新しいインスタンスを作成しました。私はそれらのすべてを覚えることさえできないほど多くのことを試みました。私は人々が似たような質問をするのを見たことがあるが、私が試みたものは何も働かない今私は自分が「正しい道」にいると思ったときに私が混乱してしまったことをたくさん試しました。どのようにこれらのコントロールを適切に機能させるための任意のアイデアですか?

通知サービス:

public class NotificationService extends Service { 


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


@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN) 
@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 


    if (intent.getAction().equals(Constant.ACTION.STARTFOREGROUND_ACTION)) { 
     showNotification(); 
     Toast.makeText(this, "Service Started", Toast.LENGTH_SHORT).show(); 



    } else if (intent.getAction().equals(Constant.ACTION.PREV_ACTION)) { 
     Toast.makeText(this, "Clicked Previous", Toast.LENGTH_SHORT).show(); 
     Log.i("NS", "Clicked Previous"); 



    } else if (intent.getAction().equals(Constant.ACTION.PLAY_ACTION)) { 



     Log.i("NS", "Clicked Play"); 
    } else if (intent.getAction().equals(Constant.ACTION.NEXT_ACTION)) { 





     Toast.makeText(this, "Clicked Next", Toast.LENGTH_SHORT).show(); 
     Log.i("NS", "Clicked Next"); 
    } else if (intent.getAction().equals(
      Constant.ACTION.STOPFOREGROUND_ACTION)) { 
     Log.i("NS", "Received Stop Foreground Intent"); 
     Toast.makeText(this, "Service Stoped", Toast.LENGTH_SHORT).show(); 
     stopForeground(true); 
     stopSelf(); 
    } 
    return START_STICKY; 
} 

@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN) 
public void showNotification() { 

    Notification status; 

// Using RemoteViews to bind custom layouts into Notification 
     RemoteViews views = new RemoteViews(getPackageName(), 
       R.layout.status_bar); 
     RemoteViews bigViews = new RemoteViews(getPackageName(), 
       R.layout.status_bar_expanded); 

// showing default album image 
     views.setViewVisibility(R.id.status_bar_icon, View.VISIBLE); 
     views.setViewVisibility(R.id.status_bar_album_art, View.GONE); 
     bigViews.setImageViewBitmap(R.id.status_bar_album_art, 
       Constant.getDefaultAlbumArt(this)); 

     Intent notificationIntent = new Intent(this, NotificationService.class); 
     notificationIntent.setAction(Constant.ACTION.MAIN_ACTION); 
     notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 
       | Intent.FLAG_ACTIVITY_CLEAR_TASK); 
     PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, 
       notificationIntent, 0); 

     Intent previousIntent = new Intent(this, NotificationService.class); 
     previousIntent.setAction(Constant.ACTION.PREV_ACTION); 
     PendingIntent ppreviousIntent = PendingIntent.getService(this, 0, 
       previousIntent, 0); 

     Intent playIntent = new Intent(this, NotificationService.class); 
     playIntent.setAction(Constant.ACTION.PLAY_ACTION); 
     PendingIntent pplayIntent = PendingIntent.getService(this, 0, 
       playIntent, 0); 

     Intent nextIntent = new Intent(this, NotificationService.class); 
     nextIntent.setAction(Constant.ACTION.NEXT_ACTION); 
     PendingIntent pnextIntent = PendingIntent.getService(this, 0, 
       nextIntent, 0); 

     Intent closeIntent = new Intent(this, NotificationService.class); 
     closeIntent.setAction(Constant.ACTION.STOPFOREGROUND_ACTION); 
     PendingIntent pcloseIntent = PendingIntent.getService(this, 0, 
       closeIntent, 0); 

     views.setOnClickPendingIntent(R.id.status_bar_play, pplayIntent); 
     bigViews.setOnClickPendingIntent(R.id.status_bar_play, pplayIntent); 

     views.setOnClickPendingIntent(R.id.status_bar_next, pnextIntent); 
     bigViews.setOnClickPendingIntent(R.id.status_bar_next, pnextIntent); 

     views.setOnClickPendingIntent(R.id.status_bar_prev, ppreviousIntent); 
     bigViews.setOnClickPendingIntent(R.id.status_bar_prev, ppreviousIntent); 

     views.setOnClickPendingIntent(R.id.status_bar_collapse, pcloseIntent); 
     bigViews.setOnClickPendingIntent(R.id.status_bar_collapse, pcloseIntent); 

     views.setImageViewResource(R.id.status_bar_play, 
       R.drawable.apollo_holo_dark_pause); 
     bigViews.setImageViewResource(R.id.status_bar_play, 
       R.drawable.apollo_holo_dark_pause); 

     views.setTextViewText(R.id.status_bar_track_name, "Song Title"); 
     bigViews.setTextViewText(R.id.status_bar_track_name, "Song Title"); 

     views.setTextViewText(R.id.status_bar_artist_name, "Artist Name"); 
     bigViews.setTextViewText(R.id.status_bar_artist_name, "Artist Name"); 

     bigViews.setTextViewText(R.id.status_bar_album_name, "Album Name"); 

     status = new Notification.Builder(this).build(); 
     status.contentView = views; 
     status.bigContentView = bigViews; 
     status.flags = Notification.FLAG_ONGOING_EVENT; 
     status.icon = R.drawable.ic_launcher; 
     status.contentIntent = pendingIntent; 
     startForeground(Constant.NOTIFICATION_ID.FOREGROUND_SERVICE, status); 
    } 

} 

MusicService:

public class MusicService extends Service implements 
    MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener, 
    MediaPlayer.OnCompletionListener { 

//media player 
private MediaPlayer player; 
//song list 
private ArrayList<Song> songs; 
//current position 
private int songPosn; 
private final IBinder musicBind = new MusicBinder(); 
private String songTitle=""; 
private static final int NOTIFY_ID=1; 
private boolean shuffle=false; 
private Random rand; 

public void onCreate(){ 
    //create the service 
    super.onCreate(); 
    songPosn=0; 
    player = new MediaPlayer(); 

    initMusicPlayer(); 

    rand=new Random(); 
} 

public void initMusicPlayer(){ 
    //set player properties 
    player.setWakeMode(getApplicationContext(), 
      PowerManager.PARTIAL_WAKE_LOCK); 
    player.setAudioStreamType(AudioManager.STREAM_MUSIC); 

    player.setOnPreparedListener(this); 
    player.setOnCompletionListener(this); 
    player.setOnErrorListener(this); 
} 

public void setList(ArrayList<Song> theSongs){ 
    songs=theSongs; 
} 

public class MusicBinder extends Binder { 
    MusicService getService() { 
     return MusicService.this; 
    } 
} 

public void setShuffle(){ 
    if(shuffle) shuffle=false; 
    else shuffle=true; 
} 

public void playSong(){ 
    player.reset(); 
    //get song 
    Song playSong = songs.get(songPosn); 

//get id 
    long currSong = playSong.getID(); 
//set uri 
    Uri trackUri = ContentUris.withAppendedId(
      android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, 
      currSong); 

    try{ 
     player.setDataSource(getApplicationContext(), trackUri); 
    } 
    catch(Exception e){ 
     Log.e("MUSIC SERVICE", "Error setting data source", e); 
    } 

    player.prepareAsync(); 

    songTitle=playSong.getTitle(); 
} 

public void setSong(int songIndex){ 
    songPosn=songIndex; 
} 

public int getPosn(){ 
    return player.getCurrentPosition(); 
} 

public int getDur(){ 
    return player.getDuration(); 
} 

public boolean isPng(){ 
    return player.isPlaying(); 
} 

public void pausePlayer(){ 
    player.pause(); 
} 

public void seek(int posn){ 
    player.seekTo(posn); 
} 

public void go(){ 
    player.start(); 
} 

public void playPrev(){ 
    songPosn--; 
    if(songPosn<0) songPosn=songs.size()-1; 
    playSong(); 
} 

//skip to next 
public void playNext(){ 
    if(shuffle){ 
     int newSong = songPosn; 
     while(newSong==songPosn){ 
      newSong=rand.nextInt(songs.size()); 
     } 
     songPosn=newSong; 
    } 
    else{ 
     songPosn++; 
     if(songPosn>=songs.size()) songPosn=0; 
    } 
    playSong(); 
} 
@Override 
public void onDestroy() { 
    stopForeground(true); 
} 

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

@Override 
public boolean onUnbind(Intent intent){ 
    player.stop(); 
    player.release(); 
    return false; 
} 

@Override 
public void onCompletion(MediaPlayer mp) { 
    if(player.getCurrentPosition()>0){ 
     mp.reset(); 
     playNext(); 
    } 
} 

@Override 
public boolean onError(MediaPlayer mp, int what, int extra) { 
    mp.reset(); 
    return false; 
} 

@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN) 
@Override 
public void onPrepared(MediaPlayer mp) { 
    //start playback 
    mp.start(); 

    Intent onPreparedIntent = new Intent("MEDIA_PLAYER_PREPARED"); 
    LocalBroadcastManager.getInstance(this).sendBroadcast(onPreparedIntent); 


    Intent notIntent = new Intent(this, MusicPlayer.class); 
    notIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
    PendingIntent pendInt = PendingIntent.getActivity(this, 0, 
      notIntent, PendingIntent.FLAG_UPDATE_CURRENT); 

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

    builder.setContentIntent(pendInt) 
      .setSmallIcon(R.drawable.player_play) 
      .setTicker(songTitle) 
      .setOngoing(true) 
      .setContentTitle("Playing") 
    .setContentText(songTitle); 
    Notification not = builder.build(); 

    Intent serviceIntent = new Intent(MusicService.this, NotificationService.class); 
    serviceIntent.setAction(Constant.ACTION.STARTFOREGROUND_ACTION); 
    startService(serviceIntent); 
} 
} 

音楽プレーヤー:

public class MusicPlayer extends AppCompatActivity implements MediaPlayerControl { 

private ArrayList<Song> songList; 
private ListView songView; 
public MusicService musicSrv; 
private Intent playIntent; 
private boolean musicBound=false; 
private MusicController controller; 
private boolean paused=false, playbackPaused=false; 


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


    songView = (ListView)findViewById(R.id.song_list); 
    songList = new ArrayList<Song>(); 

    getSongList(); 

    Collections.sort(songList, new Comparator<Song>(){ 
     public int compare(Song a, Song b){ 
      return a.getArtist().compareTo(b.getArtist()); 
     } 
    }); 

    songAdapter songAdt = new songAdapter(this, songList); 
    songView.setAdapter(songAdt); 

    setController(); 

    FloatingActionButton fabRandom = (FloatingActionButton)findViewById(R.id.fabRandom); 
    fabRandom.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 

     } 
    }); 

} 

//play next 
private void playNext(){ 
    musicSrv.playNext(); 
    if(playbackPaused){ 
     setController(); 
     playbackPaused=false; 
    } 
    controller.show(0); 
} 

private void playPrev(){ 
    musicSrv.playPrev(); 
    if(playbackPaused){ 
     setController(); 
     playbackPaused=false; 
    } 
    controller.show(0); 
} 

public void songPicked(View view){ 
    musicSrv.setSong(Integer.parseInt(view.getTag().toString())); 
    musicSrv.playSong(); 
    if(playbackPaused){ 
     setController(); 
     playbackPaused=false; 
    } 
    setController(); 
    controller.show(0); 
} 
@Override 

protected void onPause(){ 
    super.onPause(); 
    paused=true; 
} 

@Override 
protected void onResume(){ 
    super.onResume(); 

    // Set up receiver for media player onPrepared broadcast 
    LocalBroadcastManager.getInstance(this).registerReceiver(onPrepareReceiver, 
      new IntentFilter("MEDIA_PLAYER_PREPARED")); 


    if(paused){ 
     setController(); 
     paused=false; 
    } 
} 

@Override 
protected void onStop() { 
    super.onStop(); 
} 

private void setController(){ 
    //set the controller up 


    if (controller == null) controller = new MusicController(this); 

     controller.invalidate(); 


    controller.setPrevNextListeners(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      playNext(); 
     } 
    }, new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      playPrev(); 
     } 
    }); 

    controller.setMediaPlayer(this); 
    controller.setAnchorView(findViewById(R.id.song_list)); 

} 

@Override 

public void onBackPressed() { 



    moveTaskToBack(true); 
    Intent intent = new Intent (getApplicationContext(), FitnessActivity.class); 
    startActivity(intent); 



} 


// Broadcast receiver to determine when music player has been prepared 
private BroadcastReceiver onPrepareReceiver = new BroadcastReceiver() { 
    @Override 
    public void onReceive(Context c, Intent i) { 
     // When music player has been prepared, show controller 
     controller.show(0); 
    } 
}; 

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

     musicSrv.playNext(); 

    } 
}; 

//connect to the service 
public ServiceConnection musicConnection = new ServiceConnection(){ 

    @Override 
    public void onServiceConnected(ComponentName name, IBinder service) { 
     MusicService.MusicBinder binder = (MusicService.MusicBinder)service; 
     //get service 
     musicSrv = binder.getService(); 
     //pass list 
     musicSrv.setList(songList); 
     musicBound = true; 
    } 

    @Override 
    public void onServiceDisconnected(ComponentName name) { 
     musicBound = false; 
    } 
}; 

@Override 
protected void onStart() { 
    super.onStart(); 
    if(playIntent==null){ 
     playIntent = new Intent(this, MusicService.class); 
     bindService(playIntent, musicConnection, Context.BIND_AUTO_CREATE); 
     startService(playIntent); 
     setController(); 
    } 
} 

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    switch (item.getItemId()) { 
     case R.id.action_shuffle: 
      musicSrv.setShuffle(); 
      break; 
     case R.id.action_end: 
      stopService(playIntent); 
      musicSrv=null; 
      System.exit(0); 
      break; 
    } 
    return super.onOptionsItemSelected(item); 
} 

@Override 
protected void onDestroy() { 
    stopService(playIntent); 
    musicSrv=null; 
    super.onDestroy(); 
} 

public void getSongList() { 
    //retrieve song info 
    ContentResolver musicResolver = getContentResolver(); 
    Uri musicUri = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; 
    Cursor musicCursor = musicResolver.query(musicUri, null, null, null, null); 

    if(musicCursor!=null && musicCursor.moveToFirst()){ 
     //get columns 
     int titleColumn = musicCursor.getColumnIndex 
       (android.provider.MediaStore.Audio.Media.TITLE); 
     int idColumn = musicCursor.getColumnIndex 
       (android.provider.MediaStore.Audio.Media._ID); 
     int artistColumn = musicCursor.getColumnIndex 
       (android.provider.MediaStore.Audio.Media.ARTIST); 
     int durationColumn = musicCursor.getColumnIndex 
       (MediaStore.Audio.Media.DURATION); 
     //add songs to list 


     do { 
      long thisId = musicCursor.getLong(idColumn); 
      String thisTitle = musicCursor.getString(titleColumn); 
      String thisArtist = musicCursor.getString(artistColumn); 
      long thisDuration = musicCursor.getLong(durationColumn); 
      if (thisDuration>10000){ 
      songList.add(new Song(thisId, thisTitle, thisArtist, thisDuration));} 
     } 
     while (musicCursor.moveToNext()); 
    } 
} 


@Override 
public void start() { 
    musicSrv.go(); 
} 

@Override 
public void pause() { 
    playbackPaused=true; 
    musicSrv.pausePlayer(); 
} 

@Override 
public int getDuration() { 
    if(musicSrv!=null && musicBound && musicSrv.isPng()) 
    return musicSrv.getDur(); 
    else return 0; 
} 

@Override 
public int getCurrentPosition() { 
    if(musicSrv!=null && musicBound && musicSrv.isPng()) 
    return musicSrv.getPosn(); 
    else return 0; 
} 

@Override 
public void seekTo(int pos) { 
    musicSrv.seek(pos); 
} 

@Override 
public boolean isPlaying() { 
    if(musicSrv!=null && musicBound) 
    return musicSrv.isPng(); 
    return false; 
} 

@Override 
public int getBufferPercentage() { 
    return 0; 
} 

@Override 
public boolean canPause() { 
    return true; 
} 

@Override 
public boolean canSeekBackward() { 
    return true; 
} 

@Override 
public boolean canSeekForward() { 
    return true; 
} 

@Override 
public int getAudioSessionId() { 
    return 0; 
} 

public void onNextNotification(){ 

} 
} 

マニフェスト:

<activity 
     android:name=".MusicPlayer" 
     <intent-filter> 
      <action android:name="android.intent.action.MAIN"/> 

      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 
    </activity> 
    <service android:name=".MusicService" 
     /> 
    <service android:name=".NotificationService" /> 
+0

onStartCommand()は呼び出されませんか?それとも、それは電話だが意図的ではない行動をしているのだろうかメソッド呼び出しを記録しようとします。 –

+0

呼び出されましたが、意図は何もしていないようです。実際のサービスに縛られていないようです。このチュートリアルでは、サービスはビューを使用してバインドされていると述べていますが、bigviewは推奨されていません。したがって、notifのコントロールは基本的には何もしません。 – Joe

答えて

0

通知サービスは、音楽サービスではなく、通知サービスによって受信されます。編集通知意図が音楽サービスへの音楽サービス

Intent playIntent = new Intent(this, MusicService.class); 
//... edit all of them 

移動onStartCommand()方法を対象とし、割り当てアクション

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

    if (intent.getAction().equals(Constant.ACTION.PLAY_ACTION)) { 
     //call play method 
    } 
//...etc 

STARTFOREGROUND_ACTIONSTOPFOREGROUND_ACTION除いて、通知サービスのonStartCommandでそれを残すために()。また、両方のサービスでインテントにヌルチェックを挿入します。

+0

Maxost - MusicServiceにonStartCommand()を移動すると、通知を表示するには通知に保持する必要はありませんか? サービスでif(intent.getAction()。equals(Constant.ACTION.PLAY_ACTION))を試すと、直ちにNULLポインタ例外がスローされます – Joe

+0

@Joe私の回答を更新しました –