Revision: 366
Author: onnerby
Date: Wed Jul 29 15:56:39 2009
Log: More on the android client.
http://code.google.com/p/musikcube/source/detail?r=366
Added:
/trunk/src/android/res/drawable/ic_media_next.png
/trunk/src/android/res/drawable/ic_media_pause.png
/trunk/src/android/res/drawable/ic_media_play.png
/trunk/src/android/res/drawable/ic_media_previous.png
/trunk/src/android/res/drawable/ic_menu_help.png
/trunk/src/android/res/drawable/ic_menu_preferences.png
/trunk/src/android/res/drawable/
mc_launcher.ai
/trunk/src/android/res/drawable/mc_notify.png
/trunk/src/android/res/layout/category_list_item.xml
/trunk/src/android/res/layout/play_control.xml
/trunk/src/android/res/menu
/trunk/src/android/res/menu/default_menu.xml
/trunk/src/android/res/values/styles.xml
/trunk/src/android/res/xml
/trunk/src/android/res/xml/preferences.xml
/trunk/src/android/src/org/musikcube/Preferences.java
/trunk/src/android/src/org/musikcube/core/MetadataQuery.java
/trunk/src/android/src/org/musikcube/core/Player.java
/trunk/src/android/src/org/musikcube/core/Track.java
/trunk/src/android/src/org/musikcube/core/TrackPlayer.java
Modified:
/trunk/src/android/.classpath
/trunk/src/android/AndroidManifest.xml
/trunk/src/android/res/drawable/icon.png
/trunk/src/android/res/values/strings.xml
/trunk/src/android/src/doep/xml/Reader.java
/trunk/src/android/src/doep/xml/ReaderNode.java
/trunk/src/android/src/doep/xml/Writer.java
/trunk/src/android/src/org/musikcube/App.java
/trunk/src/android/src/org/musikcube/CategoryList.java
/trunk/src/android/src/org/musikcube/Service.java
/trunk/src/android/src/org/musikcube/TrackList.java
/trunk/src/android/src/org/musikcube/core/IQuery.java
/trunk/src/android/src/org/musikcube/core/Library.java
/trunk/src/android/src/org/musikcube/core/ListQuery.java
/trunk/src/android/src/org/musikcube/main.java
=======================================
--- /dev/null
+++ /trunk/src/android/res/drawable/ic_media_next.png Wed Jul 29 15:56:39
2009
@@ -0,0 +1,32 @@
+‰PNG
+
+
+IHDR szzô tEXtSoftware Adobe
ImageReadyqÉe< ¿IDATxÚìW_L[U ¿°#¹] ´Ó9ºA\ ‹câ²[²D
+‹¦ 3.{ b¢Öh dËF³d[ &DåÉ Ãö°058|1@¦\HÊ:²²Ýe ì
+º\H”Ý #u*¶ ’6£z¯p þÎm諒¥Èæƒ1áÜœ|§ß=¿ïû ïûι§ ‹‹‹Ì Ù
+Ö ¬ 8qìD ¤ }¢ãtÇÔj@¾ã¾* Š fæ_ 8÷å¹Ï]»]œ$I ¡[¡~ènÃè¯+8 Þ]ïþÐn·—aþXd2r ê `
+‰ xK¼,Ëò"íw¤;bÛ m #*µ45Ëu¼kŠF£÷äY`fåù+7®\„î-ôgóaVêDa †Q †JÇV ç;êsðCüF¬´ ü®ceÉ
+Ö˜Ï M ×.×+ŽrǶ޾ÞA`†1ÿêC¤0¼®¹¥ùmû“ö§ ,*
+à –ÝùÜNζÑV. K[‚—‚‰½/ï éà` ÈqµÜK%E%¥”4Å•¬/Ùà¬vrê‚ZÜýY÷\p$x ˜d
+çuHá{®:×þɩɊB}õôañh AmpUÜ‹˜Ül¯°7y xëu ô½ OzÞ –°ëaøuÏAÏGP{½G½/ä
ÀnW «¾r{eÝŽm;Ê 3¿ VÃ(I¥
+µ²[š 4 B±9@b -Pª—U™aU–:e UÑÒA%] ÒXí;éÛ l Æ
+̵ÎO;å¬ô¥;µS(3rJaÎñ’, ãýGZÛVë!Í¡
+
+}¬.EG#β 7¾Ñx ᵆw1ç}ïAo•ŽI(‰¬¹
+9Îó4{¹};Âz¸fO û 1©÷뜜ÓÝv²í
+k™µ¥¥©¥Þˆ´ª ’d8ÍŒ†rÙ1a‹ _mô(Š¢ê)Óë&K"
+4E´Ùž°=
+T
+ ®
+ ž7=EP•dF¸P £ž 3 ]oŒS[ dêt’z£ÎõâÔRBØ¢}õû Áv ¯ÐÓnD ³¢3 f’ÉØû©¢3 Ó
+ éæ@ÿ Æ @W í¢t ˆ6Ye³Hd9Ö ¥ ò ÍqÎ|ÝY¦>õ{N ‚=}=] s´ú-Ä’.ÂeÂonF TFæ ùóñ™øô
+Å—5Ž'âÓ8
+»ø>þLÀ ª|
¦r–F€6 gú(^E‹Æ¢wÏv õG ‰Ž»÷¸kV Y GÅ›Ý_t_C¸y8 Ó´H ‹š"AŒ 2å8Cª¡pHà¿á¿¢g·µØZ›óM059)' † Å°Ø 3á&ßËßÏ9;Ò8l¬ì
+Ît
+OÆ †
+þÈÏ ?Î ¡ã“Žyœrµ†S3a ©™èwü AI* žÞžoÍä°à?
þD‘–âP’I–c} Dfbwc!þ"/À° ŽÃ&#Œ ‡°þ5
+õ‡n„ÎC FÞ ÊSO·O 9ÕŽáfØ Ëc–ìÕ¨Ì,
+^ •ú¡ ÁyÜ\h´ÚµBJcPh÷ r
+÷„áÎÓ —W*¼ é5ÄàO ‚îYj, ‹Œó_óC‰d‚ ºžoGÐù †a
+ˆ’(Ày/ýP óýÃ^ˆ ®TS¶b›Uš”&ñÕãÓ†~Ì €k ×·QÜ ¦QdcÀù¡ €™{¤;aë±ÖÍ Õ0ü ò6± ÷¸w Ä&z)
+ãßÖþ ¬ ø_ ø[€ BÌ®¤Sà‰ IEND®B`‚
=======================================
--- /dev/null
+++ /trunk/src/android/res/drawable/ic_media_pause.png Wed Jul 29 15:56:39
2009
Binary file, no diff available.
=======================================
--- /dev/null
+++ /trunk/src/android/res/drawable/ic_media_play.png Wed Jul 29 15:56:39
2009
Binary file, no diff available.
=======================================
--- /dev/null
+++ /trunk/src/android/res/drawable/ic_media_previous.png Wed Jul 29
15:56:39 2009
@@ -0,0 +1,33 @@
+‰PNG
+
+
+IHDR szzô tEXtSoftware Adobe
ImageReadyqÉe< ±IDATxÚìWoh e ¿¤—q‘s,Ådnl‡uë B3[0q[i1™M 5¹îƒ‰ìC; $ìà d Z Cf((í
+¬¢Ä²A&®6⪠²‘2ªÍF\2 k±e\\ é\5§ÞVŸ÷š÷r¹.¶Ý>ôKßãxïž{þüžßû¼ N³°°@¬eÓ kÜÖ ¬9 òq
+„ ‡LÐ5À ÷† Z¡Í3Ðí„{Bó¨³ œ ö
+̳L»Ýfoày>Ÿ M¼ Òÿc³ ºFÐï`Yvgr,™" 18BßÄù8¿µÁê
+I‹É2
+ š@ž®bó e Ü à f;cE²¹ù¹{$|x 9[)
+ ßB×Òm]oty) U'
E‚(ÂUEß ÝÞ]Ö]^W›« @ ‘¾\ ´ ~×åsíA ‚òG âr Gf0l²·Øý-¯R$õ„@ Ò7Ôëá DAmƒjà Y73õÌ^Š 4H zÉ ! –1³õìnf s (L‚Á ¡C¡ Á¦½«³ Ñ÷ ¬lE±’ à¡ ƒeX ·ŸóQFêi
+TÙ#ÖHÉ—¸˜
+:ƒà;A=tÍìó,Çy9/EQ›°Ž@.f€û È Ux£Ëãz ŠÍ Ï ° µ þ_=A" 22¡
øVð9 ÞÍZÙf ÕT Ë=²•œ 8³Éüvà@Àc1[ê Z
+»J Pf¥ø ; :`HÜþ þ×i ½m¹ÂÄìÙöØZÝmî×€)ƒ h¹9†j@¦
+^
+ba# ŒÛíuwB¡µCf $vÄò¸á€êgÚHoæ<\@
+*ª²
+b/ ÀÓH ¶†Ž„<L
+Ó( Zɉ²x”™+ä$v*W¹Â 7µ - kàcyªà‚
+Š` ÁU:¸à”áÀÊw¬«ÅÆ¥6
+>
+îI\L| ² ä"#©r wQñN–Þ âþ²º"Q!“ 0šŒ2=ìvö^ì|l8: ý ¤ Â\á–
+`E 2spñwø[±/bg`& «êªd¨×êI=¡ © œ ÍÞÈF޾wtp"5q
DËîXˆâøpü±ãÇNñyþ— m*h ”+˜2S q Öí £ŸE?ˆ
+Å>)
+ʇV·âÙh4 ÀÚ@øD¸'9ž¼ ßÄ%6
+}4\ZD™4n ñ Ü * F? þ ý< Ÿâ§"‘Ó‘S@sZžß%Gò& 2X| ÐÿÙ²År&y1Ù C2P
+·—œ@ðÌ2PD
+³ƒÑ$.%rcWƆ Æ œûœ¼š)§Ã9 ÿ:žK§Ò9p 1YLu:R'M; V·Èž
ÜM]K} º)¸ €ŸÉ³±³³ÙkÙùÚMµ$,h[ X
+\ø
+6{gvjÕ X'^FÛ±Ïëã`'݆g ?ÏOGNFz xOWì'G‚4dl·[í
+¶ GSôF<{2éÌw«> Âø~ [÷`ÿÉþîL63
+¬ÝGÅ«^ppë;ÑWèëí I¦’ƒ‘ÁH? èu4ä¥a'jº»»W}"rísÝN|“Ȥo¦óàp^§×‰333“¹_sCð-_Åæ·s_ž›
+O ß H
+ùwêFêºæqÿŒ‚‡ƒO• ¥¿C¦WWhƒŽt;€‡ 5ë¿fë Ö À cÄãWà IEND®B`‚
=======================================
--- /dev/null
+++ /trunk/src/android/res/drawable/ic_menu_help.png Wed Jul 29 15:56:39
2009
Binary file, no diff available.
=======================================
--- /dev/null
+++ /trunk/src/android/res/drawable/ic_menu_preferences.png Wed Jul 29
15:56:39 2009
Binary file, no diff available.
=======================================
--- /dev/null
+++ /trunk/src/android/res/drawable/
mc_launcher.ai Wed Jul 29 15:56:39 2009
Binary file, no diff available.
=======================================
--- /dev/null
+++ /trunk/src/android/res/drawable/mc_notify.png Wed Jul 29 15:56:39 2009
Binary file, no diff available.
=======================================
--- /dev/null
+++ /trunk/src/android/res/layout/category_list_item.xml Wed Jul 29
15:56:39 2009
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+ <LinearLayout xmlns:android="
http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:paddingLeft="8dp"
+ android:paddingRight="8dp">
+
+ <ListView android:id="@id/android:list"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:layout_weight="1"
+ android:drawSelectorOnTop="false"/>
+
+ <TextView android:id="@id/android:empty"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:text="Loading...."/>
+ </LinearLayout>
=======================================
--- /dev/null
+++ /trunk/src/android/res/layout/play_control.xml Wed Jul 29 15:56:39 2009
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+ <LinearLayout xmlns:android="
http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:paddingLeft="8dp"
+ android:paddingRight="8dp" android:gravity="center">
+<LinearLayout android:id="@+id/LinearLayout01"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal">
+ <ImageButton android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="@+id/MediaPrev"
android:clickable="true" android:src="@drawable/ic_media_previous"
android:adjustViewBounds="true"></ImageButton>
+ <ImageButton android:layout_width="wrap_content"
android:layout_height="wrap_content" android:adjustViewBounds="true"
android:id="@+id/MediaPause"
android:src="@drawable/ic_media_pause"></ImageButton>
+ <ImageButton android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="@+id/MediaNext"
android:adjustViewBounds="true"
android:src="@drawable/ic_media_next"></ImageButton>
+</LinearLayout>
+
+</LinearLayout>
=======================================
--- /dev/null
+++ /trunk/src/android/res/menu/default_menu.xml Wed Jul 29 15:56:39 2009
@@ -0,0 +1,2 @@
+<menu xmlns:android="
http://schemas.android.com/apk/res/android"><item
android:title="@string/menu_settings" android:id="@+id/context_settings"
android:enabled="true" android:visible="true"></item>
+</menu>
=======================================
--- /dev/null
+++ /trunk/src/android/res/values/styles.xml Wed Jul 29 15:56:39 2009
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+
http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+
+</resources>
=======================================
--- /dev/null
+++ /trunk/src/android/res/xml/preferences.xml Wed Jul 29 15:56:39 2009
@@ -0,0 +1,14 @@
+<PreferenceScreen
xmlns:android="
http://schemas.android.com/apk/res/android">
+
+
+<PreferenceCategory android:title="Connection">
+<EditTextPreference android:key="@string/host" android:enabled="true"
android:title="Host" android:dialogMessage="Hostname or IP to musikServer"
android:summary="Hostname or IP to musikServer" android:dialogTitle="Host"
android:selectable="true"
android:defaultValue="
vallgraven.intermezzon.com"></EditTextPreference>
+<EditTextPreference android:key="@string/queryport" android:enabled="true"
android:inputType="number" android:title="Query port"
android:dialogMessage="TCP port for querying musikServer"
android:summary="TCP port for querying musikServer"
android:dialogTitle="Query port"
android:defaultValue="10543"></EditTextPreference>
+<EditTextPreference android:key="@string/httpport" android:enabled="true"
android:inputType="number" android:title="HTTP port"
android:dialogMessage="TCP port for streaming music" android:summary="TCP
port for streaming music" android:dialogTitle="HTTP port"
android:defaultValue="10544"></EditTextPreference>
+
+</PreferenceCategory>
+<PreferenceCategory android:title="Authentication">
+<EditTextPreference android:key="@string/username" android:enabled="true"
android:title="Username" android:summary="Username to identify yourself to
the musikServer" android:dialogTitle="Username"
android:defaultValue="doep"></EditTextPreference>
+<EditTextPreference android:dialogTitle="Password"
android:key="@string/password" android:inputType="textPassword"
android:enabled="true" android:title="Password" android:summary="Password
on the musikServer" android:defaultValue="doep"></EditTextPreference>
+</PreferenceCategory>
+</PreferenceScreen>
=======================================
--- /dev/null
+++ /trunk/src/android/src/org/musikcube/Preferences.java Wed Jul 29
15:56:39 2009
@@ -0,0 +1,35 @@
+package org.musikcube;
+
+import android.os.Bundle;
+import android.preference.PreferenceActivity;
+
+public class Preferences extends PreferenceActivity {
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ addPreferencesFromResource(R.xml.preferences);
+ }
+
+ @Override
+ protected void onStop() {
+ // TODO Auto-generated method stub
+ super.onStop();
+ // Let the library know to restart connection
+ org.musikcube.core.Library.GetInstance().Restart();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ org.musikcube.core.Library.GetInstance().RemovePointer();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ org.musikcube.core.Library.GetInstance().AddPointer();
+ }
+
+}
=======================================
--- /dev/null
+++ /trunk/src/android/src/org/musikcube/core/MetadataQuery.java Wed Jul 29
15:56:39 2009
@@ -0,0 +1,72 @@
+package org.musikcube.core;
+
+import doep.xml.ReaderNode;
+import doep.xml.WriterNode;
+
+public class MetadataQuery extends IQuery {
+
+ public java.util.ArrayList<Integer> requestedTracks = new
java.util.ArrayList<Integer>();
+ public java.util.ArrayList<String> requestedMetakeys = new
java.util.ArrayList<String>();
+ public java.util.ArrayList<Track> resultTracks = new
java.util.ArrayList<Track>();
+
+ public MetadataQuery() {
+ super();
+ this.type = "TrackMetadata";
+ }
+
+
+ @Override
+ public void SendQuery(WriterNode node)
+ throws Exception
+ {
+ WriterNode queryNode = this.SendQueryNode(node);
+
+ WriterNode metakeysNode = queryNode.ChildNode("metakeys");
+
+ String metakeys = "";
+ int metakeysCount = this.requestedMetakeys.size();
+ for(int i=0;i<metakeysCount;i++){
+ if(i!=0){
+ metakeys += ",";
+ }
+ metakeys += this.requestedMetakeys.get(i);
+ }
+ metakeysNode.content = metakeys;
+
+ WriterNode tracksNode = queryNode.ChildNode("tracks");
+ String tracks = "";
+ int tracksCount = this.requestedTracks.size();
+ for(int i=0;i<tracksCount;i++){
+ if(i!=0){
+ tracks += ",";
+ }
+ tracks += this.requestedTracks.get(i).toString();
+ }
+ tracksNode.content = tracks;
+
+ queryNode.End();
+ }
+
+ @Override
+ public void ReceiveQueryResult(ReaderNode node)
+ throws Exception
+ {
+
+ ReaderNode trackNode = null;
+ while( (trackNode=node.ChildNode("t"))!=null ){
+ Track track = new Track();
+
track.id = Integer.parseInt(trackNode.attributes.get("id"));
+
+ ReaderNode mdNode = null;
+ while( (mdNode=trackNode.ChildNode("md"))!=null ){
+ mdNode.End();
+ track.metadata.put(mdNode.attributes.get("k"), mdNode.content);
+ }
+ }
+
+ if(this.listener!=null){
+ this.listener.OnQueryResults();
+ }
+ }
+
+}
=======================================
--- /dev/null
+++ /trunk/src/android/src/org/musikcube/core/Player.java Wed Jul 29
15:56:39 2009
@@ -0,0 +1,119 @@
+package org.musikcube.core;
+
+import java.util.ArrayList;
+
+import android.content.Intent;
+
+public class Player implements TrackPlayer.OnTrackStatusListener{
+
+ private ArrayList<Integer> nowPlaying = new ArrayList<Integer>();
+ private int position = 0;
+ private Library library;
+
+ private java.lang.Object lock = new java.lang.Object();
+
+ private ArrayList<TrackPlayer> playingTracks = new
ArrayList<TrackPlayer>();
+
+ public android.app.Service service;
+
+ public void run() {
+ }
+
+ private static org.musikcube.core.Player player = null;
+
+ public static final synchronized Player GetInstance(){
+ if(Player.player==null){
+ Player.player = new org.musikcube.core.Player();
+ }
+ return Player.player;
+ }
+/*
+ private synchronized void StartThread(){
+ synchronized(lock){
+ if(this.running==false){
+ this.thread = new Thread(this);
+ this.running = true;
+ this.thread.start();
+ }
+ }
+ }
+ */
+
+ public void Play(java.util.ArrayList<Integer> playlist,int position){
+
+ synchronized(this.lock){
+ this.nowPlaying = playlist;
+ this.position = position;
+ }
+
+ this.Play();
+ }
+
+ public void Play(){
+ this.Startup();
+ this.StopAllTracks();
+
+ synchronized(this.lock){
+ String url
= "http://"+this.library.host+":"+this.library.httpPort+"/track/?track_id="+this.nowPlaying.get(this.position)+"&auth_key="+this.library.authorization;
+ TrackPlayer player = new TrackPlayer(url,true);
+ player.listener = this;
+ this.playingTracks.add(player);
+ }
+
+ }
+
+ public void Next(){
+ synchronized(this.lock){
+ this.position++;
+ if(this.position>=this.nowPlaying.size()){
+ this.StopAllTracks();
+ this.End();
+ }else{
+ this.Play();
+ }
+ }
+ }
+
+ private void StopAllTracks(){
+ synchronized(this.lock){
+ int trackCount = this.playingTracks.size();
+ for(int i=0;i<trackCount;i++){
+ this.playingTracks.get(i).listener = null;
+ this.playingTracks.get(i).Stop();
+ }
+ this.playingTracks.clear();
+ }
+ }
+
+ private void Startup(){
+ synchronized(this.lock){
+ if(this.library==null){
+ this.library = Library.GetInstance();
+ this.library.AddPointer();
+ }
+ }
+ }
+
+ private void End(){
+ synchronized(this.lock){
+ if(this.library!=null){
+ this.library.RemovePointer();
+ this.library = null;
+
+ Intent intent = new Intent(this.service, org.musikcube.Service.class);
+ intent.putExtra("org.musikcube.Service.action", "player ended");
+ this.service.startService(intent);
+
+ }
+ }
+ }
+
+ public void OnTrackStatusUpdate(TrackPlayer trackPlayer,int status) {
+// this.Next();
+ Intent intent = new Intent(this.service, org.musikcube.Service.class);
+ intent.putExtra("org.musikcube.Service.action", "next");
+ this.service.startService(intent);
+ }
+
+
+}
=======================================
--- /dev/null
+++ /trunk/src/android/src/org/musikcube/core/Track.java Wed Jul 29
15:56:39 2009
@@ -0,0 +1,6 @@
+package org.musikcube.core;
+
+public class Track {
+ public int id = 0;
+ public java.util.TreeMap<String, String> metadata = new
java.util.TreeMap<String, String>();
+}
=======================================
--- /dev/null
+++ /trunk/src/android/src/org/musikcube/core/TrackPlayer.java Wed Jul 29
15:56:39 2009
@@ -0,0 +1,145 @@
+package org.musikcube.core;
+
+import android.media.MediaPlayer;
+
+public class TrackPlayer implements Runnable,
MediaPlayer.OnCompletionListener, MediaPlayer.OnErrorListener {
+
+ private Thread thread;
+ private String url;
+ private java.lang.Object lock = new java.lang.Object();
+ private MediaPlayer mediaPlayer;
+
+ private int status = 1;
+
+ private static final int STATUS_PREPARED = 1;
+ private static final int STATUS_PLAYING = 2;
+ private static final int STATUS_PAUSE = 3;
+ private static final int STATUS_EXIT = 10;
+
+ public void run() {
+ this.mediaPlayer = new MediaPlayer();
+ try {
+
+ this.mediaPlayer.setOnCompletionListener(this);
+ this.mediaPlayer.setOnErrorListener(this);
+
+ this.mediaPlayer.setDataSource(this.url);
+ this.mediaPlayer.prepare();
+
+ synchronized(this.lock){
+ while(this.status==STATUS_PREPARED)
+ this.lock.wait();
+ }
+
+ int currentStatus = 0;
+ synchronized(this.lock){
+ currentStatus = this.status;
+ }
+
+ if(currentStatus==STATUS_PLAYING)
+ this.mediaPlayer.start();
+
+ synchronized(this.lock){
+ while(this.status==STATUS_PLAYING)
+ this.lock.wait();
+ }
+
+ this.mediaPlayer.stop();
+
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ synchronized(this.lock){
+ this.status = STATUS_EXIT;
+ }
+ }
+
+ this.CallListener();
+
+ }
+
+ public TrackPlayer(String url){
+ this.url = url;
+ this.thread = new Thread(this);
+ this.thread.start();
+ }
+
+ public TrackPlayer(String url,boolean start){
+ this.url = url;
+ if(start==true){
+ this.status = STATUS_PLAYING;
+ }
+ this.thread = new Thread(this);
+ this.thread.start();
+ }
+
+ private void Exit(){
+ synchronized(this.lock){
+ this.status = STATUS_EXIT;
+ this.lock.notifyAll();
+ }
+ try {
+ this.thread.join();
+ } catch (InterruptedException e) {
+ }
+ }
+
+ public void Stop(){
+ synchronized(this.lock){
+ this.status = STATUS_EXIT;
+ this.lock.notifyAll();
+ }
+ }
+
+ public void Pause(){
+ synchronized(this.lock){
+ this.status = STATUS_PAUSE;
+ this.lock.notifyAll();
+ }
+ }
+
+ public boolean Play(){
+ synchronized(this.lock){
+ if(this.status==STATUS_PLAYING || this.status==STATUS_PREPARED){
+ this.status = STATUS_PLAYING;
+ this.lock.notifyAll();
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private void CallListener(){
+ if(this.listener!=null){
+ this.listener.OnTrackStatusUpdate(this,this.status);
+ }
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ this.Exit();
+ super.finalize();
+ }
+
+ public interface OnTrackStatusListener{
+ public void OnTrackStatusUpdate(TrackPlayer trackPlayer,int status);
+ }
+
+ public OnTrackStatusListener listener = null;
+
+ public void onCompletion(MediaPlayer mp) {
+ synchronized(this.lock){
+ this.status = STATUS_EXIT;
+ this.lock.notifyAll();
+ }
+ }
+
+ public boolean onError(MediaPlayer mp, int what, int extra) {
+ synchronized(this.lock){
+ this.status = STATUS_EXIT;
+ this.lock.notifyAll();
+ }
+ return false;
+ }
+
+
+}
=======================================
--- /trunk/src/android/.classpath Sun Jun 28 23:20:09 2009
+++ /trunk/src/android/.classpath Wed Jul 29 15:56:39 2009
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
+ <classpathentry kind="con"
path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
- <classpathentry kind="con"
path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry kind="output" path="bin"/>
</classpath>
=======================================
--- /trunk/src/android/AndroidManifest.xml Fri Jul 10 08:10:19 2009
+++ /trunk/src/android/AndroidManifest.xml Wed Jul 29 15:56:39 2009
@@ -11,12 +11,15 @@
<category android:name="android.intent.category.LAUNCHER"
/>
</intent-filter>
</activity>
- <service android:name="Service" android:process=":remote"
android:enabled="true"></service>
+ <service android:name="Service"></service>
<activity android:name="CategoryList"></activity>
<activity android:name="TrackList"></activity>
+<activity android:name="Preferences"></activity>
</application>
<uses-sdk android:minSdkVersion="3" />
<uses-permission
android:name="android.permission.INTERNET"></uses-permission>
+
+
</manifest>
=======================================
--- /trunk/src/android/res/drawable/icon.png Sun Jun 28 23:20:09 2009
+++ /trunk/src/android/res/drawable/icon.png Wed Jul 29 15:56:39 2009
Binary file, no diff available.
=======================================
--- /trunk/src/android/res/values/strings.xml Sun Jul 5 14:53:29 2009
+++ /trunk/src/android/res/values/strings.xml Wed Jul 29 15:56:39 2009
@@ -3,4 +3,16 @@
<string name="hello">Hello World, main!</string>
<string name="app_name">musikCube</string>
+<string name="menu_settings">Settings</string>
+<string name="menu_help">Help</string>
+<string name="host">
vallgraven.intermezzon.com</string>
+
+
+
+
+
+<string name="username">doep</string>
+<string name="password">doep</string>
+<string name="queryport">10543</string>
+<string name="httpport">10544</string>
</resources>
=======================================
--- /trunk/src/android/src/doep/xml/Reader.java Wed Jul 8 14:54:19 2009
+++ /trunk/src/android/src/doep/xml/Reader.java Wed Jul 29 15:56:39 2009
@@ -1,10 +1,8 @@
package doep.xml;
import org.xmlpull.v1.*;
-import android.util.Log;
import doep.xml.ReaderNode;
import java.io.InputStream;
-import java.util.LinkedList;
import java.lang.Exception;
=======================================
--- /trunk/src/android/src/doep/xml/ReaderNode.java Wed Jul 8 14:54:19 2009
+++ /trunk/src/android/src/doep/xml/ReaderNode.java Wed Jul 29 15:56:39 2009
@@ -1,5 +1,4 @@
package doep.xml;
-import android.util.Log;
import doep.xml.Reader;
public class ReaderNode {
=======================================
--- /trunk/src/android/src/doep/xml/Writer.java Wed Jul 8 14:54:19 2009
+++ /trunk/src/android/src/doep/xml/Writer.java Wed Jul 29 15:56:39 2009
@@ -1,7 +1,5 @@
package doep.xml;
-import android.util.Log;
-
public class Writer extends WriterNode {
=======================================
--- /trunk/src/android/src/org/musikcube/App.java Sun Jul 5 14:53:29 2009
+++ /trunk/src/android/src/org/musikcube/App.java Wed Jul 29 15:56:39 2009
@@ -11,5 +11,7 @@
Log.i("MUSIKCUBE::APP","Start");
org.musikcube.core.Library library =
org.musikcube.core.Library.GetInstance();
+ library.Startup(this);
+
}
}
=======================================
--- /trunk/src/android/src/org/musikcube/CategoryList.java Wed Jul 8
14:54:19 2009
+++ /trunk/src/android/src/org/musikcube/CategoryList.java Wed Jul 29
15:56:39 2009
@@ -85,7 +85,7 @@
this.setOrientation(VERTICAL);
mTitle = new TextView(context);
- mTitle.setTextSize(18);
+ mTitle.setTextSize(22);
mTitle.setText(title);
addView(mTitle, new LinearLayout.LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
@@ -172,6 +172,7 @@
this.callbackHandler.post(this.callbackRunnable);
}
+ @SuppressWarnings("unchecked")
@Override
protected void onListItemClick(ListView l, View v, int position, long id){
Log.i("CategoryList::onListItemClick","clicked on "+position+" "+id);
@@ -204,5 +205,17 @@
startActivity(intent);
}
}
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ org.musikcube.core.Library.GetInstance().RemovePointer();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ org.musikcube.core.Library.GetInstance().AddPointer();
+ }
}
=======================================
--- /trunk/src/android/src/org/musikcube/Service.java Fri Jul 10 08:10:19
2009
+++ /trunk/src/android/src/org/musikcube/Service.java Wed Jul 29 15:56:39
2009
@@ -3,13 +3,10 @@
*/
package org.musikcube;
-import java.io.IOException;
-import java.util.ArrayList;
-
import org.musikcube.core.Library;
+import org.musikcube.core.Player;
import android.content.Intent;
-import android.media.MediaPlayer;
import android.os.IBinder;
import android.util.Log;
@@ -20,9 +17,8 @@
public class Service extends android.app.Service {
Library library;
- MediaPlayer player;
-
- ArrayList<Integer> nowPlaying = new ArrayList<Integer>();
+ Player player;
+
int nowPlayingPosition = 0;
/**
@@ -44,7 +40,8 @@
@Override
public void onCreate(){
Log.i("musikcube::Service","CREATE");
- this.library = org.musikcube.core.Library.GetInstance();
+ this.player = Player.GetInstance();
+ this.player.service = this;
}
/* (non-Javadoc)
@@ -55,7 +52,22 @@
// TODO Auto-generated method stub
super.onStart(intent, startId);
-
if(intent.getIntegerArrayListExtra("org.musikcube.Service.tracklist")!=null){
+ String action = intent.getStringExtra("org.musikcube.Service.action");
+ if(action.equals("playlist")){
+ Player player = Player.GetInstance();
+
player.Play(intent.getIntegerArrayListExtra("org.musikcube.Service.tracklist"),
intent.getIntExtra("org.musikcube.Service.position", 0));
+ }
+ if(action.equals("next")){
+ Player player = Player.GetInstance();
+ player.Next();
+ }
+ if(action.equals("player ended")){
+ this.stopSelf();
+ }
+
+// if(intent
getIntegerArrayListExtra("org.musikcube.Service.tracklist")!=null){
+
+/*
if(intent.getIntegerArrayListExtra("org.musikcube.Service.tracklist")!=null){
this.nowPlaying =
intent.getIntegerArrayListExtra("org.musikcube.Service.tracklist");
this.nowPlayingPosition =
intent.getIntExtra("org.musikcube.Service.position", 0);
@@ -70,7 +82,7 @@
this.library.WaitForAuthroization();
try {
-
Log.i("musikcube::Service","onStart3 "+"http://"+this.library.host+":"+this.library.httpPort+"/track/?track_id="+this.nowPlaying.get(this.nowPlayingPosition)+"&auth_key="+this.library.authorization);
+//
Log.i("musikcube::Service","onStart3 "+"http://"+this.library.host+":"+this.library.httpPort+"/track/?track_id="+this.nowPlaying.get(this.nowPlayingPosition)+"&auth_key="+this.library.authorization);
this.player.setDataSource("http://"+this.library.host+":"+this.library.httpPort+"/track/?track_id="+this.nowPlaying.get(this.nowPlayingPosition)+"&auth_key="+this.library.authorization);
Log.i("musikcube::Service","onStart4");
this.player.prepare();
@@ -81,7 +93,12 @@
} catch (Exception e) {
e.printStackTrace();
}
- }
+ }*/
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
}
=======================================
--- /trunk/src/android/src/org/musikcube/TrackList.java Fri Jul 10 08:10:19
2009
+++ /trunk/src/android/src/org/musikcube/TrackList.java Wed Jul 29 15:56:39
2009
@@ -80,7 +80,7 @@
this.setOrientation(VERTICAL);
mTitle = new TextView(context);
- mTitle.setTextSize(18);
+ mTitle.setTextSize(22);
mTitle.setText(title.toString());
addView(mTitle, new LinearLayout.LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
@@ -159,8 +159,22 @@
Intent intent = new Intent(this, org.musikcube.Service.class);
intent.putExtra("org.musikcube.Service.tracklist", this.query.trackList);
intent.putExtra("org.musikcube.Service.position", position);
+ intent.putExtra("org.musikcube.Service.action", "playlist");
startService(intent);
}
+
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ org.musikcube.core.Library.GetInstance().RemovePointer();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ org.musikcube.core.Library.GetInstance().AddPointer();
+ }
}
=======================================
--- /trunk/src/android/src/org/musikcube/core/IQuery.java Sun Jul 5
14:53:29 2009
+++ /trunk/src/android/src/org/musikcube/core/IQuery.java Wed Jul 29
15:56:39 2009
@@ -1,7 +1,5 @@
package org.musikcube.core;
-import java.io.IOException;
-
import doep.xml.*;
public class IQuery extends Object{
=======================================
--- /trunk/src/android/src/org/musikcube/core/Library.java Fri Jul 10
08:10:19 2009
+++ /trunk/src/android/src/org/musikcube/core/Library.java Wed Jul 29
15:56:39 2009
@@ -5,10 +5,12 @@
import java.net.*;
import java.io.*;
+
+import android.content.Context;
import android.util.*;
import doep.xml.*;
-import org.musikcube.Service;
+import org.musikcube.R;
import org.musikcube.core.IQuery;
/**
@@ -17,21 +19,28 @@
*/
public class Library implements Runnable{
- private String username;
- private String password;
+// private String username;
+// private String password;
public String authorization = "";
public String host;
- private int queryPort;
+// private int queryPort;
public int httpPort;
-
+
private Thread thread;
private boolean running = false;
+ private boolean restart = false;
+ private boolean exit = false;
private Socket socket;
+ private Context context;
+
+ int connections = 0;
+
private java.lang.Object notifier = new java.lang.Object();
private java.util.LinkedList<IQuery> sendQueryQueue = new
java.util.LinkedList<IQuery>();
private java.util.LinkedList<IQuery> waitingQueryQueue = new
java.util.LinkedList<IQuery>();
+ private int shutdownCounter = -1;
private static org.musikcube.core.Library library = null;
@@ -39,12 +48,74 @@
public static final synchronized Library GetInstance(){
if(Library.library==null){
Library.library = new org.musikcube.core.Library();
- Library.library.Connect("192.168.99.100", "doep", "doep", 10543, 10544);
- }
-
+ }
return Library.library;
}
+ public void AddPointer(){
+ synchronized(this.notifier){
+ this.connections++;
+
+ if(this.connections==1 && this.running==false){
+ this.Restart();
+ }
+
+ if(this.connections==0){
+ this.shutdownCounter = 10;
+ }else{
+ this.shutdownCounter = -1;
+ }
+ }
+ }
+ public void RemovePointer(){
+ synchronized(this.notifier){
+ this.connections--;
+ if(this.connections==0){
+ this.shutdownCounter = 10;
+ }else{
+ this.shutdownCounter = -1;
+ }
+ }
+ }
+
+
+ public void Startup(Context context){
+ if(context!=null){
+ this.context = context;
+
+ // Startup thread when the application sends the context for the first
time
+ this.thread = new Thread(this);
+ this.running = true;
+ this.thread.start();
+
+ }
+ }
+
+ public void Restart(){
+ synchronized(this.notifier){
+ this.running = false;
+ this.restart = true;
+// this.Startup(null);
+ if(this.socket!=null){
+ try {
+ this.socket.shutdownInput();
+ this.socket.shutdownOutput();
+ this.socket.close();
+ } catch (Exception e) {
+ }
+ }
+ this.notifier.notifyAll();
+ }
+ }
+
+ public boolean Running(){
+ synchronized(this.notifier){
+ if(this.running==true){
+ return true;
+ }
+ }
+ return false;
+ }
private class WriterThreadHelper implements Runnable{
private Thread thread;
@@ -52,6 +123,9 @@
public WriterThreadHelper(Library library){
this.library = library;
this.thread = new Thread(this);
+ }
+
+ public void Start(){
this.thread.start();
}
@@ -63,28 +137,7 @@
private WriterThreadHelper writerThreadHelper;
protected Library(){
- }
-
- public boolean Connect(String host,String username,String password,int
queryPort,int httpPort){
- //Log.i("Library","starting "+host+":"+queryPort);
- synchronized (notifier) {
-
- if(!running){
- this.host = host;
- this.username = username;
- this.password = password;
- this.queryPort = queryPort;
- this.httpPort = httpPort;
-
- // Startup thread
- this.thread = new Thread(this);
- // this.thread.setDaemon(true);
- this.running = true;
- this.thread.start();
- return true;
- }
- return false;
- }
+// this.writerThreadHelper = new WriterThreadHelper(this);
}
public void WaitForAuthroization(){
@@ -101,76 +154,138 @@
}
public void run(){
- // First try to connect
- try{
- this.socket = new java.net.Socket(this.host,this.queryPort);
- //Log.v("Library::socket","Successfully connected
to "+this.host+":"+this.queryPort);
-
- doep.xml.Reader reader = new
doep.xml.Reader(this.socket.getInputStream());
- //Log.v("Library::run","Reader started");
- {
- // Wait for a "authentication" tag
- doep.xml.ReaderNode authNode=null;
- if( (authNode=reader.ChildNode("authentication")) != null ){
- //Log.v("Library::run","Authtag found");
- // Wait for authorization tag to end
- authNode.End();
-
- synchronized (notifier) {
- Log.v("Library::run","Authtag end");
- this.authorization = authNode.content;
- Log.v("Library::run","Authorization="+this.authorization);
- this.notifier.notifyAll();
- Log.v("Library::run","Authorization notify");
- }
- }
+
+ while(true){
+ this.running = true;
+ // First try to connect
+ try{
+ synchronized (notifier) {
+ this.host = this.context.getString(R.string.host);
+ int queryPort =
Integer.parseInt(this.context.getString(R.string.queryport));
+ this.httpPort =
Integer.parseInt(this.context.getString(R.string.httpport));
+ this.socket = new java.net.Socket(host,queryPort);
+ }
+ //Log.v("Library::socket","Successfully connected
to "+this.host+":"+this.queryPort);
+
+ doep.xml.Reader reader = new
doep.xml.Reader(this.socket.getInputStream());
+ //Log.v("Library::run","Reader started");
+ {
+ // Wait for a "authentication" tag
+ doep.xml.ReaderNode authNode=null;
+ if( (authNode=reader.ChildNode("authentication")) != null ){
+ //Log.v("Library::run","Authtag found");
+ // Wait for authorization tag to end
+ authNode.End();
+
+ synchronized (notifier) {
+ Log.v("Library::run","Authtag end");
+ this.authorization = authNode.content;
+ Log.v("Library::run","Authorization="+this.authorization);
+ this.notifier.notifyAll();
+ Log.v("Library::run","Authorization notify");
+ }
+ }
+ }
+
+ this.writerThreadHelper = new WriterThreadHelper(this);
+ this.writerThreadHelper.Start();
+
+ // Lets start waiting for query-results
+ //Log.v("Library::socket","Waiting for query results");
+
+ doep.xml.ReaderNode queryNode = null;
+ while((queryNode=reader.ChildNode("queryresults"))!=null){
+ //Log.v("NODE","We have a "+queryNode.name);
+ // Find the right query
+ IQuery query = null;
+
+ synchronized(this.waitingQueryQueue){
+ java.util.ListIterator<IQuery>
it=this.waitingQueryQueue.listIterator();
+ String queryIdString = queryNode.attributes.get("id");
+ int queryId = Integer.parseInt(queryIdString);
+ while(it.hasNext() && query==null){
+ query = it.next();
+ if(
query.id!=queryId){
+ query = null;
+ }else{
+ // Remove it from the waitingQueue
+ it.remove();
+ }
+ }
+ }
+
+ if(query!=null){
+ //Log.v("Library::socket","Parse query results");
+ // Parse the results
+ query.ReceiveQueryResult(queryNode);
+ }
+ queryNode.End();
+
+ }
+
+ //Log.v("Library::socket","NOT Waiting for query results");
+ }
+ catch(IOException x){
+ Log.e("Library::socket","IOE "+x.getMessage());
+ }
+ catch(Exception x){
+ Log.e("Library::socket","E "+x.getMessage());
}
- // Start write thread
- this.writerThreadHelper = new WriterThreadHelper(this);
-
- // Lets start waiting for query-results
- //Log.v("Library::socket","Waiting for query results");
-
- doep.xml.ReaderNode queryNode = null;
- while((queryNode=reader.ChildNode("queryresults"))!=null){
- //Log.v("NODE","We have a "+queryNode.name);
- // Find the right query
- IQuery query = null;
-
- synchronized(this.waitingQueryQueue){
- java.util.ListIterator<IQuery>
it=this.waitingQueryQueue.listIterator();
- String queryIdString = queryNode.attributes.get("id");
- int queryId = Integer.parseInt(queryIdString);
- while(it.hasNext() && query==null){
- query = it.next();
- if(
query.id!=queryId){
- query = null;
- }else{
- // Remove it from the waitingQueue
- it.remove();
- }
+ synchronized (notifier) {
+ this.running = false;
+ }
+
+ // Notify the write-thread to end the thread
+ synchronized(this.sendQueryQueue){
+ this.sendQueryQueue.notifyAll();
+ }
+
+ try{
+ if(this.writerThreadHelper!=null){
+ this.writerThreadHelper.thread.join();
+ }
+ }
+ catch(Exception x){
+
+ }
+
+ synchronized (notifier) {
+ if(this.connections!=0){
+ try{
+ this.notifier.wait(2000);
+ }
+ catch(Exception x){
+
}
}
-
- if(query!=null){
- //Log.v("Library::socket","Parse query results");
- // Parse the results
- query.ReceiveQueryResult(queryNode);
- }
- queryNode.End();
-
+
+ while(this.connections==0){
+ try{
+ this.notifier.wait();
+ }
+ catch(Exception x){
+
+ }
+ }
+/* int countDown = 10;
+ while(!this.exit && !this.restart){
+ try{
+ this.notifier.wait(2000);
+ }
+ catch(Exception x){
+
+ }
+ }*/
+
+ if(this.exit){
+ return;
+ }
+ this.restart = false;
+// this.running = true;
}
- //Log.v("Library::socket","NOT Waiting for query results");
- }
- catch(IOException x){
- Log.e("Library::socket","IOE "+x.getMessage());
- }
- catch(Exception x){
- Log.e("Library::socket","E "+x.getMessage());
- }
-
+ }
}
public void WriteThread(WriterThreadHelper thread){
@@ -178,10 +293,13 @@
try{
doep.xml.Writer writer = new
doep.xml.Writer(this.socket.getOutputStream());
{
+ String username = this.context.getString(R.string.username);
+ String password = this.context.getString(R.string.password);
+
// Authenticate
WriterNode authNode = writer.ChildNode("authentication");
- authNode.attributes.put("username", this.username);
- authNode.content = this.password;
+ authNode.attributes.put("username", username);
+ authNode.content = password;
authNode.End();
}
@@ -192,6 +310,14 @@
synchronized(this.sendQueryQueue){
if(this.sendQueryQueue.isEmpty()){
this.sendQueryQueue.wait(2000);
+
+ synchronized(this.notifier){
+ this.shutdownCounter--;
+ if(this.shutdownCounter==0){
+ this.Restart();
+ }
+ }
+
//Log.v("Library::WriteThread","wait over");
}else{
// Get the first query
@@ -222,27 +348,40 @@
catch(Exception x){
Log.e("Library::WriteThread","E "+x.getMessage());
}
+
+ // Notify the "read"-thread by closing the socket
+ try {
+ this.socket.close();
+ } catch (Exception x) {
+ Log.e("Library::WriteThread","E "+x.getMessage());
+ }
//Log.v("Library::WriteThread","Ended");
}
- public void Disconnect(){
- this.running = false;
+ public void Exit(){
+ synchronized(this.notifier){
+ this.exit = true;
+ this.running = false;
+ }
synchronized(this.sendQueryQueue){
this.sendQueryQueue.notifyAll();
}
synchronized(this.waitingQueryQueue){
this.waitingQueryQueue.notifyAll();
}
-// this.writerThreadHelper.notifyAll();
try{
this.socket.close();
}
catch(Exception x){
Log.e("Library::Disconnect","Exception error "+x.getMessage());
}
- //this.writerThreadHelper.thread.join();
- //this.thread.join();
+ try{
+ this.thread.join();
+ }
+ catch(Exception x){
+ Log.e("Library::Disconnect","Exception error "+x.getMessage());
+ }
}
public void AddQuery(IQuery query){
=======================================
--- /trunk/src/android/src/org/musikcube/core/ListQuery.java Wed Jul 8
14:54:19 2009
+++ /trunk/src/android/src/org/musikcube/core/ListQuery.java Wed Jul 29
15:56:39 2009
@@ -1,7 +1,5 @@
package org.musikcube.core;
-import java.io.IOException;
-
import doep.xml.ReaderNode;
import doep.xml.WriterNode;
=======================================
--- /trunk/src/android/src/org/musikcube/main.java Wed Jul 8 14:54:19 2009
+++ /trunk/src/android/src/org/musikcube/main.java Wed Jul 29 15:56:39 2009
@@ -3,9 +3,14 @@
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageButton;
+
import org.musikcube.CategoryList;
@@ -47,4 +52,34 @@
};
-}
+ public boolean onCreateOptionsMenu(Menu menu) {
+ MenuInflater inflater = getMenuInflater();
+ inflater.inflate(R.menu.default_menu, menu);
+ return true;
+ }
+
+ public boolean onOptionsItemSelected(MenuItem item) {
+
Log.i("MC2.onContextItemSelected","item "+item.getItemId()+" "+R.id.context_settings);
+ switch (item.getItemId()) {
+ case R.id.context_settings:
+ Intent intent = new Intent(main.this, Preferences.class);
+ startActivity(intent);
+ return true;
+ default:
+ return super.onContextItemSelected(item);
+ }
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ org.musikcube.core.Library.GetInstance().RemovePointer();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ org.musikcube.core.Library.GetInstance().AddPointer();
+ }
+
+}