/*
* Copyright (C) 2012 Andrew Neal Licensed under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law
* or agreed to in writing, software distributed under the License is
* distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
package com.andrew.apollo;
import java.lang.reflect.Field;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.widget.RemoteViews;
import com.bt.download.android.R;
import com.bt.download.android.util.SystemUtils;
/**
* Builds the notification for Apollo's service. Jelly Bean and higher uses the
* expanded notification by default.
*
* @author Andrew Neal (andrewdneal@gmail.com)
*/
public class NotificationHelper {
private static final String INTENT_AUDIO_PLAYER = "com.bt.download.android.AUDIO_PLAYER";
/**
* Notification ID
*/
private static final int APOLLO_MUSIC_SERVICE = 1;
/**
* NotificationManager
*/
private final NotificationManager mNotificationManager;
/**
* Context
*/
private final MusicPlaybackService mService;
/**
* Custom notification layout
*/
private RemoteViews mNotificationTemplate;
/**
* The Notification
*/
private Notification mNotification = null;
/**
* API 16+ bigContentView
*/
private RemoteViews mExpandedView;
/**
* Constructor of <code>NotificationHelper</code>
*
* @param service The {@link Context} to use
*/
public NotificationHelper(final MusicPlaybackService service) {
mService = service;
mNotificationManager = (NotificationManager) service.getSystemService(Context.NOTIFICATION_SERVICE);
}
/**
* Call this to build the {@link Notification}.
*/
public void buildNotification(final String albumName, final String artistName, final String trackName, final Long albumId, final Bitmap albumArt, final boolean isPlaying) {
// Default notification layout
mNotificationTemplate = new RemoteViews(mService.getPackageName(), R.layout.notification_template_base);
initCollapsedLayout(trackName, artistName, albumArt);
// Notification Builder
mNotification = new Notification.Builder(mService).setSmallIcon(R.drawable.frostwire_notification).setContentIntent(getPendingIntent()).setContent(mNotificationTemplate).getNotification();
// Control playback from the notification
initPlaybackActions(isPlaying);
if (SystemUtils.hasJellyBean()) {
// Expanded notifiction style
mExpandedView = new RemoteViews(mService.getPackageName(), R.layout.notification_template_expanded_base);
setBigContentView(mNotification, mExpandedView);
// Control playback from the notification
initExpandedPlaybackActions(isPlaying);
// Set up the expanded content view
initExpandedLayout(trackName, albumName, artistName, albumArt);
}
mService.startForeground(APOLLO_MUSIC_SERVICE, mNotification);
}
/**
* Remove notification
*/
public void killNotification() {
mService.stopForeground(true);
mNotification = null;
}
/**
* Changes the playback controls in and out of a paused state
*
* @param isPlaying True if music is playing, false otherwise
*/
public void updatePlayState(final boolean isPlaying) {
if (mNotification == null || mNotificationManager == null) {
return;
}
if (mNotificationTemplate != null) {
mNotificationTemplate.setImageViewResource(R.id.notification_base_play, isPlaying ? R.drawable.btn_notification_playback_pause : R.drawable.btn_notification_playback_play);
}
if (SystemUtils.hasJellyBean() && mExpandedView != null) {
mExpandedView.setImageViewResource(R.id.notification_expanded_base_play, isPlaying ? R.drawable.btn_notification_playback_pause : R.drawable.btn_notification_playback_play);
}
mNotificationManager.notify(APOLLO_MUSIC_SERVICE, mNotification);
}
/**
* Open to the now playing screen
*/
private PendingIntent getPendingIntent() {
return PendingIntent.getActivity(mService, 0, new Intent(INTENT_AUDIO_PLAYER).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK), 0);
}
/**
* Lets the buttons in the remote view control playback in the expanded
* layout
*/
private void initExpandedPlaybackActions(boolean isPlaying) {
// Play and pause
mExpandedView.setOnClickPendingIntent(R.id.notification_expanded_base_play, retreivePlaybackActions(1));
// Skip tracks
mExpandedView.setOnClickPendingIntent(R.id.notification_expanded_base_next, retreivePlaybackActions(2));
// Previous tracks
mExpandedView.setOnClickPendingIntent(R.id.notification_expanded_base_previous, retreivePlaybackActions(3));
// Stop and collapse the notification
mExpandedView.setOnClickPendingIntent(R.id.notification_expanded_base_collapse, retreivePlaybackActions(4));
// Update the play button image
mExpandedView.setImageViewResource(R.id.notification_expanded_base_play, isPlaying ? R.drawable.btn_notification_playback_pause : R.drawable.btn_notification_playback_play);
}
/**
* Lets the buttons in the remote view control playback in the normal layout
*/
private void initPlaybackActions(boolean isPlaying) {
// Play and pause
mNotificationTemplate.setOnClickPendingIntent(R.id.notification_base_play, retreivePlaybackActions(1));
// Skip tracks
mNotificationTemplate.setOnClickPendingIntent(R.id.notification_base_next, retreivePlaybackActions(2));
// Previous tracks
mNotificationTemplate.setOnClickPendingIntent(R.id.notification_base_previous, retreivePlaybackActions(3));
// Stop and collapse the notification
mNotificationTemplate.setOnClickPendingIntent(R.id.notification_base_collapse, retreivePlaybackActions(4));
// Update the play button image
mNotificationTemplate.setImageViewResource(R.id.notification_base_play, isPlaying ? R.drawable.btn_notification_playback_pause : R.drawable.btn_notification_playback_play);
}
/**
* @param which Which {@link PendingIntent} to return
* @return A {@link PendingIntent} ready to control playback
*/
private final PendingIntent retreivePlaybackActions(final int which) {
Intent action;
PendingIntent pendingIntent;
final ComponentName serviceName = new ComponentName(mService, MusicPlaybackService.class);
switch (which) {
case 1:
// Play and pause
action = new Intent(MusicPlaybackService.TOGGLEPAUSE_ACTION);
action.setComponent(serviceName);
pendingIntent = PendingIntent.getService(mService, 1, action, 0);
return pendingIntent;
case 2:
// Skip tracks
action = new Intent(MusicPlaybackService.NEXT_ACTION);
action.setComponent(serviceName);
pendingIntent = PendingIntent.getService(mService, 2, action, 0);
return pendingIntent;
case 3:
// Previous tracks
action = new Intent(MusicPlaybackService.PREVIOUS_ACTION);
action.setComponent(serviceName);
pendingIntent = PendingIntent.getService(mService, 3, action, 0);
return pendingIntent;
case 4:
// Stop and collapse the notification
action = new Intent(MusicPlaybackService.STOP_ACTION);
action.setComponent(serviceName);
pendingIntent = PendingIntent.getService(mService, 4, action, 0);
return pendingIntent;
default:
break;
}
return null;
}
/**
* Sets the track name, artist name, and album art in the normal layout
*/
private void initCollapsedLayout(final String trackName, final String artistName, final Bitmap albumArt) {
// Track name (line one)
mNotificationTemplate.setTextViewText(R.id.notification_base_line_one, trackName);
// Artist name (line two)
mNotificationTemplate.setTextViewText(R.id.notification_base_line_two, artistName);
// Album art
if (albumArt != null) {
mNotificationTemplate.setImageViewBitmap(R.id.notification_base_image, albumArt);
}
}
/**
* Sets the track name, album name, artist name, and album art in the
* expanded layout
*/
private void initExpandedLayout(final String trackName, final String artistName, final String albumName, final Bitmap albumArt) {
// Track name (line one)
mExpandedView.setTextViewText(R.id.notification_expanded_base_line_one, trackName);
// Album name (line two)
mExpandedView.setTextViewText(R.id.notification_expanded_base_line_two, albumName);
// Artist name (line three)
mExpandedView.setTextViewText(R.id.notification_expanded_base_line_three, artistName);
// Album art
if (albumArt != null) {
mExpandedView.setImageViewBitmap(R.id.notification_expanded_base_image, albumArt);
}
}
private static void setBigContentView(Notification notification, RemoteViews view) {
try {
Field f = Notification.class.getDeclaredField("bigContentView");
f.set(notification, view);
} catch (Throwable e) {
// unable to set the big view version
}
}
}