Switch to appcompat notifications

I really liked our own notification styles, but on Android 11, it just starts to look very alien.
This commit is contained in:
Adrian Ulrich 2021-03-03 08:54:23 +01:00
parent 20ea9226b5
commit 7e870fe9e5
20 changed files with 31 additions and 569 deletions

View File

@ -27,6 +27,7 @@ android {
dependencies {
implementation 'androidx.legacy:legacy-support-core-ui:1.0.0'
implementation 'androidx.media:media:1.2.1'
implementation 'com.google.android.material:material:1.0.0'
implementation 'junit:junit:4.12'
compileOnly 'androidx.annotation:annotation:1.0.0'

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2017 Adrian Ulrich <adrian@blinkenlights.ch>
* Copyright (C) 2017-2021 Adrian Ulrich <adrian@blinkenlights.ch>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -21,7 +21,10 @@ import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Build;
import androidx.core.app.NotificationCompat;
public class NotificationHelper {
/**
@ -51,27 +54,12 @@ public class NotificationHelper {
}
/**
* Returns a new Notification.Builder.
* Returns a new NotificationCompat.Builder.
*
* @param context the context to use
*/
public Notification.Builder getNewBuilder(Context context) {
Notification.Builder builder;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
builder = new Notification.Builder(context, mChannelId);
} else {
builder = new Notification.Builder(context);
}
return builder;
}
/**
* Retruns a new Notification.
*
* @param context the context to use.
*/
public Notification getNewNotification(Context context) {
return getNewBuilder(context).getNotification(); // build() is API16.
public NotificationCompat.Builder getNewBuilder(Context context) {
return new NotificationCompat.Builder(context, mChannelId);
}
/**

View File

@ -57,8 +57,8 @@ import android.os.Process;
import android.os.SystemClock;
import android.util.Log;
import android.view.View;
import android.widget.RemoteViews;
import android.widget.Toast;
import androidx.core.app.NotificationCompat;
import java.lang.Math;
import java.io.DataInputStream;
import java.io.DataOutputStream;
@ -178,10 +178,6 @@ public final class PlaybackService extends Service
* Change the repeat mode.
*/
public static final String ACTION_CYCLE_REPEAT = "ch.blinkenlights.android.vanilla.CYCLE_REPEAT";
/**
* Pause music and hide the notification.
*/
public static final String ACTION_CLOSE_NOTIFICATION = "ch.blinkenlights.android.vanilla.CLOSE_NOTIFICATION";
/**
* Whether we should create a foreground notification as early as possible.
*/
@ -309,10 +305,6 @@ public final class PlaybackService extends Service
* Behaviour of the notification
*/
private int mNotificationVisibility;
/**
* If true, create a notification with ticker text or heads up display
*/
private boolean mNotificationNag;
/**
* If true, audio will not be played through the speaker.
*/
@ -463,7 +455,6 @@ public final class PlaybackService extends Service
SharedPreferences settings = SharedPrefHelper.getSettings(this);
settings.registerOnSharedPreferenceChangeListener(this);
mNotificationVisibility = Integer.parseInt(settings.getString(PrefKeys.NOTIFICATION_VISIBILITY, PrefDefaults.NOTIFICATION_VISIBILITY));
mNotificationNag = settings.getBoolean(PrefKeys.NOTIFICATION_NAG, PrefDefaults.NOTIFICATION_NAG);
mScrobble = settings.getBoolean(PrefKeys.SCROBBLE, PrefDefaults.SCROBBLE);
mIdleTimeout = settings.getBoolean(PrefKeys.USE_IDLE_TIMEOUT, PrefDefaults.USE_IDLE_TIMEOUT) ? settings.getInt(PrefKeys.IDLE_TIMEOUT, PrefDefaults.IDLE_TIMEOUT) : 0;
@ -607,11 +598,6 @@ public final class PlaybackService extends Service
// Flush the queue and start playing:
query.mode = SongTimeline.MODE_PLAY;
addSongs(query);
} else if (ACTION_CLOSE_NOTIFICATION.equals(action)) {
mForceNotificationVisible = false;
pause();
stopForeground(true); // sometimes required to clear notification
updateNotification();
}
}
@ -890,9 +876,6 @@ public final class PlaybackService extends Service
// mode.
stopForeground(true);
updateNotification();
} else if (PrefKeys.NOTIFICATION_NAG.equals(key)) {
mNotificationNag = settings.getBoolean(PrefKeys.NOTIFICATION_NAG, PrefDefaults.NOTIFICATION_NAG);
// no need to update notification: happens on next event
} else if (PrefKeys.SCROBBLE.equals(key)) {
mScrobble = settings.getBoolean(PrefKeys.SCROBBLE, PrefDefaults.SCROBBLE);
} else if (PrefKeys.MEDIA_BUTTON.equals(key) || PrefKeys.MEDIA_BUTTON_BEEP.equals(key)) {
@ -2143,81 +2126,38 @@ public final class PlaybackService extends Service
*/
public Notification createNotification(Song song, int state, int mode)
{
boolean playing = (state & FLAG_PLAYING) != 0;
RemoteViews views = new RemoteViews(getPackageName(), R.layout.notification);
RemoteViews expanded = new RemoteViews(getPackageName(), R.layout.notification_expanded);
Bitmap cover = song.getCover(this);
if (cover == null) {
views.setImageViewResource(R.id.cover, R.drawable.fallback_cover);
expanded.setImageViewResource(R.id.cover, R.drawable.fallback_cover_large);
} else {
views.setImageViewBitmap(R.id.cover, cover);
expanded.setImageViewBitmap(R.id.cover, cover);
}
int playButton = ThemeHelper.getPlayButtonResource(playing);
views.setImageViewResource(R.id.play_pause, playButton);
expanded.setImageViewResource(R.id.play_pause, playButton);
final boolean playing = (state & FLAG_PLAYING) != 0;
final Bitmap cover = song.getCover(this);
ComponentName service = new ComponentName(this, PlaybackService.class);
Intent previous = new Intent(PlaybackService.ACTION_PREVIOUS_SONG);
previous.setComponent(service);
views.setOnClickPendingIntent(R.id.previous, PendingIntent.getService(this, 0, previous, 0));
expanded.setOnClickPendingIntent(R.id.previous, PendingIntent.getService(this, 0, previous, 0));
int playButton = ThemeHelper.getPlayButtonResource(playing);
Intent playPause = new Intent(PlaybackService.ACTION_TOGGLE_PLAYBACK_NOTIFICATION);
playPause.setComponent(service);
views.setOnClickPendingIntent(R.id.play_pause, PendingIntent.getService(this, 0, playPause, 0));
expanded.setOnClickPendingIntent(R.id.play_pause, PendingIntent.getService(this, 0, playPause, 0));
Intent next = new Intent(PlaybackService.ACTION_NEXT_SONG);
next.setComponent(service);
views.setOnClickPendingIntent(R.id.next, PendingIntent.getService(this, 0, next, 0));
expanded.setOnClickPendingIntent(R.id.next, PendingIntent.getService(this, 0, next, 0));
int closeButtonVisibility = (mode == VISIBILITY_WHEN_PLAYING) ? View.VISIBLE : View.INVISIBLE;
Intent close = new Intent(PlaybackService.ACTION_CLOSE_NOTIFICATION);
close.setComponent(service);
views.setOnClickPendingIntent(R.id.close, PendingIntent.getService(this, 0, close, 0));
views.setViewVisibility(R.id.close, closeButtonVisibility);
expanded.setOnClickPendingIntent(R.id.close, PendingIntent.getService(this, 0, close, 0));
expanded.setViewVisibility(R.id.close, closeButtonVisibility);
Intent previous = new Intent(PlaybackService.ACTION_PREVIOUS_SONG);
previous.setComponent(service);
views.setTextViewText(R.id.title, song.title);
views.setTextViewText(R.id.artist, song.artist);
expanded.setTextViewText(R.id.title, song.title);
expanded.setTextViewText(R.id.album, song.album);
expanded.setTextViewText(R.id.artist, song.artist);
Notification notification = mNotificationHelper.getNewNotification(getApplicationContext());
notification.contentView = views;
notification.icon = R.drawable.status_icon;
notification.flags |= Notification.FLAG_ONGOING_EVENT;
notification.contentIntent = mNotificationAction;
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
// expanded view is available since 4.1
notification.bigContentView = expanded;
// 4.1 also knows about notification priorities
// HIGH is one higher than the default.
notification.priority = Notification.PRIORITY_HIGH;
}
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
notification.visibility = Notification.VISIBILITY_PUBLIC;
}
if(mNotificationNag) {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
notification.priority = Notification.PRIORITY_MAX;
notification.vibrate = new long[0]; // needed to get headsup
} else {
notification.tickerText = song.title + " - " + song.artist;
}
}
return notification;
Notification n = mNotificationHelper.getNewBuilder(getApplicationContext())
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setSmallIcon(R.drawable.status_icon)
.setLargeIcon(cover)
.setContentTitle(song.title)
.setContentText(song.album)
.setSubText(song.artist)
.setContentIntent(mNotificationAction)
.addAction(new NotificationCompat.Action(R.drawable.previous,
getString(R.string.previous_song), PendingIntent.getService(this, 0, previous, 0)))
.addAction(new NotificationCompat.Action(playButton,
getString(R.string.play_pause), PendingIntent.getService(this, 0, playPause, 0)))
.addAction(new NotificationCompat.Action(R.drawable.next,
getString(R.string.next_song), PendingIntent.getService(this, 0, next, 0)))
.setStyle(new androidx.media.app.NotificationCompat.MediaStyle())
.build();
return n;
}
public void onAudioFocusChange(int type)

View File

@ -52,7 +52,6 @@ public class PrefKeys {
public static final String MEDIA_BUTTON_BEEP = "media_button_beep";
public static final String NOTIFICATION_ACTION = "notification_action";
public static final String NOTIFICATION_VISIBILITY = "notification_visibility";
public static final String NOTIFICATION_NAG = "notification_nag";
public static final String PLAYBACK_ON_STARTUP = "playback_on_startup";
public static final String SCROBBLE = "scrobble";
public static final String SHAKE_ACTION = "shake_action";

Binary file not shown.

Before

Width:  |  Height:  |  Size: 251 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 500 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 166 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 369 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 305 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 687 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 883 B

View File

@ -1,99 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2012 Christopher Eby <kreed@kreed.org>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="64dp"
android:orientation="horizontal"
>
<ImageView
android:id="@+id/cover"
android:scaleType="centerCrop"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_marginRight="8dp"
android:contentDescription="@string/cover_art" />
<LinearLayout
android:layout_width="0px"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="center"
android:orientation="vertical">
<TextView
android:id="@+id/title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textAppearance="@android:style/TextAppearance.Material.Notification.Title"
android:singleLine="true"
android:ellipsize="marquee" />
<TextView
android:id="@+id/artist"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textAppearance="@android:style/TextAppearance.Material.Notification.Line2"
android:singleLine="true"
android:ellipsize="marquee" />
</LinearLayout>
<ImageButton
android:id="@+id/previous"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:layout_height="42dp"
android:layout_width="wrap_content"
android:layout_gravity="center"
android:background="?android:attr/selectableItemBackground"
android:scaleType="fitCenter"
android:src="@drawable/widget_previous"
android:contentDescription="@string/previous_song" />
<ImageButton
android:id="@+id/play_pause"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:layout_height="42dp"
android:layout_width="wrap_content"
android:layout_gravity="center"
android:background="?android:attr/selectableItemBackground"
android:scaleType="fitCenter"
android:src="@drawable/widget_play"
android:contentDescription="@string/play_pause" />
<ImageButton
android:id="@+id/next"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:layout_height="42dp"
android:layout_width="wrap_content"
android:layout_gravity="center"
android:background="?android:attr/selectableItemBackground"
android:scaleType="fitCenter"
android:src="@drawable/widget_next"
android:contentDescription="@string/next_song" />
<ImageButton
android:id="@+id/close"
android:padding="5dp"
android:layout_height="42dp"
android:layout_width="wrap_content"
android:layout_gravity="center"
android:background="?android:attr/selectableItemBackground"
android:scaleType="fitCenter"
android:src="@drawable/notification_close_dark"
android:contentDescription="@string/close_notification" />
</LinearLayout>

View File

@ -1,130 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2014 Adrian Ulrich <adrian@blinkenlights.ch>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:orientation="horizontal">
<ImageView
android:id="@+id/cover"
android:scaleType="centerCrop"
android:layout_width="128dp"
android:layout_height="128dp"
android:layout_marginRight="8dp"
android:contentDescription="@string/cover_art" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal">
<LinearLayout
android:layout_marginTop="4dp"
android:layout_width="0px"
android:layout_height="match_parent"
android:layout_weight="1"
android:layout_gravity="center"
android:orientation="vertical">
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="@android:style/TextAppearance.Material.Notification.Title"
android:singleLine="true"
android:ellipsize="marquee" />
<TextView
android:id="@+id/artist"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="@android:style/TextAppearance.Material.Notification.Line2"
android:singleLine="true"
android:ellipsize="marquee" />
<TextView
android:id="@+id/album"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="@android:style/TextAppearance.Material.Notification.Line2"
android:singleLine="true"
android:ellipsize="marquee" />
</LinearLayout>
<ImageButton
android:id="@+id/close"
android:padding="5dp"
android:layout_width="32dp"
android:layout_height="32dp"
android:scaleType="fitCenter"
android:background="?android:attr/selectableItemBackground"
android:src="@drawable/notification_close_dark"
android:contentDescription="@string/close_notification" />
</LinearLayout>
<!-- start controll buttons -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageButton
android:id="@+id/previous"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:layout_height="42dp"
android:layout_width="match_parent"
android:layout_gravity="center"
android:layout_weight="1"
android:background="?android:attr/selectableItemBackground"
android:scaleType="fitCenter"
android:src="@drawable/widget_previous"
android:contentDescription="@string/next_song" />
<ImageButton
android:id="@+id/play_pause"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:layout_height="42dp"
android:layout_width="match_parent"
android:layout_gravity="center"
android:layout_weight="1"
android:background="?android:attr/selectableItemBackground"
android:scaleType="fitCenter"
android:src="@drawable/widget_play"
android:contentDescription="@string/play_pause" />
<ImageButton
android:id="@+id/next"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:layout_height="42dp"
android:layout_width="match_parent"
android:layout_gravity="center"
android:layout_weight="1"
android:background="?android:attr/selectableItemBackground"
android:scaleType="fitCenter"
android:src="@drawable/widget_next"
android:contentDescription="@string/next_song" />
</LinearLayout>
<!-- end controll buttons -->
</LinearLayout>
</LinearLayout>

View File

@ -1,99 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2012 Christopher Eby <kreed@kreed.org>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center_vertical"
android:orientation="horizontal">
<ImageView
android:id="@+id/cover"
android:scaleType="centerCrop"
android:layout_width="64dip"
android:layout_height="64dip"
android:layout_marginRight="8dip"
android:contentDescription="@string/cover_art" />
<LinearLayout
android:layout_width="0px"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="center"
android:orientation="vertical">
<TextView
android:id="@+id/title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textAppearance="@android:style/TextAppearance.StatusBar.EventContent.Title"
android:singleLine="true"
android:ellipsize="marquee" />
<TextView
android:id="@+id/artist"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textAppearance="@android:style/TextAppearance.StatusBar.EventContent"
android:singleLine="true"
android:ellipsize="marquee" />
</LinearLayout>
<ImageButton
android:id="@+id/previous"
android:paddingTop="5dip"
android:paddingBottom="5dip"
android:layout_height="42dip"
android:layout_width="wrap_content"
android:layout_gravity="center"
android:background="?android:attr/selectableItemBackground"
android:scaleType="fitCenter"
android:src="@drawable/widget_previous"
android:contentDescription="@string/previous_song" />
<ImageButton
android:id="@+id/play_pause"
android:paddingTop="5dip"
android:paddingBottom="5dip"
android:layout_height="42dip"
android:layout_width="wrap_content"
android:layout_gravity="center"
android:background="?android:attr/selectableItemBackground"
android:scaleType="fitCenter"
android:src="@drawable/widget_play"
android:contentDescription="@string/play_pause" />
<ImageButton
android:id="@+id/next"
android:paddingTop="5dip"
android:paddingBottom="5dip"
android:layout_height="42dip"
android:layout_width="wrap_content"
android:layout_gravity="center"
android:background="?android:attr/selectableItemBackground"
android:scaleType="fitCenter"
android:src="@drawable/widget_next"
android:contentDescription="@string/next_song" />
<ImageButton
android:id="@+id/close"
android:padding="5dip"
android:layout_height="42dip"
android:layout_width="wrap_content"
android:layout_gravity="center"
android:background="?android:attr/selectableItemBackground"
android:scaleType="fitCenter"
android:src="@drawable/notification_close"
android:contentDescription="@string/close_notification" />
</LinearLayout>

View File

@ -1,130 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2014 Adrian Ulrich <adrian@blinkenlights.ch>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:orientation="horizontal">
<ImageView
android:id="@+id/cover"
android:scaleType="centerCrop"
android:layout_width="128dip"
android:layout_height="128dip"
android:layout_marginRight="8dip"
android:contentDescription="@string/cover_art" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal">
<LinearLayout
android:layout_marginTop="4dip"
android:layout_width="0px"
android:layout_height="match_parent"
android:layout_weight="1"
android:layout_gravity="center"
android:orientation="vertical">
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="@android:style/TextAppearance.StatusBar.EventContent.Title"
android:singleLine="true"
android:ellipsize="marquee" />
<TextView
android:id="@+id/artist"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="@android:style/TextAppearance.StatusBar.EventContent"
android:singleLine="true"
android:ellipsize="marquee" />
<TextView
android:id="@+id/album"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="@android:style/TextAppearance.StatusBar.EventContent"
android:singleLine="true"
android:ellipsize="marquee" />
</LinearLayout>
<ImageButton
android:id="@+id/close"
android:padding="5dip"
android:layout_width="32dp"
android:layout_height="32dp"
android:scaleType="fitCenter"
android:background="?android:attr/selectableItemBackground"
android:src="@drawable/notification_close"
android:contentDescription="@string/close_notification" />
</LinearLayout>
<!-- start controll buttons -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageButton
android:id="@+id/previous"
android:paddingTop="5dip"
android:paddingBottom="5dip"
android:layout_height="42dip"
android:layout_width="match_parent"
android:layout_gravity="center"
android:layout_weight="1"
android:background="?android:attr/selectableItemBackground"
android:scaleType="fitCenter"
android:src="@drawable/previous"
android:contentDescription="@string/next_song" />
<ImageButton
android:id="@+id/play_pause"
android:paddingTop="5dip"
android:paddingBottom="5dip"
android:layout_height="42dip"
android:layout_width="match_parent"
android:layout_gravity="center"
android:layout_weight="1"
android:background="?android:attr/selectableItemBackground"
android:scaleType="fitCenter"
android:src="@drawable/play"
android:contentDescription="@string/play_pause" />
<ImageButton
android:id="@+id/next"
android:paddingTop="5dip"
android:paddingBottom="5dip"
android:layout_height="42dip"
android:layout_width="match_parent"
android:layout_gravity="center"
android:layout_weight="1"
android:background="?android:attr/selectableItemBackground"
android:scaleType="fitCenter"
android:src="@drawable/next"
android:contentDescription="@string/next_song" />
</LinearLayout>
<!-- end controll buttons -->
</LinearLayout>
</LinearLayout>

View File

@ -219,9 +219,6 @@ THE SOFTWARE.
<string name="notification_visibility_title">Notification visibility</string>
<string name="notification_action_title">Notification action</string>
<string name="notification_nag">Very verbose notification</string>
<string name="notification_nag_summary">Announce track changes using a \'Heads-Up-Notification\'</string>
<string name="playback_screen">Playback screen</string>
<string name="playback_on_startup_title">Open on startup</string>
<string name="playback_on_startup_summary">Open playback view on startup</string>

View File

@ -35,9 +35,4 @@ THE SOFTWARE.
android:entries="@array/notification_action_entries"
android:entryValues="@array/entry_values"
android:defaultValue="0" />
<CheckBoxPreference
android:key="notification_nag"
android:title="@string/notification_nag"
android:defaultValue="false"
android:summary="@string/notification_nag_summary" />
</PreferenceScreen>