Java Question Comunicating with Stock Music Service

MikieK

Member
Licensed User
Longtime User
I've done some searching, and found this:https://github.com/sudar/AdjustVolume/
Its a relatively simple app that sends commands to music.apk (it is sophisticated enough to identify phones with an HTC rom)
I've just attempted to pull features from this app to try and implement a library, result: force close(its my second attempt at a library after hello world, and I think I bit off more than I understood)
The app uses Aidl's as a go-between. The Java equivelent I think is an interface.
Anyway, Eclipse was showing error messages all over the place, so I've given up.
Here's my attempt (The Aidl's can be taken from above):
B4X:
package com.test.android.MusicCom;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.RemoteException;
import android.os.IBinder;
import android.os.Binder;
import anywheresoftware.b4a.BA.ShortName;


@ShortName("MusicCom")
public class MusicCom{
   
    protected static final String TAG = "MusicCom";
   private boolean isHtc;
   private MediaPlayerServiceConnection musicConn;

   /**
    * Selects the next song
    * 
    * @throws RemoteException 
    * 
    */
   public void Next() {
      try {
         musicConn.nextSong();
      } catch (RemoteException e) {
   
      }
   }
   
   /**
    * Selects the Previous song
    * 
    * @throws RemoteException
    */
   public void Prev()  {
      try {
         musicConn.prevSong();
      } catch (RemoteException e) {
   
      }
   }
   
   /**
    * Get the name of the current Trackname
    * 
    * @return
    * @throws RemoteException
    */
   public String TrackName() {
      try {
         return musicConn.getTrackName();
      } catch (RemoteException e) {
   
         return "error";
      }
   }

   public void initialise() {

      Intent i = new Intent();
      musicConn = new MediaPlayerServiceConnection();
      
      isHtc = true;
      i.setClassName("com.htc.music", "com.htc.music.MediaPlaybackService");
      
        if (!this.bindService(i, musicConn, Context.MODE_PRIVATE)) {
           isHtc = false;
            i.setClassName("com.android.music", "com.android.music.MediaPlaybackService");
            this.bindService(i, musicConn, Context.MODE_PRIVATE);
}   
   }
   
   /**
    * The service connection class that allows you to talk to the MediaPlayer Service
    * 
    * @author "Sudar Muthu (http://sudarmuthu.com)"
    *
    */
   private class MediaPlayerServiceConnection implements ServiceConnection {
       public com.htc.music.IMediaPlaybackService mServiceHtc;
       public com.android.music.IMediaPlaybackService mServiceAndroid;

      
      public void onServiceConnected(ComponentName name, IBinder service) {
         // This is the important line where we bind the service
          if (isHtc)
             mServiceHtc = com.htc.music.IMediaPlaybackService.Stub.asInterface(service);
         else
            mServiceAndroid = com.android.music.IMediaPlaybackService.Stub.asInterface(service);
      }

      /**
       * Selects the next song
       * 
       * @throws RemoteException 
       * 
       */
      public void nextSong() throws RemoteException {
         if (isHtc) {
            mServiceHtc.next();
         } else {
            mServiceAndroid.next();
         }
      }
      
      /**
       * Selects the Previous song
       * 
       * @throws RemoteException
       */
      public void prevSong() throws RemoteException {
         if (isHtc) {
            mServiceHtc.prev();
         } else {
            mServiceAndroid.prev();
         }
      }
      
      /**
       * Get the name of the current Trackname
       * 
       * @return
       * @throws RemoteException
       */
      public String getTrackName() throws RemoteException {
         if (isHtc) {
            return mServiceHtc.getTrackName();
         } else {
            return mServiceAndroid.getTrackName();            
         }
      }

      @Override
      public void onServiceDisconnected(ComponentName arg0) {
      }

   }   
}
Its a horrible cut-and-shut I know.
Is there anything obviously wrong above?, is what I was trying to do even possible?
 

MikieK

Member
Licensed User
Longtime User
I have played around with the code a bit...
B4X:
package com.B4a.Library.MusicCom;

import java.io.IOException;



import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;
import anywheresoftware.b4a.BA.ShortName;
import anywheresoftware.b4a.objects.streams.File;



@ShortName("MusicCom")
public class MusicCom{
   private boolean isHtc;
   private MediaPlayerServiceConnection musicConn;
   /**
    * Is the Service Connected?
    */
   public boolean Connected = false;
   /**
    * Returns True if successful
    */
   public boolean Initialize(){
      boolean toreturn;
      try {
         if (File.Exists("/data/data/", "com.htc.music")){
            isHtc = true;
               toreturn  = true;
         }
         else if (File.Exists("/data/data/", "com.android.music")){
               isHtc = false;
               toreturn = true;
            }
            else {toreturn = false;
         }
      } catch (IOException e) {
      toreturn = false;
      }
   if (toreturn = true) {
      Intent i = new Intent();
      musicConn = new MediaPlayerServiceConnection();
      if (isHtc){i.setClassName("com.htc.music", "com.htc.music.MediaPlaybackService");
      }
      else {
          i.setClassName("com.android.music", "com.android.music.MediaPlaybackService");
      }
   
      [U][B]Context.bindService(i, musicConn, Context.MODE_PRIVATE);[/B][/U]
      
   }
   return toreturn;
   }
   /**
    * Selects the next song
    * Returns true if successful 
    * 
    */
   public boolean Next() {
      boolean toreturn = true;
      try {
         musicConn.nextSong();
      } catch (RemoteException e) {
   toreturn = false;
      }
      return toreturn;
   }
   
   /**
    * Selects the Previous song
    * Returns true if successful
    */
   public boolean Prev()  {
      boolean toreturn = true;
      try {
         musicConn.prevSong();
      } catch (RemoteException e) {
   toreturn = false;
      }
      return toreturn;
   }
   
   /**
    * Get the name of the current Trackname
    * 
    */
   public String TrackName() {
      try {
         return musicConn.getTrackName();
      } catch (RemoteException e) {
   
         return "error";
      }
   }
   
   /**
    * The service connection class that allows you to talk to the MediaPlayer Service
    * 
    * @author "Sudar Muthu (http://sudarmuthu.com)"
    *
    */
   private class MediaPlayerServiceConnection implements ServiceConnection {
       public com.htc.music.IMediaPlaybackService mServiceHtc;
       public com.android.music.IMediaPlaybackService mServiceAndroid;

      
      public void onServiceConnected(ComponentName name, IBinder service) {
         Connected = true;
         // This is the important line where we bind the service
          if (isHtc)
             mServiceHtc = com.htc.music.IMediaPlaybackService.Stub.asInterface(service);
         else
            mServiceAndroid = com.android.music.IMediaPlaybackService.Stub.asInterface(service);
      }

      /**
       * Selects the next song
       * 
       * @throws RemoteException 
       * 
       */
      public void nextSong() throws RemoteException {
         if (isHtc) {
            mServiceHtc.next();
         } else {
            mServiceAndroid.next();
         }
      }
      
      /**
       * Selects the Previous song
       * 
       * @throws RemoteException
       */
      public void prevSong() throws RemoteException {
         if (isHtc) {
            mServiceHtc.prev();
         } else {
            mServiceAndroid.prev();
         }
      }
      
      /**
       * Get the name of the current Trackname
       * 
       * @return
       * @throws RemoteException
       */
      public String getTrackName() throws RemoteException {
         if (isHtc) {
            return mServiceHtc.getTrackName();
         } else {
            return mServiceAndroid.getTrackName();            
         }
      }

      @Override      
      public void onServiceDisconnected(ComponentName name) {
         Connected = false;
      }
   }
}

FATAL EXCEPTION: main
java.lang.Error: Unresolved compilation problems:
Cannot make a static reference to the non-static method bindService(Intent, ServiceConnection, int) from the type Context

The error relates to the line underlined and in bold above. I tried making the
MediaPlayerServiceConnection class static with no success. Also, when I try and call Next in b4a, I get an expected "end if" or "end sub" error?
 
Last edited:

MikieK

Member
Licensed User
Longtime User
Cheers Erel, I tried that and got a bit further, but its a mine field, and since this wont work from Gingerbread up (and on other devices with non standard music players) I'm giving up.
 
Top