1
0
Fork 0
forked from len0rd/rockbox

Add widgets to android port.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29170 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Antoine Cellerier 2011-01-29 20:47:32 +00:00
parent e9749d1b93
commit c0c769c5a8
37 changed files with 771 additions and 5 deletions

View file

@ -11,6 +11,7 @@ import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.net.Uri;
import android.util.Log;
import android.widget.RemoteViews;
@ -92,6 +93,19 @@ public class RunForegroundManager
else
mNotification.tickerText = title+" - "+artist;
mNM.notify(R.string.notification, mNotification);
Intent widgetUpdate = new Intent("org.rockbox.TrackUpdateInfo");
widgetUpdate.putExtra("title", title);
widgetUpdate.putExtra("artist", artist);
widgetUpdate.putExtra("album", album);
mCurrentService.sendBroadcast(widgetUpdate);
}
public void finishNotification()
{
Log.d("Rockbox", "TrackFinish");
Intent widgetUpdate = new Intent("org.rockbox.TrackFinish");
mCurrentService.sendBroadcast(widgetUpdate);
}
private interface IRunForeground

View file

@ -147,5 +147,5 @@ public class RockboxFramebuffer extends View
private native void post_update_done();
private native void set_lcd_active(int active);
private native void touchHandler(boolean down, int x, int y);
private native boolean buttonHandler(int keycode, boolean state);
private native static boolean buttonHandler(int keycode, boolean state);
}

View file

@ -23,9 +23,11 @@ package org.rockbox;
import java.util.Arrays;
import android.content.Intent;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.net.Uri;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Process;
@ -80,10 +82,16 @@ public class RockboxPCM extends AudioTrack
private void play_pause(boolean pause) {
if (pause)
{
Intent widgetUpdate = new Intent("org.rockbox.UpdateState");
widgetUpdate.putExtra("state", "pause");
RockboxService.get_instance().sendBroadcast(widgetUpdate);
pause();
}
else
{
Intent widgetUpdate = new Intent("org.rockbox.UpdateState");
widgetUpdate.putExtra("state", "play");
RockboxService.get_instance().sendBroadcast(widgetUpdate);
if (getPlayState() == AudioTrack.PLAYSTATE_STOPPED)
{
RockboxService.get_instance().startForeground();
@ -114,6 +122,9 @@ public class RockboxPCM extends AudioTrack
throw new IllegalStateException(e);
}
RockboxService.get_instance().stopForeground();
Intent widgetUpdate = new Intent("org.rockbox.UpdateState");
widgetUpdate.putExtra("state", "stop");
RockboxService.get_instance().sendBroadcast(widgetUpdate);
}
@SuppressWarnings("unused")

View file

@ -43,6 +43,7 @@ import android.os.Bundle;
import android.os.IBinder;
import android.os.ResultReceiver;
import android.util.Log;
import android.view.KeyEvent;
/* This class is used as the main glue between java and c.
* All access should be done through RockboxService.get_instance() for safety.
@ -76,7 +77,7 @@ public class RockboxService extends Service
@Override
public void onCreate()
{
instance = this;
instance = this;
}
public static RockboxService get_instance()
@ -115,6 +116,31 @@ public class RockboxService extends Service
if (!rbLibLoaded)
startservice();
if (intent != null && intent.getAction() != null)
{
Log.d("RockboxService", intent.getAction());
if (intent.getAction().equals("org.rockbox.PlayPause"))
{
if (fb != null)
fb.onKeyUp(KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE, null);
}
else if (intent.getAction().equals("org.rockbox.Prev"))
{
if (fb != null)
fb.onKeyUp(KeyEvent.KEYCODE_MEDIA_PREVIOUS, null);
}
else if (intent.getAction().equals("org.rockbox.Next"))
{
if (fb != null)
fb.onKeyUp(KeyEvent.KEYCODE_MEDIA_NEXT, null);
}
else if (intent.getAction().equals("org.rockbox.Stop"))
{
if (fb != null)
fb.onKeyUp(KeyEvent.KEYCODE_MEDIA_STOP, null);
}
}
/* Display a notification about us starting.
* We put an icon in the status bar. */
if (fg_runner == null)

View file

@ -0,0 +1,121 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2011 Antoine Cellerier <dionoea at videolan dot org>
*
* 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.
*
****************************************************************************/
package org.rockbox.widgets;
import org.rockbox.R;
import android.app.Activity;
import android.appwidget.AppWidgetManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.CheckBox;
public class RockboxWidgetConfigure extends Activity
{
int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
public RockboxWidgetConfigure()
{
super();
}
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setResult(RESULT_CANCELED);
setContentView(R.layout.appwidget_configure);
((CheckBox)findViewById(R.id.enable_prev)).setChecked(false);
((CheckBox)findViewById(R.id.enable_stop)).setChecked(true);
((CheckBox)findViewById(R.id.enable_playpause)).setChecked(true);
((CheckBox)findViewById(R.id.enable_next)).setChecked(false);
findViewById(R.id.confirm).setOnClickListener(mCreateWidget);
Intent intent = getIntent();
Bundle extras = intent.getExtras();
if (extras != null)
mAppWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID)
finish();
}
View.OnClickListener mCreateWidget = new View.OnClickListener()
{
public void onClick(View v)
{
final Context context = RockboxWidgetConfigure.this;
WidgetPref state = new WidgetPref();
state.enablePrev = ((CheckBox)findViewById(R.id.enable_prev)).isChecked();
state.enableStop = ((CheckBox)findViewById(R.id.enable_stop)).isChecked();
state.enablePlayPause = ((CheckBox)findViewById(R.id.enable_playpause)).isChecked();
state.enableNext = ((CheckBox)findViewById(R.id.enable_next)).isChecked();
saveWidgetPref(context, mAppWidgetId, state);
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
RockboxWidgetProvider.updateAppWidget(context, appWidgetManager, mAppWidgetId, null);
Intent result = new Intent();
result.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
setResult(RESULT_OK, result);
finish();
}
};
static public class WidgetPref
{
public boolean enablePrev = true;
public boolean enableStop = true;
public boolean enablePlayPause = true;
public boolean enableNext = true;
}
static void saveWidgetPref(Context context, int appWidgetId, WidgetPref state)
{
SharedPreferences.Editor prefs = context.getSharedPreferences("org.rockbox.RockboxWidgetConfigure", 0).edit();
prefs.putBoolean("prev"+appWidgetId, state.enablePrev);
prefs.putBoolean("stop"+appWidgetId, state.enableStop);
prefs.putBoolean("playpause"+appWidgetId, state.enablePlayPause);
prefs.putBoolean("next"+appWidgetId, state.enableNext);
prefs.commit();
}
static WidgetPref loadWidgetPref(Context context, int appWidgetId)
{
SharedPreferences prefs = context.getSharedPreferences("org.rockbox.RockboxWidgetConfigure", 0);
WidgetPref state = new WidgetPref();
state.enablePrev = prefs.getBoolean("prev"+appWidgetId, true);
state.enableStop = prefs.getBoolean("stop"+appWidgetId, true);
state.enablePlayPause = prefs.getBoolean("playpause"+appWidgetId, true);
state.enableNext = prefs.getBoolean("next"+appWidgetId, true);
return state;
}
}

View file

@ -0,0 +1,171 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2011 Antoine Cellerier <dionoea at videolan dot org>
*
* 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.
*
****************************************************************************/
package org.rockbox.widgets;
import org.rockbox.R;
import org.rockbox.RockboxActivity;
import org.rockbox.RockboxService;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.appwidget.AppWidgetProviderInfo;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.util.Log;
import android.view.View;
import android.view.KeyEvent;
import android.widget.RemoteViews;
import java.util.ArrayList;
public class RockboxWidgetProvider extends AppWidgetProvider
{
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds)
{
final int N = appWidgetIds.length;
for (int i = 0; i < N; i++)
{
int appWidgetId = appWidgetIds[i];
updateAppWidget(context, appWidgetManager, appWidgetId, null);
}
}
@Override
public void onDeleted(Context context, int[] appWidgetIds)
{
}
@Override
public void onEnabled(Context context)
{
}
@Override
public void onDisabled(Context context)
{
}
@Override
public void onReceive(Context context, Intent intent)
{
String action = intent.getAction();
if (intent.getAction().equals("org.rockbox.TrackUpdateInfo") ||
intent.getAction().equals("org.rockbox.TrackFinish") ||
intent.getAction().equals("org.rockbox.UpdateState"))
{
AppWidgetManager gm = AppWidgetManager.getInstance(context);
int[] appWidgetIds = gm.getAppWidgetIds(new ComponentName(context, this.getClass()));
final int N = appWidgetIds.length;
for (int i = 0; i < N; i++)
{
updateAppWidget(context, gm, appWidgetIds[i], intent);
}
}
else
{
super.onReceive(context, intent);
}
}
public static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId, Intent args)
{
AppWidgetProviderInfo provider = appWidgetManager.getAppWidgetInfo(appWidgetId);
RemoteViews views = null;
views = new RemoteViews(context.getPackageName(), provider.initialLayout);
Intent intent = new Intent(context, RockboxActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
views.setOnClickPendingIntent(R.id.infoDisplay, pendingIntent);
RockboxWidgetConfigure.WidgetPref state = RockboxWidgetConfigure.loadWidgetPref(context, appWidgetId);
if (state.enablePrev)
{
intent = new Intent("org.rockbox.Prev", Uri.EMPTY, context, RockboxService.class);
pendingIntent = PendingIntent.getService(context, 0, intent, 0);
views.setOnClickPendingIntent(R.id.prev, pendingIntent);
}
else
views.setViewVisibility(R.id.prev, View.GONE);
if (state.enablePlayPause)
{
intent = new Intent("org.rockbox.PlayPause", Uri.EMPTY, context, RockboxService.class);
pendingIntent = PendingIntent.getService(context, 0, intent, 0);
views.setOnClickPendingIntent(R.id.playPause, pendingIntent);
}
else
views.setViewVisibility(R.id.playPause, View.GONE);
if (state.enableNext)
{
intent = new Intent("org.rockbox.Next", Uri.EMPTY, context, RockboxService.class);
pendingIntent = PendingIntent.getService(context, 0, intent, 0);
views.setOnClickPendingIntent(R.id.next, pendingIntent);
}
else
views.setViewVisibility(R.id.next, View.GONE);
if (state.enableStop)
{
intent = new Intent("org.rockbox.Stop", Uri.EMPTY, context, RockboxService.class);
pendingIntent = PendingIntent.getService(context, 0, intent, 0);
views.setOnClickPendingIntent(R.id.stop, pendingIntent);
}
else
views.setViewVisibility(R.id.stop, View.GONE);
if (args != null)
{
if (args.getAction().equals("org.rockbox.TrackUpdateInfo"))
{
CharSequence title = args.getCharSequenceExtra("title");
CharSequence artist = args.getCharSequenceExtra("artist");
CharSequence album = args.getCharSequenceExtra("album");
views.setTextViewText(R.id.infoDisplay, title+"\n"+artist+"\n"+album);
}
else if (args.getAction().equals("org.rockbox.TrackFinish"))
{
// FIXME: looks like this event is always fired earlier than
// the actual track change (a few seconds)
views.setTextViewText(R.id.infoDisplay, context.getString(R.string.appwidget_infoDisplay));
}
else if (args.getAction().equals("org.rockbox.UpdateState"))
{
CharSequence playstate = args.getCharSequenceExtra("state");
if (playstate.equals("play"))
views.setImageViewResource(R.id.playPause, R.drawable.appwidget_pause);
else /* pause or stop */
views.setImageViewResource(R.id.playPause, R.drawable.appwidget_play);
}
}
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}

View file

@ -0,0 +1,27 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2011 Antoine Cellerier <dionoea at videolan dot org>
*
* 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.
*
****************************************************************************/
package org.rockbox.widgets;
public class RockboxWidgetProvider2x2 extends RockboxWidgetProvider
{
}

View file

@ -0,0 +1,27 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2011 Antoine Cellerier <dionoea at videolan dot org>
*
* 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.
*
****************************************************************************/
package org.rockbox.widgets;
public class RockboxWidgetProvider4x1 extends RockboxWidgetProvider
{
}