Add widgets to android port.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29170 a1c6a512-1295-4272-9138-f99709370657
|
@ -29,6 +29,37 @@
|
|||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<!-- Widgets -->
|
||||
<receiver android:name=".widgets.RockboxWidgetProvider4x1"
|
||||
android:label="@string/appwidget_label_4x1">
|
||||
<intent-filter>
|
||||
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
||||
<action android:name="org.rockbox.TrackUpdateInfo" />
|
||||
<action android:name="org.rockbox.TrackFinish" />
|
||||
<action android:name="org.rockbox.UpdateState" />
|
||||
</intent-filter>
|
||||
<meta-data android:name="android.appwidget.provider"
|
||||
android:resource="@xml/appwidget_provider_4x1" />
|
||||
</receiver>
|
||||
|
||||
<receiver android:name=".widgets.RockboxWidgetProvider2x2"
|
||||
android:label="@string/appwidget_label_2x2">
|
||||
<intent-filter>
|
||||
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
||||
<action android:name="org.rockbox.TrackUpdateInfo" />
|
||||
<action android:name="org.rockbox.TrackFinish" />
|
||||
<action android:name="org.rockbox.UpdateState" />
|
||||
</intent-filter>
|
||||
<meta-data android:name="android.appwidget.provider"
|
||||
android:resource="@xml/appwidget_provider_2x2" />
|
||||
</receiver>
|
||||
|
||||
<!-- Widget configuration -->
|
||||
<activity android:name=".widgets.RockboxWidgetConfigure">
|
||||
<intent-filter>
|
||||
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
</application>
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ R_OBJ := $(BUILDDIR)/bin/$(PACKAGE_PATH)/R.class
|
|||
|
||||
JAVA_SRC := $(wildcard $(ANDROID_DIR)/src/$(PACKAGE_PATH)/Helper/*.java)
|
||||
JAVA_SRC += $(wildcard $(ANDROID_DIR)/src/$(PACKAGE_PATH)/*.java)
|
||||
JAVA_SRC += $(wildcard $(ANDROID_DIR)/src/$(PACKAGE_PATH)/widgets/*.java)
|
||||
JAVA_OBJ := $(call java2class,$(subst $(ANDROID)/src/$(PACKAGE_PATH),$(ANDROID)/bin/$(PACKAGE_PATH),$(JAVA_SRC)))
|
||||
|
||||
|
||||
|
|
6
android/res/drawable/appwidget_background.xml
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@drawable/appwidget_background_normal" />
|
||||
</selector>
|
||||
|
BIN
android/res/drawable/appwidget_background_normal.9.png
Normal file
After Width: | Height: | Size: 654 B |
BIN
android/res/drawable/appwidget_ff_normal.png
Normal file
After Width: | Height: | Size: 9.2 KiB |
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_pressed="true" android:drawable="@drawable/appwidget_selection_clicked" />
|
||||
<item android:state_focused="true" android:drawable="@drawable/appwidget_selection_over" />
|
||||
<item android:drawable="@drawable/appwidget_selection_transparent" />
|
||||
</selector>
|
||||
|
6
android/res/drawable/appwidget_next.xml
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@drawable/appwidget_ff_normal" />
|
||||
</selector>
|
||||
|
6
android/res/drawable/appwidget_pause.xml
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@drawable/appwidget_pause_normal" />
|
||||
</selector>
|
||||
|
BIN
android/res/drawable/appwidget_pause_normal.png
Normal file
After Width: | Height: | Size: 7.4 KiB |
6
android/res/drawable/appwidget_play.xml
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@drawable/appwidget_play_normal" />
|
||||
</selector>
|
||||
|
BIN
android/res/drawable/appwidget_play_normal.png
Normal file
After Width: | Height: | Size: 11 KiB |
6
android/res/drawable/appwidget_prev.xml
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@drawable/appwidget_rew_normal" />
|
||||
</selector>
|
||||
|
BIN
android/res/drawable/appwidget_rew_normal.png
Normal file
After Width: | Height: | Size: 9 KiB |
BIN
android/res/drawable/appwidget_selection_clicked.9.png
Normal file
After Width: | Height: | Size: 169 B |
BIN
android/res/drawable/appwidget_selection_over.9.png
Normal file
After Width: | Height: | Size: 170 B |
BIN
android/res/drawable/appwidget_selection_transparent.9.png
Normal file
After Width: | Height: | Size: 165 B |
6
android/res/drawable/appwidget_stop.xml
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@drawable/appwidget_stop_normal" />
|
||||
</selector>
|
||||
|
BIN
android/res/drawable/appwidget_stop_normal.png
Normal file
After Width: | Height: | Size: 7.1 KiB |
BIN
android/res/drawable/rockbox.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
android/res/drawable/source/appwidget_background.svg
Normal file
After Width: | Height: | Size: 3.9 KiB |
42
android/res/layout/appwidget_2x2.xml
Normal file
|
@ -0,0 +1,42 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center"
|
||||
android:background="@drawable/appwidget_background">
|
||||
<!-- style="@style/appwidget_background"-->
|
||||
|
||||
<ImageView android:id="@+id/logo"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="40dp"
|
||||
android:scaleType="centerInside"
|
||||
android:src="@drawable/rockbox" />
|
||||
<Button android:id="@+id/infoDisplay"
|
||||
style="@style/appwidget_infodisplay"
|
||||
android:layout_width="fill_parent"
|
||||
android:text="@string/appwidget_infoDisplay" />
|
||||
<LinearLayout android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal">
|
||||
<ImageButton android:id="@+id/prev"
|
||||
style="@style/appwidget_button"
|
||||
android:layout_weight="1"
|
||||
android:src="@drawable/appwidget_prev" />
|
||||
<ImageButton android:id="@+id/stop"
|
||||
style="@style/appwidget_button"
|
||||
android:layout_weight="1"
|
||||
android:src="@drawable/appwidget_stop" />
|
||||
<ImageButton android:id="@+id/playPause"
|
||||
style="@style/appwidget_button"
|
||||
android:layout_weight="1"
|
||||
android:src="@drawable/appwidget_play" />
|
||||
<ImageButton android:id="@+id/next"
|
||||
style="@style/appwidget_button"
|
||||
android:layout_weight="1"
|
||||
android:src="@drawable/appwidget_next" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
31
android/res/layout/appwidget_4x1.xml
Normal file
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center"
|
||||
android:background="@drawable/appwidget_background">
|
||||
<!-- style="@style/appwidget_background"-->
|
||||
|
||||
<Button android:id="@+id/infoDisplay"
|
||||
style="@style/appwidget_infodisplay"
|
||||
android:layout_height="fill_parent"
|
||||
android:text="@string/appwidget_infoDisplay" />
|
||||
<ImageButton android:id="@+id/prev"
|
||||
style="@style/appwidget_button"
|
||||
android:layout_height="fill_parent"
|
||||
android:src="@drawable/appwidget_prev" />
|
||||
<ImageButton android:id="@+id/stop"
|
||||
style="@style/appwidget_button"
|
||||
android:layout_height="fill_parent"
|
||||
android:src="@drawable/appwidget_stop" />
|
||||
<ImageButton android:id="@+id/playPause"
|
||||
style="@style/appwidget_button"
|
||||
android:layout_height="fill_parent"
|
||||
android:src="@drawable/appwidget_play" />
|
||||
<ImageButton android:id="@+id/next"
|
||||
style="@style/appwidget_button"
|
||||
android:layout_height="fill_parent"
|
||||
android:src="@drawable/appwidget_next" />
|
||||
</LinearLayout>
|
40
android/res/layout/appwidget_configure.xml
Normal file
|
@ -0,0 +1,40 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageView android:id="@+id/logo"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:scaleType="centerInside"
|
||||
android:src="@drawable/rockbox" />
|
||||
|
||||
<TextView android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/appwidget_configure_instructions"/>
|
||||
|
||||
<CheckBox android:id="@+id/enable_prev"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/appwidget_configure_prev"/>
|
||||
<CheckBox android:id="@+id/enable_stop"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/appwidget_configure_stop"/>
|
||||
<CheckBox android:id="@+id/enable_playpause"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/appwidget_configure_playpause"/>
|
||||
<CheckBox android:id="@+id/enable_next"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/appwidget_configure_next"/>
|
||||
|
||||
<Button android:id="@+id/confirm"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/appwidget_configure_confirm"/>
|
||||
</LinearLayout>
|
||||
|
|
@ -10,4 +10,18 @@
|
|||
<string name="No">No</string>
|
||||
<string name="error_extraction">Error occured during extraction!</string>
|
||||
<string name="rockbox_extracting">Rockbox is loading. Please wait...</string>
|
||||
</resources>
|
||||
|
||||
<!-- Widget -->
|
||||
<string name="appwidget_label_4x1">Rockbox (line)</string>
|
||||
<string name="appwidget_label_2x2">Rockbox (square)</string>
|
||||
<string name="appwidget_infoDisplay">Touch to launch app</string>
|
||||
|
||||
<!-- Widget configuration -->
|
||||
<string name="appwidget_configure_instructions">Please chose elements to display in widget.</string>
|
||||
<string name="appwidget_configure_prev">Prev Button</string>
|
||||
<string name="appwidget_configure_stop">Stop Button</string>
|
||||
<string name="appwidget_configure_playpause">Play/Pause Button</string>
|
||||
<string name="appwidget_configure_next">Next Button</string>
|
||||
<string name="appwidget_configure_confirm">Create Widget</string>
|
||||
|
||||
</resources>
|
||||
|
|
18
android/res/values/style.xml
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<resources>
|
||||
<style name="appwidget_infodisplay">
|
||||
<item name="android:layout_width">1dp</item>
|
||||
<item name="android:layout_height">1dp</item>
|
||||
<item name="android:layout_weight">1</item>
|
||||
<item name="android:textColor">#cecfce</item>
|
||||
<item name="android:background">@drawable/appwidget_infodisplay_background</item>
|
||||
</style>
|
||||
<style name="appwidget_button">
|
||||
<item name="android:layout_width">40dp</item>
|
||||
<item name="android:layout_height">40dp</item>
|
||||
<item name="android:scaleType">fitCenter</item>
|
||||
<item name="android:background">@drawable/appwidget_infodisplay_background</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
8
android/res/xml/appwidget_provider_2x2.xml
Normal file
|
@ -0,0 +1,8 @@
|
|||
<!-- cell size is (number of cells * 74) - 2 dp according to http://developer.android.com/guide/topics/appwidgets/index.html#MetaData -->
|
||||
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:minWidth="146dp"
|
||||
android:minHeight="146dp"
|
||||
android:updatePeriodMillis="86400000"
|
||||
android:initialLayout="@layout/appwidget_2x2"
|
||||
android:configure="org.rockbox.widgets.RockboxWidgetConfigure">
|
||||
</appwidget-provider>
|
8
android/res/xml/appwidget_provider_4x1.xml
Normal file
|
@ -0,0 +1,8 @@
|
|||
<!-- cell size is (number of cells * 74) - 2 dp according to http://developer.android.com/guide/topics/appwidgets/index.html#MetaData -->
|
||||
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:minWidth="294dp"
|
||||
android:minHeight="72dp"
|
||||
android:updatePeriodMillis="86400000"
|
||||
android:initialLayout="@layout/appwidget_4x1"
|
||||
android:configure="org.rockbox.widgets.RockboxWidgetConfigure">
|
||||
</appwidget-provider>
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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)
|
||||
|
|
121
android/src/org/rockbox/widgets/RockboxWidgetConfigure.java
Normal 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;
|
||||
}
|
||||
}
|
171
android/src/org/rockbox/widgets/RockboxWidgetProvider.java
Normal 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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
{
|
||||
}
|
||||
|
|
@ -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
|
||||
{
|
||||
}
|
||||
|
|
@ -30,7 +30,7 @@ extern JNIEnv *env_ptr;
|
|||
extern jclass RockboxService_class;
|
||||
extern jobject RockboxService_instance;
|
||||
|
||||
static jmethodID updateNotification;
|
||||
static jmethodID updateNotification, finishNotification;
|
||||
static jobject NotificationManager_instance;
|
||||
static jstring title, artist, album;
|
||||
|
||||
|
@ -66,6 +66,16 @@ static void track_changed_callback(void *param)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* notify about track finishing */
|
||||
static void track_finished_callback(void *param)
|
||||
{
|
||||
(void)param;
|
||||
JNIEnv e = *env_ptr;
|
||||
e->CallVoidMethod(env_ptr, NotificationManager_instance,
|
||||
finishNotification);
|
||||
}
|
||||
|
||||
void notification_init(void)
|
||||
{
|
||||
JNIEnv e = *env_ptr;
|
||||
|
@ -79,6 +89,9 @@ void notification_init(void)
|
|||
"(Ljava/lang/String;"
|
||||
"Ljava/lang/String;"
|
||||
"Ljava/lang/String;)V");
|
||||
finishNotification = e->GetMethodID(env_ptr, class, "finishNotification",
|
||||
"()V");
|
||||
|
||||
add_event(PLAYBACK_EVENT_TRACK_CHANGE, false, track_changed_callback);
|
||||
add_event(PLAYBACK_EVENT_TRACK_FINISH, false, track_finished_callback);
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@ Java_org_rockbox_RockboxFramebuffer_touchHandler(JNIEnv*env, jobject this,
|
|||
* this writes in an interrupt-like fashion the button events that the user
|
||||
* generated by pressing/releasing them to a variable */
|
||||
JNIEXPORT bool JNICALL
|
||||
Java_org_rockbox_RockboxFramebuffer_buttonHandler(JNIEnv*env, jobject this,
|
||||
Java_org_rockbox_RockboxFramebuffer_buttonHandler(JNIEnv*env, jclass this,
|
||||
jint keycode, jboolean state)
|
||||
{
|
||||
(void)env;
|
||||
|
|