QSP под Android
Взялся недавно за портирование QSP на андроид.
Учитывая, что под андроид нельзя “напрямую” портировать написанный с использованием wxWidgets плеер, задача оказалась довольно сложной.
Разобравшись с доступными средствами, определился, как именно сделать порт, а именно:
- Библиотека QSP собирается в NDK.
- Для библиотеки делается “биндинг под ANDROID”.
- Для доступа к интерфейсу библиотеки через jni пишется специальный класс-прослойка.
- GUI пишется на Java.
Страница на Маркете: Quest Player
Плеер теперь умеет реагировать на нажатие ссылок.
Плеер научился проигрывать музыку!
Инвентарь и доп.описание можно сделать не вкладками а отдельными экранами и переходить через жесты.
Piligrim,
Так изначально и было задумано, но как это реализовать, быстро разобраться не смог.
Поэтому пришлось сделать вкладками.
Если есть рабочие рецепты, как сделать переключение экранов “как на рабочем столе” (перетаскиванием влево-вправо), прошу поделиться.
Попробовал плеер на “Сказка ночи”. На первом же действии Force Close:
Spoiler
11-17 12:23:27.720: WARN/dalvikvm(2964): threadid=1: thread exiting with uncaught exception (group=0x400207e8)
11-17 12:23:27.730: ERROR/AndroidRuntime(2964): FATAL EXCEPTION: main
11-17 12:23:27.730: ERROR/AndroidRuntime(2964): java.lang.NullPointerException
11-17 12:23:27.730: ERROR/AndroidRuntime(2964): at com.qsp.player.QspPlayerStart.CloseFile(QspPlayerStart.java:341)
11-17 12:23:27.730: ERROR/AndroidRuntime(2964): at com.qsp.player.QspPlayerStart.QSPExecuteSelActionCode(Native Method)
11-17 12:23:27.730: ERROR/AndroidRuntime(2964): at com.qsp.player.QspPlayerStart$2.onItemClick(QspPlayerStart.java:385)
11-17 12:23:27.730: ERROR/AndroidRuntime(2964): at android.widget.AdapterView.performItemClick(AdapterView.java:284)
11-17 12:23:27.730: ERROR/AndroidRuntime(2964): at android.widget.ListView.performItemClick(ListView.java:3382)
11-17 12:23:27.730: ERROR/AndroidRuntime(2964): at android.widget.AbsListView$PerformClick.run(AbsListView.java:1696)
11-17 12:23:27.730: ERROR/AndroidRuntime(2964): at android.os.Handler.handleCallback(Handler.java:587)
11-17 12:23:27.730: ERROR/AndroidRuntime(2964): at android.os.Handler.dispatchMessage(Handler.java:92)
11-17 12:23:27.730: ERROR/AndroidRuntime(2964): at android.os.Looper.loop(Looper.java:123)
11-17 12:23:27.730: ERROR/AndroidRuntime(2964): at android.app.ActivityThread.main(ActivityThread.java:4627)
11-17 12:23:27.730: ERROR/AndroidRuntime(2964): at java.lang.reflect.Method.invokeNative(Native Method)
11-17 12:23:27.730: ERROR/AndroidRuntime(2964): at java.lang.reflect.Method.invoke(Method.java:521)
11-17 12:23:27.730: ERROR/AndroidRuntime(2964): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
11-17 12:23:27.730: ERROR/AndroidRuntime(2964): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
11-17 12:23:27.730: ERROR/AndroidRuntime(2964): at dalvik.system.NativeStart.main(Native Method)
11-17 12:23:27.740: WARN/ActivityManager(125): Force finishing activity com.qsp.player/.QspPlayerStart
11-17 12:23:28.271: WARN/ActivityManager(125): Activity pause timeout for HistoryRecord{437845d8 com.qsp.player/.QspPlayerStart}
Листание пальцем где-то так можно. Если по простому, без анимации.
Spoiler
import android.app.Activity;
import android.os.Bundle;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.widget.LinearLayout;
import android.widget.TextView;
public class Main extends Activity {
public static final int SWIPE_MIN = 120;
public static final int SWIPE_THRESHOLD = 100;
public static final String DEBUG_TAG = "DEBUG";
GestureDetector gestures;
TextView text;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
LinearLayout frame = (LinearLayout) findViewById(R.id.holder);
text = new TextView(this);
gestures = new GestureDetector(Main.this, new GestureDetector.SimpleOnGestureListener() {
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
if(e1.getX() - e2.getX() > SWIPE_MIN && Math.abs(velocityX) > SWIPE_THRESHOLD) {
//swipe left
text.append("Simple left text.\n");
}else if(e2.getX() - e1.getX() > SWIPE_MIN && Math.abs(velocityX) > SWIPE_THRESHOLD) {
//swipe right
text.append("Simple right text.\n");
}
return true;
}
});
text.append("Simple text.\n");
frame.addView(text);
}
public boolean onTouchEvent(MotionEvent event) {
return gestures.onTouchEvent(event);
}
}
Piligrim,
спасибо за код! Попробую.
По “Сказке Ночи” исправил тот баг, но сразу же вылез другой баг. Поэтому пока что не заливал, буду искать.
Баг исправлен окончательно :)
Заработала локация-счетчик.
При инсталяции на симулятор пишет:
~/android-sdk-linux_x86/tools$ ./adb install QspPlayer.apk
203 KB/s (188386 bytes in 0.902s)
pkg: /data/local/tmp/QspPlayer.apk
Failure [INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION]
попробую на железе
Обновлений как я понимаю не было еще, это так сказать вести с полей?
Piligrim,
Было-было. Я все обновляю сразу. Пожалуй, буду писать дату и время, чтобы никто не путался.
Ntropy,
Нужна прошивка 2.2 чтоб все работало.
А почему нужна 2.2? Используется что-то, появившееся именно в ней? Еще прилично устройств на 1.6 и 2.0.
Для моего G1 вообще официальной 2.2 не предвидится. А многие не перешивают телефоны сами.
Вопрос: можно ли выкладывать чистый apk? и если не меняется его адрес, то добавить QR код, например с помощью http://qrcoder.ru/?t=l тогда можно будет легко скачивать прямо телефоном с помощью сканера кодов.
Piligrim,
под 1.6 у меня на винде не работает эмулятор. (Даже на 2.2 он запускается не всегда)
Поэтому, разрабатываю и собираю пока что для 2.2, так проще и быстрее.
Релиз “альфа-версии” постараюсь сделать для 1.6.
Piligrim,
Выкладывал в .zip, т.к. расширение .apk нужно прописать в настройках сайта, чтобы его можно было прикладывать к сообщению. Лень было в настройках сайта ковыряться. Ну раз надо, значит буду публиковать в .apk :) Не проблема!