forked from len0rd/rockbox
Use a Native keyboard GUI instead of rockbox's internal one on android
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@28407 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
26f7ee13ce
commit
eaff333bf5
11 changed files with 261 additions and 4 deletions
|
@ -17,7 +17,8 @@
|
||||||
</activity>
|
</activity>
|
||||||
<service android:name=".RockboxService"/>
|
<service android:name=".RockboxService"/>
|
||||||
|
|
||||||
</application>
|
<activity android:name="KeyboardActivity" android:launchMode="singleTop"></activity>
|
||||||
|
</application>
|
||||||
<uses-sdk android:minSdkVersion="4" />
|
<uses-sdk android:minSdkVersion="4" />
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|
4
android/res/layout/keyboardinput.xml
Normal file
4
android/res/layout/keyboardinput.xml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<AbsoluteLayout android:id="@+id/AbsoluteLayout01" android:layout_width="fill_parent" android:layout_height="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android"><EditText android:layout_height="wrap_content" android:text="Some Text" android:layout_width="fill_parent" android:id="@+id/KbdInput"></EditText>
|
||||||
|
</AbsoluteLayout>
|
|
@ -3,4 +3,7 @@
|
||||||
|
|
||||||
<string name="app_name">Rockbox</string>
|
<string name="app_name">Rockbox</string>
|
||||||
<string name="notification">Rockbox</string>
|
<string name="notification">Rockbox</string>
|
||||||
|
<string name="OK">OK</string>
|
||||||
|
<string name="Cancel">Cancel</string>
|
||||||
|
<string name="KbdInputTitle">Rockbox Keyboard Input</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
7
android/src/org/rockbox/HostCallback.java
Normal file
7
android/src/org/rockbox/HostCallback.java
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
package org.rockbox;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
|
|
||||||
|
public interface HostCallback {
|
||||||
|
public void onComplete(int resultCode, Intent data);
|
||||||
|
}
|
41
android/src/org/rockbox/KeyboardActivity.java
Normal file
41
android/src/org/rockbox/KeyboardActivity.java
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
package org.rockbox;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.text.Editable;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.EditText;
|
||||||
|
|
||||||
|
public class KeyboardActivity extends Activity {
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
LayoutInflater inflater=LayoutInflater.from(this);
|
||||||
|
View addView=inflater.inflate(R.layout.keyboardinput, null);
|
||||||
|
EditText input = (EditText) addView.findViewById(R.id.KbdInput);
|
||||||
|
input.setText(getIntent().getStringExtra("value"));
|
||||||
|
new AlertDialog.Builder(this)
|
||||||
|
.setTitle(R.string.KbdInputTitle)
|
||||||
|
.setView(addView)
|
||||||
|
.setIcon(R.drawable.icon)
|
||||||
|
.setPositiveButton(R.string.OK, new DialogInterface.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int whichButton) {
|
||||||
|
EditText input = (EditText)((Dialog)dialog).findViewById(R.id.KbdInput);
|
||||||
|
Editable s = input.getText();
|
||||||
|
getIntent().putExtra("value", s.toString());
|
||||||
|
setResult(RESULT_OK, getIntent());
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.setNegativeButton(R.string.Cancel, new DialogInterface.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int whichButton) {
|
||||||
|
setResult(RESULT_CANCELED, getIntent());
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.show();
|
||||||
|
}
|
||||||
|
}
|
|
@ -24,7 +24,9 @@ package org.rockbox;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.ProgressDialog;
|
import android.app.ProgressDialog;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.Window;
|
import android.view.Window;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
|
@ -41,6 +43,7 @@ public class RockboxActivity extends Activity
|
||||||
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN
|
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN
|
||||||
,WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
,WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||||
|
final Activity thisActivity = this;
|
||||||
final Intent intent = new Intent(this, RockboxService.class);
|
final Intent intent = new Intent(this, RockboxService.class);
|
||||||
/* prepare a please wait dialog in case we need
|
/* prepare a please wait dialog in case we need
|
||||||
* to wait for unzipping libmisc.so
|
* to wait for unzipping libmisc.so
|
||||||
|
@ -95,7 +98,8 @@ public class RockboxActivity extends Activity
|
||||||
loadingdialog.dismiss();
|
loadingdialog.dismiss();
|
||||||
if (rbservice.get_fb() == null)
|
if (rbservice.get_fb() == null)
|
||||||
throw new IllegalStateException("FB NULL");
|
throw new IllegalStateException("FB NULL");
|
||||||
setContentView(rbservice.get_fb());
|
rbservice.set_activity(thisActivity);
|
||||||
|
setContentView(rbservice.get_fb());
|
||||||
rbservice.get_fb().invalidate();
|
rbservice.get_fb().invalidate();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -111,6 +115,7 @@ public class RockboxActivity extends Activity
|
||||||
|
|
||||||
public void onResume()
|
public void onResume()
|
||||||
{
|
{
|
||||||
|
|
||||||
super.onResume();
|
super.onResume();
|
||||||
if (isRockboxRunning())
|
if (isRockboxRunning())
|
||||||
{
|
{
|
||||||
|
@ -123,6 +128,7 @@ public class RockboxActivity extends Activity
|
||||||
g.removeView(rbservice.get_fb());
|
g.removeView(rbservice.get_fb());
|
||||||
setContentView(rbservice.get_fb());
|
setContentView(rbservice.get_fb());
|
||||||
} finally {
|
} finally {
|
||||||
|
rbservice.set_activity(this);
|
||||||
rbservice.get_fb().resume();
|
rbservice.get_fb().resume();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -135,6 +141,7 @@ public class RockboxActivity extends Activity
|
||||||
protected void onPause()
|
protected void onPause()
|
||||||
{
|
{
|
||||||
super.onPause();
|
super.onPause();
|
||||||
|
rbservice.set_activity(null);
|
||||||
rbservice.get_fb().suspend();
|
rbservice.get_fb().suspend();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,6 +149,7 @@ public class RockboxActivity extends Activity
|
||||||
protected void onStop()
|
protected void onStop()
|
||||||
{
|
{
|
||||||
super.onStop();
|
super.onStop();
|
||||||
|
rbservice.set_activity(null);
|
||||||
rbservice.get_fb().suspend();
|
rbservice.get_fb().suspend();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,6 +157,29 @@ public class RockboxActivity extends Activity
|
||||||
protected void onDestroy()
|
protected void onDestroy()
|
||||||
{
|
{
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
|
rbservice.set_activity(null);
|
||||||
rbservice.get_fb().suspend();
|
rbservice.get_fb().suspend();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private HostCallback hostcallback = null;
|
||||||
|
public void waitForActivity(Intent i, HostCallback callback)
|
||||||
|
{
|
||||||
|
if (hostcallback != null)
|
||||||
|
{
|
||||||
|
LOG("Something has gone wrong");
|
||||||
|
}
|
||||||
|
hostcallback = callback;
|
||||||
|
startActivityForResult(i, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onActivityResult(int requestCode, int resultCode, Intent data)
|
||||||
|
{
|
||||||
|
hostcallback.onComplete(resultCode, data);
|
||||||
|
hostcallback = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LOG(CharSequence text)
|
||||||
|
{
|
||||||
|
Log.d("Rockbox", (String) text);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,12 +118,11 @@ public class RockboxFramebuffer extends View
|
||||||
setFocusableInTouchMode(true);
|
setFocusableInTouchMode(true);
|
||||||
setClickable(true);
|
setClickable(true);
|
||||||
requestFocus();
|
requestFocus();
|
||||||
/* make updates again, the underlying function will
|
|
||||||
* send an event */
|
|
||||||
set_lcd_active(1);
|
set_lcd_active(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public native void set_lcd_active(int active);
|
public native void set_lcd_active(int active);
|
||||||
public native void touchHandler(boolean down, int x, int y);
|
public native void touchHandler(boolean down, int x, int y);
|
||||||
public native boolean buttonHandler(int keycode, boolean state);
|
public native boolean buttonHandler(int keycode, boolean state);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
69
android/src/org/rockbox/RockboxKeyboardInput.java
Normal file
69
android/src/org/rockbox/RockboxKeyboardInput.java
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* __________ __ ___.
|
||||||
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||||
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||||
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||||
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||||
|
* \/ \/ \/ \/ \/
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 Jonathan Gordon
|
||||||
|
*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
public class RockboxKeyboardInput
|
||||||
|
{
|
||||||
|
private BroadcastReceiver b;
|
||||||
|
private String result;
|
||||||
|
|
||||||
|
public RockboxKeyboardInput()
|
||||||
|
{
|
||||||
|
result = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void kbd_input(String text)
|
||||||
|
{
|
||||||
|
RockboxActivity a = (RockboxActivity) RockboxService.get_instance().get_activity();
|
||||||
|
Intent kbd = new Intent(a, KeyboardActivity.class);
|
||||||
|
kbd.putExtra("value", text);
|
||||||
|
a.waitForActivity(kbd, new HostCallback(){
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onComplete(int resultCode, Intent data) {
|
||||||
|
if (resultCode == Activity.RESULT_OK)
|
||||||
|
{
|
||||||
|
result = data.getStringExtra("value");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
public String get_result()
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean is_usable()
|
||||||
|
{
|
||||||
|
return RockboxService.get_instance().get_activity() != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -35,6 +35,7 @@ import java.util.TimerTask;
|
||||||
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipEntry;
|
||||||
import java.util.zip.ZipFile;
|
import java.util.zip.ZipFile;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
import android.app.Notification;
|
import android.app.Notification;
|
||||||
import android.app.NotificationManager;
|
import android.app.NotificationManager;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
|
@ -61,6 +62,7 @@ public class RockboxService extends Service
|
||||||
/* locals needed for the c code and rockbox state */
|
/* locals needed for the c code and rockbox state */
|
||||||
private RockboxFramebuffer fb = null;
|
private RockboxFramebuffer fb = null;
|
||||||
private boolean mRockboxRunning = false;
|
private boolean mRockboxRunning = false;
|
||||||
|
private Activity current_activity = null;
|
||||||
|
|
||||||
private Notification notification;
|
private Notification notification;
|
||||||
private static final Class<?>[] mStartForegroundSignature =
|
private static final Class<?>[] mStartForegroundSignature =
|
||||||
|
@ -113,6 +115,16 @@ public class RockboxService extends Service
|
||||||
fb = newfb;
|
fb = newfb;
|
||||||
mRockboxRunning = true;
|
mRockboxRunning = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Activity get_activity()
|
||||||
|
{
|
||||||
|
return current_activity;
|
||||||
|
}
|
||||||
|
public void set_activity(Activity a)
|
||||||
|
{
|
||||||
|
current_activity = a;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private void do_start(Intent intent)
|
private void do_start(Intent intent)
|
||||||
{
|
{
|
||||||
|
|
|
@ -116,7 +116,11 @@ player/keyboard.c
|
||||||
#ifdef HAVE_LCD_BITMAP
|
#ifdef HAVE_LCD_BITMAP
|
||||||
recorder/bmp.c
|
recorder/bmp.c
|
||||||
recorder/icons.c
|
recorder/icons.c
|
||||||
|
#if (CONFIG_PLATFORM&PLATFORM_ANDROID)
|
||||||
|
hosted/keyboard.c
|
||||||
|
#else
|
||||||
recorder/keyboard.c
|
recorder/keyboard.c
|
||||||
|
#endif
|
||||||
recorder/peakmeter.c
|
recorder/peakmeter.c
|
||||||
#if defined(HAVE_ALBUMART) || defined(HAVE_JPEG)
|
#if defined(HAVE_ALBUMART) || defined(HAVE_JPEG)
|
||||||
recorder/resize.c
|
recorder/resize.c
|
||||||
|
|
86
apps/hosted/keyboard.c
Normal file
86
apps/hosted/keyboard.c
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* __________ __ ___.
|
||||||
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||||
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||||
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||||
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||||
|
* \/ \/ \/ \/ \/
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 Jonathan Gordon
|
||||||
|
*
|
||||||
|
* 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 "config.h"
|
||||||
|
|
||||||
|
#if (CONFIG_PLATFORM&PLATFORM_ANDROID)
|
||||||
|
#include <jni.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <system.h>
|
||||||
|
|
||||||
|
extern JNIEnv *env_ptr;
|
||||||
|
static jclass RockboxKeyboardInput_class = NULL;
|
||||||
|
static jobject RockboxKeyboardInput_instance;
|
||||||
|
static jmethodID kbd_inputfunc, kbd_result;
|
||||||
|
|
||||||
|
static void kdb_init(void)
|
||||||
|
{
|
||||||
|
JNIEnv e = *env_ptr;
|
||||||
|
jmethodID kbd_is_usable;
|
||||||
|
if (RockboxKeyboardInput_class == NULL)
|
||||||
|
{
|
||||||
|
/* get the class and its constructor */
|
||||||
|
RockboxKeyboardInput_class = e->FindClass(env_ptr, "org/rockbox/RockboxKeyboardInput");
|
||||||
|
jmethodID constructor = e->GetMethodID(env_ptr, RockboxKeyboardInput_class, "<init>", "()V");
|
||||||
|
RockboxKeyboardInput_instance = e->NewObject(env_ptr, RockboxKeyboardInput_class, constructor);
|
||||||
|
kbd_inputfunc = e->GetMethodID(env_ptr, RockboxKeyboardInput_class,
|
||||||
|
"kbd_input", "(Ljava/lang/String;)V");
|
||||||
|
kbd_result = e->GetMethodID(env_ptr, RockboxKeyboardInput_class,
|
||||||
|
"get_result", "()Ljava/lang/String;");
|
||||||
|
}
|
||||||
|
/* need to get it every time incase the activity died/restarted */
|
||||||
|
kbd_is_usable = e->GetMethodID(env_ptr, RockboxKeyboardInput_class,
|
||||||
|
"is_usable", "()Z");
|
||||||
|
while (!e->CallBooleanMethod(env_ptr, RockboxKeyboardInput_instance, kbd_is_usable))
|
||||||
|
sleep(HZ/10);
|
||||||
|
}
|
||||||
|
|
||||||
|
int kbd_input(char* text, int buflen)
|
||||||
|
{
|
||||||
|
JNIEnv e = *env_ptr;
|
||||||
|
jstring str = e->NewStringUTF(env_ptr, text);
|
||||||
|
jobject ret;
|
||||||
|
const char* retchars;
|
||||||
|
kdb_init();
|
||||||
|
|
||||||
|
e->CallVoidMethod(env_ptr, RockboxKeyboardInput_instance, kbd_inputfunc, str);
|
||||||
|
|
||||||
|
do {
|
||||||
|
sleep(HZ/10);
|
||||||
|
ret = e->CallObjectMethod(env_ptr, RockboxKeyboardInput_instance, kbd_result);
|
||||||
|
} while (!ret);
|
||||||
|
|
||||||
|
e->ReleaseStringChars(env_ptr, str, NULL);
|
||||||
|
retchars = e->GetStringUTFChars(env_ptr, ret, 0);
|
||||||
|
if (retchars[0])
|
||||||
|
snprintf(text, buflen, retchars);
|
||||||
|
e->ReleaseStringUTFChars(env_ptr, ret, retchars);
|
||||||
|
|
||||||
|
return retchars[0]?0:1; /* return 0 on success */
|
||||||
|
}
|
||||||
|
|
||||||
|
int load_kbd(unsigned char* filename)
|
||||||
|
{
|
||||||
|
(void)filename;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Loading…
Add table
Add a link
Reference in a new issue