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
This commit is contained in:
Thomas Martitz 2010-12-10 18:41:09 +00:00
parent c47d813451
commit f5a461d182
17 changed files with 222 additions and 24 deletions

View file

@ -2,4 +2,4 @@
ADB="$ANDROID_SDK_PATH/tools/adb"
$ADB install -r rockbox.apk
echo 'am start -W -a android.intent.action.MAIN -n org.rockbox/.RockboxActivity; exit' | $ADB shell
echo 'am start -a android.intent.action.MAIN -n org.rockbox/.RockboxActivity; exit' | $ADB shell

Binary file not shown.

After

Width:  |  Height:  |  Size: 1,013 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1,011 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 549 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 533 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 886 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 675 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 628 B

View file

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:paddingLeft="6dp"
android:paddingRight="6dp"
android:paddingTop="0dp"
android:paddingBottom="0dp"
android:orientation="horizontal">
<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView android:src="@drawable/notification_small"
android:gravity="center"
android:paddingTop="2dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</ImageView>
<TextView android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="true"
android:ellipsize="end"
android:textStyle="bold"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceMediumInverse"
android:gravity="center"
android:paddingTop="0dp"
android:paddingLeft="6dp" />
</LinearLayout>
<LinearLayout android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="3dp"
android:orientation="vertical">
<TextView android:id="@+id/content"
android:layout_gravity="left"
android:scrollHorizontally="true"
android:maxLines="2"
android:ellipsize="end"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmallInverse"
/>
</LinearLayout>
</LinearLayout>
</LinearLayout>

View file

@ -12,6 +12,7 @@ import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.util.Log;
import android.widget.RemoteViews;
public class RunForegroundManager
{
@ -25,34 +26,32 @@ public class RunForegroundManager
public RunForegroundManager(Service service) throws Exception
{
mCurrentService = service;
mNM = (NotificationManager)
service.getSystemService(Service.NOTIFICATION_SERVICE);
/* For now we'll use the same text for the ticker and the
* expanded notification */
CharSequence text = service.getText(R.string.notification);
/* Set the icon, scrolling text and timestamp */
mNotification = new Notification(R.drawable.icon, text,
System.currentTimeMillis());
/* The PendingIntent to launch our activity if the user selects
* this notification */
RemoteViews views = new RemoteViews(service.getPackageName(), R.layout.statusbar);
/* create Intent for clicking on the expanded notifcation area */
Intent intent = new Intent(service, RockboxActivity.class);
PendingIntent contentIntent =
PendingIntent.getActivity(service, 0, intent, 0);
intent = intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mNotification = new Notification();
mNotification.tickerText = service.getString(R.string.notification);
mNotification.icon = R.drawable.notification;
mNotification.contentView = views;
mNotification.flags |= Notification.FLAG_ONGOING_EVENT;
mNotification.contentIntent = PendingIntent.getActivity(service, 0, intent, 0);
/* Set the info for the views that show in the notification panel. */
mNotification.setLatestEventInfo(service,
service.getText(R.string.notification), text, contentIntent);
try {
api = new newForegroundApi(R.string.notification, mNotification);
} catch (NoSuchMethodException e) {
/* Fall back on the old API */
api = new oldForegroundApi();
}
mCurrentService = service;
}
private void LOG(CharSequence text)
{
Log.d("Rockbox", (String)text);
}
private void LOG(CharSequence text, Throwable tr)
{
Log.d("Rockbox", (String)text, tr);
@ -83,6 +82,14 @@ public class RunForegroundManager
api.stopForeground();
}
public void updateNotification(String title, String content, String ticker)
{
RemoteViews views = mNotification.contentView;
views.setTextViewText(R.id.title, title);
views.setTextViewText(R.id.content, content);
mNotification.tickerText = ticker;
mNM.notify(R.string.notification, mNotification);
}
private interface IRunForeground
{

View file

@ -117,10 +117,13 @@ public class RockboxService extends Service
/* Display a notification about us starting.
* We put an icon in the status bar. */
try {
fg_runner = new RunForegroundManager(this);
} catch (Exception e) {
e.printStackTrace();
if (fg_runner == null)
{
try {
fg_runner = new RunForegroundManager(this);
} catch (Exception e) {
e.printStackTrace();
}
}
}

View file

@ -91,6 +91,7 @@ gui/statusbar-skinned.c
#endif
#if (CONFIG_PLATFORM&PLATFORM_ANDROID)
hosted/yesno.c
hosted/notification.c
#else
gui/yesno.c
#endif

View file

@ -8,6 +8,9 @@
#
INCLUDES += -I$(APPSDIR) $(patsubst %,-I$(APPSDIR)/%,$(subst :, ,$(APPEXTRA)))
ifdef APP_TYPE
INCLUDES += -I$(APPSDIR)/hosted
endif
SRC += $(call preprocess, $(APPSDIR)/SOURCES)
# apps/features.txt is a file that (is preprocessed and) lists named features

View file

@ -1189,6 +1189,8 @@ static void wps_state_init(void)
/* add the WPS track event callbacks */
add_event(PLAYBACK_EVENT_TRACK_CHANGE, false, track_changed_callback);
add_event(PLAYBACK_EVENT_NEXTTRACKID3_AVAILABLE, false, nextid3available_callback);
extern void notification_init(void);
notification_init();
}

View file

@ -0,0 +1,96 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2010 Thomas Martitz
*
* 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 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include <jni.h>
#include <stdio.h>
#include "notification.h"
#include "appevents.h"
#include "metadata.h"
#include "misc.h"
extern JNIEnv *env_ptr;
extern jclass RockboxService_class;
extern jobject RockboxService_instance;
static jmethodID updateNotification;
static jobject NotificationManager_instance;
static jstring headline, content, ticker;
#define NZV(a) (a && a[0])
/*
* notify about track change, and show track info */
static void track_changed_callback(void *param)
{
struct mp3entry* id3 = (struct mp3entry*)param;
JNIEnv e = *env_ptr;
if (id3)
{
/* passing NULL to DeleteLocalRef() is OK */
e->DeleteLocalRef(env_ptr, headline);
e->DeleteLocalRef(env_ptr, content);
e->DeleteLocalRef(env_ptr, ticker);
char buf[200];
const char * title = id3->title;
if (!title)
{ /* pass the filename as title if id3 info isn't available */
title =
strip_extension(buf, sizeof(buf), strrchr(id3->path,'/') + 1);
}
/* do text for the notification area in the scrolled-down statusbar */
headline = e->NewStringUTF(env_ptr, title);
/* add a \n so that android does split into two lines */
snprintf(buf, sizeof(buf), "%s\n%s", id3->artist ?: "", id3->album ?: "");
content = e->NewStringUTF(env_ptr, buf);
/* now do the text for the notification in the statusbar itself */
if (NZV(id3->artist))
{ /* title - artist */
snprintf(buf, sizeof(buf), "%s - %s", title, id3->artist);
ticker = e->NewStringUTF(env_ptr, buf);
}
else
{ /* title */
ticker = e->NewStringUTF(env_ptr, title);
}
e->CallVoidMethod(env_ptr, NotificationManager_instance,
updateNotification, headline, content, ticker);
}
}
void notification_init(void)
{
JNIEnv e = *env_ptr;
jfieldID nNM = e->GetFieldID(env_ptr, RockboxService_class,
"fg_runner", "Lorg/rockbox/Helper/RunForegroundManager;");
NotificationManager_instance = e->GetObjectField(env_ptr,
RockboxService_instance, nNM);
jclass class = e->GetObjectClass(env_ptr, NotificationManager_instance);
updateNotification = e->GetMethodID(env_ptr, class, "updateNotification",
"(Ljava/lang/String;"
"Ljava/lang/String;"
"Ljava/lang/String;)V");
add_event(PLAYBACK_EVENT_TRACK_CHANGE, false, track_changed_callback);
}

View file

@ -0,0 +1,27 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2010 Thomas Martitz
*
* 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 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#ifndef __NOTIFICATION_H__
#define __NOTIFICATION_H__
void notification_init(void);
#endif

View file

@ -76,6 +76,9 @@
#include "skin_engine/skin_engine.h"
#include "statusbar-skinned.h"
#include "bootchart.h"
#if defined(APPLICATION) && (CONFIG_PLATFORM & PLATFORM_ANDROID)
#include "notification.h"
#endif
#ifdef IPOD_ACCESSORY_PROTOCOL
#include "iap.h"
@ -333,11 +336,11 @@ static void init_tagcache(void)
static void init(void)
{
system_init();
kernel_init();
#ifdef APPLICATION
paths_init();
#endif
system_init();
kernel_init();
buffer_init();
enable_irq();
lcd_init();
@ -350,6 +353,9 @@ static void init(void)
backlight_init();
#if (CONFIG_PLATFORM & PLATFORM_SDL)
sim_tasks_init();
#endif
#if (CONFIG_PLATFORM & PLATFORM_ANDROID)
notification_init();
#endif
lang_init(core_language_builtin, language_strings,
LANG_LAST_INDEX_IN_ARRAY);