A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

Android: Rework notification and change icon sizes to better meet the systems' standard.

The notification now announces the new track on track change, and the the area in the scrolled down notification area shows track infos (title, artist, album).

Someone should check if it looks good on hdpi and ldpi screens as I can't verify it right now (emulator crashes).

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@28785 a1c6a512-1295-4272-9138-f99709370657

+222 -24
+1 -1
android/installApk.sh
··· 2 2 ADB="$ANDROID_SDK_PATH/tools/adb" 3 3 4 4 $ADB install -r rockbox.apk 5 - echo 'am start -W -a android.intent.action.MAIN -n org.rockbox/.RockboxActivity; exit' | $ADB shell 5 + echo 'am start -a android.intent.action.MAIN -n org.rockbox/.RockboxActivity; exit' | $ADB shell
android/res/drawable-hdpi/notification.png

This is a binary file and will not be displayed.

android/res/drawable-hdpi/notification_small.png

This is a binary file and will not be displayed.

android/res/drawable-ldpi/notification.png

This is a binary file and will not be displayed.

android/res/drawable-ldpi/notification_small.png

This is a binary file and will not be displayed.

android/res/drawable-mdpi/launcher.png

This is a binary file and will not be displayed.

android/res/drawable-mdpi/notification.png

This is a binary file and will not be displayed.

android/res/drawable-mdpi/notification_small.png

This is a binary file and will not be displayed.

+53
android/res/layout/statusbar.xml
··· 1 + <?xml version="1.0" encoding="ISO-8859-1"?> 2 + <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 + android:layout_width="fill_parent" 4 + android:layout_height="fill_parent" 5 + android:paddingLeft="6dp" 6 + android:paddingRight="6dp" 7 + android:paddingTop="0dp" 8 + android:paddingBottom="0dp" 9 + android:orientation="horizontal"> 10 + 11 + <LinearLayout android:layout_width="match_parent" 12 + android:layout_height="wrap_content" 13 + android:orientation="vertical"> 14 + <LinearLayout android:layout_width="match_parent" 15 + android:layout_height="wrap_content" 16 + android:orientation="horizontal"> 17 + 18 + <ImageView android:src="@drawable/notification_small" 19 + android:gravity="center" 20 + android:paddingTop="2dp" 21 + android:layout_width="wrap_content" 22 + android:layout_height="wrap_content"> 23 + </ImageView> 24 + 25 + <TextView android:id="@+id/title" 26 + android:layout_width="wrap_content" 27 + android:layout_height="wrap_content" 28 + android:focusable="true" 29 + android:ellipsize="end" 30 + android:textStyle="bold" 31 + android:singleLine="true" 32 + android:textAppearance="?android:attr/textAppearanceMediumInverse" 33 + android:gravity="center" 34 + android:paddingTop="0dp" 35 + android:paddingLeft="6dp" /> 36 + </LinearLayout> 37 + 38 + <LinearLayout android:layout_width="wrap_content" 39 + android:layout_height="wrap_content" 40 + android:paddingLeft="3dp" 41 + android:orientation="vertical"> 42 + <TextView android:id="@+id/content" 43 + android:layout_gravity="left" 44 + android:scrollHorizontally="true" 45 + android:maxLines="2" 46 + android:ellipsize="end" 47 + android:layout_width="wrap_content" 48 + android:layout_height="wrap_content" 49 + android:textAppearance="?android:attr/textAppearanceSmallInverse" 50 + /> 51 + </LinearLayout> 52 + </LinearLayout> 53 + </LinearLayout>
+24 -17
android/src/org/rockbox/Helper/RunForegroundManager.java
··· 12 12 import android.app.Service; 13 13 import android.content.Intent; 14 14 import android.util.Log; 15 + import android.widget.RemoteViews; 15 16 16 17 public class RunForegroundManager 17 18 { ··· 25 26 26 27 public RunForegroundManager(Service service) throws Exception 27 28 { 29 + mCurrentService = service; 28 30 mNM = (NotificationManager) 29 31 service.getSystemService(Service.NOTIFICATION_SERVICE); 30 - /* For now we'll use the same text for the ticker and the 31 - * expanded notification */ 32 - CharSequence text = service.getText(R.string.notification); 33 - /* Set the icon, scrolling text and timestamp */ 34 - mNotification = new Notification(R.drawable.icon, text, 35 - System.currentTimeMillis()); 32 + RemoteViews views = new RemoteViews(service.getPackageName(), R.layout.statusbar); 33 + /* create Intent for clicking on the expanded notifcation area */ 34 + Intent intent = new Intent(service, RockboxActivity.class); 35 + intent = intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 36 36 37 - /* The PendingIntent to launch our activity if the user selects 38 - * this notification */ 39 - Intent intent = new Intent(service, RockboxActivity.class); 40 - PendingIntent contentIntent = 41 - PendingIntent.getActivity(service, 0, intent, 0); 37 + mNotification = new Notification(); 38 + mNotification.tickerText = service.getString(R.string.notification); 39 + mNotification.icon = R.drawable.notification; 40 + mNotification.contentView = views; 41 + mNotification.flags |= Notification.FLAG_ONGOING_EVENT; 42 + mNotification.contentIntent = PendingIntent.getActivity(service, 0, intent, 0); 42 43 43 - /* Set the info for the views that show in the notification panel. */ 44 - mNotification.setLatestEventInfo(service, 45 - service.getText(R.string.notification), text, contentIntent); 46 - 47 44 try { 48 45 api = new newForegroundApi(R.string.notification, mNotification); 49 46 } catch (NoSuchMethodException e) { 50 47 /* Fall back on the old API */ 51 48 api = new oldForegroundApi(); 52 49 } 53 - mCurrentService = service; 54 50 } 55 - 51 + private void LOG(CharSequence text) 52 + { 53 + Log.d("Rockbox", (String)text); 54 + } 56 55 private void LOG(CharSequence text, Throwable tr) 57 56 { 58 57 Log.d("Rockbox", (String)text, tr); ··· 83 82 api.stopForeground(); 84 83 } 85 84 85 + public void updateNotification(String title, String content, String ticker) 86 + { 87 + RemoteViews views = mNotification.contentView; 88 + views.setTextViewText(R.id.title, title); 89 + views.setTextViewText(R.id.content, content); 90 + mNotification.tickerText = ticker; 91 + mNM.notify(R.string.notification, mNotification); 92 + } 86 93 87 94 private interface IRunForeground 88 95 {
+7 -4
android/src/org/rockbox/RockboxService.java
··· 117 117 118 118 /* Display a notification about us starting. 119 119 * We put an icon in the status bar. */ 120 - try { 121 - fg_runner = new RunForegroundManager(this); 122 - } catch (Exception e) { 123 - e.printStackTrace(); 120 + if (fg_runner == null) 121 + { 122 + try { 123 + fg_runner = new RunForegroundManager(this); 124 + } catch (Exception e) { 125 + e.printStackTrace(); 126 + } 124 127 } 125 128 } 126 129
+1
apps/SOURCES
··· 91 91 #endif 92 92 #if (CONFIG_PLATFORM&PLATFORM_ANDROID) 93 93 hosted/yesno.c 94 + hosted/notification.c 94 95 #else 95 96 gui/yesno.c 96 97 #endif
+3
apps/apps.make
··· 8 8 # 9 9 10 10 INCLUDES += -I$(APPSDIR) $(patsubst %,-I$(APPSDIR)/%,$(subst :, ,$(APPEXTRA))) 11 + ifdef APP_TYPE 12 + INCLUDES += -I$(APPSDIR)/hosted 13 + endif 11 14 SRC += $(call preprocess, $(APPSDIR)/SOURCES) 12 15 13 16 # apps/features.txt is a file that (is preprocessed and) lists named features
+2
apps/gui/wps.c
··· 1189 1189 /* add the WPS track event callbacks */ 1190 1190 add_event(PLAYBACK_EVENT_TRACK_CHANGE, false, track_changed_callback); 1191 1191 add_event(PLAYBACK_EVENT_NEXTTRACKID3_AVAILABLE, false, nextid3available_callback); 1192 + extern void notification_init(void); 1193 + notification_init(); 1192 1194 } 1193 1195 1194 1196
+96
apps/hosted/notification.c
··· 1 + /*************************************************************************** 2 + * __________ __ ___. 3 + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4 + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 5 + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 6 + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7 + * \/ \/ \/ \/ \/ 8 + * $Id$ 9 + * 10 + * Copyright (C) 2010 Thomas Martitz 11 + * 12 + * This program is free software; you can redistribute it and/or 13 + * modify it under the terms of the GNU General Public License 14 + * as published by the Free Software Foundation; either version 2 15 + * of the License, or (at your option) any later version. 16 + * 17 + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 18 + * KIND, either express or implied. 19 + * 20 + ****************************************************************************/ 21 + 22 + #include <jni.h> 23 + #include <stdio.h> 24 + #include "notification.h" 25 + #include "appevents.h" 26 + #include "metadata.h" 27 + #include "misc.h" 28 + 29 + extern JNIEnv *env_ptr; 30 + extern jclass RockboxService_class; 31 + extern jobject RockboxService_instance; 32 + 33 + static jmethodID updateNotification; 34 + static jobject NotificationManager_instance; 35 + static jstring headline, content, ticker; 36 + 37 + #define NZV(a) (a && a[0]) 38 + 39 + /* 40 + * notify about track change, and show track info */ 41 + static void track_changed_callback(void *param) 42 + { 43 + struct mp3entry* id3 = (struct mp3entry*)param; 44 + JNIEnv e = *env_ptr; 45 + if (id3) 46 + { 47 + /* passing NULL to DeleteLocalRef() is OK */ 48 + e->DeleteLocalRef(env_ptr, headline); 49 + e->DeleteLocalRef(env_ptr, content); 50 + e->DeleteLocalRef(env_ptr, ticker); 51 + 52 + char buf[200]; 53 + const char * title = id3->title; 54 + if (!title) 55 + { /* pass the filename as title if id3 info isn't available */ 56 + title = 57 + strip_extension(buf, sizeof(buf), strrchr(id3->path,'/') + 1); 58 + } 59 + 60 + /* do text for the notification area in the scrolled-down statusbar */ 61 + headline = e->NewStringUTF(env_ptr, title); 62 + 63 + /* add a \n so that android does split into two lines */ 64 + snprintf(buf, sizeof(buf), "%s\n%s", id3->artist ?: "", id3->album ?: ""); 65 + content = e->NewStringUTF(env_ptr, buf); 66 + 67 + /* now do the text for the notification in the statusbar itself */ 68 + if (NZV(id3->artist)) 69 + { /* title - artist */ 70 + snprintf(buf, sizeof(buf), "%s - %s", title, id3->artist); 71 + ticker = e->NewStringUTF(env_ptr, buf); 72 + } 73 + else 74 + { /* title */ 75 + ticker = e->NewStringUTF(env_ptr, title); 76 + } 77 + e->CallVoidMethod(env_ptr, NotificationManager_instance, 78 + updateNotification, headline, content, ticker); 79 + } 80 + } 81 + 82 + void notification_init(void) 83 + { 84 + JNIEnv e = *env_ptr; 85 + jfieldID nNM = e->GetFieldID(env_ptr, RockboxService_class, 86 + "fg_runner", "Lorg/rockbox/Helper/RunForegroundManager;"); 87 + NotificationManager_instance = e->GetObjectField(env_ptr, 88 + RockboxService_instance, nNM); 89 + 90 + jclass class = e->GetObjectClass(env_ptr, NotificationManager_instance); 91 + updateNotification = e->GetMethodID(env_ptr, class, "updateNotification", 92 + "(Ljava/lang/String;" 93 + "Ljava/lang/String;" 94 + "Ljava/lang/String;)V"); 95 + add_event(PLAYBACK_EVENT_TRACK_CHANGE, false, track_changed_callback); 96 + }
+27
apps/hosted/notification.h
··· 1 + /*************************************************************************** 2 + * __________ __ ___. 3 + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4 + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 5 + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 6 + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7 + * \/ \/ \/ \/ \/ 8 + * $Id$ 9 + * 10 + * Copyright (C) 2010 Thomas Martitz 11 + * 12 + * This program is free software; you can redistribute it and/or 13 + * modify it under the terms of the GNU General Public License 14 + * as published by the Free Software Foundation; either version 2 15 + * of the License, or (at your option) any later version. 16 + * 17 + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 18 + * KIND, either express or implied. 19 + * 20 + ****************************************************************************/ 21 + 22 + #ifndef __NOTIFICATION_H__ 23 + #define __NOTIFICATION_H__ 24 + 25 + void notification_init(void); 26 + 27 + #endif
+8 -2
apps/main.c
··· 76 76 #include "skin_engine/skin_engine.h" 77 77 #include "statusbar-skinned.h" 78 78 #include "bootchart.h" 79 + #if defined(APPLICATION) && (CONFIG_PLATFORM & PLATFORM_ANDROID) 80 + #include "notification.h" 81 + #endif 79 82 80 83 #ifdef IPOD_ACCESSORY_PROTOCOL 81 84 #include "iap.h" ··· 333 336 334 337 static void init(void) 335 338 { 339 + system_init(); 340 + kernel_init(); 336 341 #ifdef APPLICATION 337 342 paths_init(); 338 343 #endif 339 - system_init(); 340 - kernel_init(); 341 344 buffer_init(); 342 345 enable_irq(); 343 346 lcd_init(); ··· 350 353 backlight_init(); 351 354 #if (CONFIG_PLATFORM & PLATFORM_SDL) 352 355 sim_tasks_init(); 356 + #endif 357 + #if (CONFIG_PLATFORM & PLATFORM_ANDROID) 358 + notification_init(); 353 359 #endif 354 360 lang_init(core_language_builtin, language_strings, 355 361 LANG_LAST_INDEX_IN_ARRAY);