I have spend all day dealing with this problem, I can't solve it. I am exhausted ,have no ideas what to do with it. Please help.
I want to create service that plays music in background.But receiving always null instead of service. Sometimes onServiceConnected is called, sometimes not
public class SoundService extends Service {
private IBinder myBinder = new MyLocalBinder() ;
private static boolean isSoundOn = false;
private static boolean isBgMusicOn = false;
private static int[] soundPoolIds = null;
private Context appContext = null;
private static SoundPlayer instance = null;
private MediaPlayer mp = null;
private SoundPool sndPool = null;
public class MyLocalBinder extends Binder {
public SoundService getService() {
return SoundService.this;
}
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return myBinder;
}
#Override
public void onCreate() {
super.onCreate();
// initSoundPools();
}
#Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
}
#Override
public boolean onUnbind(Intent intent) {
// TODO Auto-generated method stub
return super.onUnbind(intent);
}
#Override
public void onRebind(Intent intent) {
// TODO Auto-generated method stub
super.onRebind(intent);
}
public long getCurrentTime() {
Time time = new Time();
time.setToNow();
return time.toMillis(false);
}
#SuppressLint("NewApi")
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
private void initBackground() {
//Some magic code here
}
private void playMusic(MediaPlayer mp) {
//Some magic code here
}
private boolean musicIsPlaying(MediaPlayer mp) {
//Some magic code here
}
return false;
}
public void stopPlayingBackground() {
//Some magic code here
}
private void stopPlaying(MediaPlayer mp,boolean release) {
//Some magic code here
}
private int randInt(int min, int max) {
//Some magic code here
}
private void initSoundPools() {
//Some magic code here
}
public void turnSoundOn(boolean on) {
isSoundOn = on;
}
public void turnMusicOn(boolean on) {
isBgMusicOn = on;
}
public void playBackgroundMusic() {
//Some magic code here
}
public void playSoundFx(int id) {
//Some magic code here
}
}
}
Here is Class that extends another that in turn extends Activity
public class MainActivity extends LGame {
p
private static final String TAG = "DEBUG";
private static SoundService soundService;
private static boolean isBound = false;
private Thread serviceThread;
private ServiceConnection myConnection;
#Override
public void onGamePaused() {
}
#Override
public void onGameResumed() {
// TODO Auto-generated method stub
}
#Override
protected void onDestroy() {
}
if (soundService!=null) {
soundService.stopSelf();
}
super.onDestroy();
}
public static SoundService getSoundService() {
return soundService;
}
#Override
public void onMain() {
LTexture.ALL_LINEAR = true;
LSetting setting = new LSetting();
setting.width = 800;
setting.height = 480;
setting.fps = 30;
setting.landscape = true;
setting.showFPS = false;
myConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className,
IBinder service) {
MyLocalBinder binder = (MyLocalBinder) service;
soundService = binder.getService();
isBound = true;
}
public void onServiceDisconnected(ComponentName arg0) {
isBound = false;
}
};
serviceThread = new Thread(){
public void run(){
Intent intent = new Intent(getApplicationContext(), SoundService.class);
getApplicationContext().bindService(intent, myConnection, Context.BIND_AUTO_CREATE);
}
};
serviceThread.start();
register(setting, MainGame.class);
}
Firstly I tried to start service in main thread but nothing changed in both cases.
Of course I've declared service in manifest.
I hope someone can help me with this.
Thx for help in advance.
EDIT
I have mentioned that I have already tried to start it like in your post but nothing changed
HELP !! I have tried almost everything
You should never bind a service in different thread, if you want to do async tasks you should create the threads inside the service itself.
#Override
public void onMain() {
LTexture.ALL_LINEAR = true;
LSetting setting = new LSetting();
setting.width = 800;
setting.height = 480;
setting.fps = 30;
setting.landscape = true;
setting.showFPS = false;
myConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className,
IBinder service) {
MyLocalBinder binder = (MyLocalBinder) service;
soundService = binder.getService();
isBound = true;
}
public void onServiceDisconnected(ComponentName arg0) {
isBound = false;
}
};
Intent intent = new Intent(getApplicationContext(), SoundService.class);
getApplicationContext().bindService(intent, myConnection, Context.BIND_AUTO_CREATE);
register(setting, MainGame.class);
}
From Android documentation :
The bindService() method returns immediately without a value.
So binding your service in the UI thread will not cause any delaying nor UI freezing.
Related
I am creating a Notification using Android Service independent from UI. This works perfectly fine. Below is the code.
public class SendNotificationService extends Service {
Context context;
String test_heading;
String test_body;
final class notifThread implements Runnable {
int service_id;
notifThread(int service_id) {
this.service_id = service_id;
}
#Override
public void run() {
String requested_method = "LoadBU";
String bu_status = "1";
CheckNewEntry checkNewEntry = new CheckNewEntry(SendNotificationService.this);
checkNewEntry.execute(requested_method, bu_status);
stopSelf(this.service_id);
}
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Thread thread = new Thread(new notifThread(startId));
thread.start();
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, "Notifications Stopped...", Toast.LENGTH_LONG).show();
}
}
This service also starts automatically on system boot. CheckNewEntry is my AsyncTask that checks the database and sends notification if there is any change. I have not added CheckNewEntry as it is beyond the scope of this question.
Now what I want to do is, run CheckNewEntry every 30 seconds or 1 minute.
Can anyone help?
After going through different Stackoverflow questions/answers, I managed to come up with my own solution.
Below is the code that I have created and is working now.
public class SendNotificationService extends Service {
public Context context = this;
public Handler handler = null;
public static Runnable runnable = null;
#Override
public void onCreate() {
handler = new Handler();
runnable = new Runnable() {
public void run() {
String requested_method = "LoadBU";
String bu_status = "1";
CheckNewEntry checkNewEntry = new CheckNewEntry(SendNotificationService.this);
checkNewEntry.execute(requested_method, bu_status);
handler.postDelayed(runnable, 10000);
}
};
handler.postDelayed(runnable, 15000);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onDestroy() {
handler.removeCallbacks(runnable);
Toast.makeText(this, "Notifications Stopped...", Toast.LENGTH_LONG).show();
}
}
If anyone of you can provide a better solution, please do post.
you can use handler like this.
public class SendNotificationService extends Service {
Context context;
String test_heading;
String test_body;
public static Runnable runn;
public static Handler hand =new Handler();
final class notifThread implements Runnable {
int service_id;
notifThread(int service_id) {
this.service_id = service_id;
}
#Override
public void run() {
String requested_method = "LoadBU";
String bu_status = "1";
CheckNewEntry checkNewEntry = new CheckNewEntry(SendNotificationService.this);
runn = new Runnable() {
#Override
public void run() {
checkNewEntry.execute(requested_method, bu_status);
hand.postDelayed(runn, 30000);
}
};
runn.run();
stopSelf(this.service_id);
}
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Thread thread = new Thread(new notifThread(startId));
thread.start();
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, "Notifications Stopped...", Toast.LENGTH_LONG).show();
}
}
I want to instantiate a thread in a Service that will work even when the client leaves the app. On his return the Tread will not be instantiated again only certain parameters of it may be changed. So I need to be able to access it. It also concerns rotation of the screen.
The current code starts another thread which is obviously not a desired solution. The commented out stuff shows different approaches but they didn't work either. I will have to access threadService object in main activity as well.
public class MainActivity extends ActionBarActivity {
private static ThreadService threadService;
private ServiceConnection threadConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
ThreadServiceBinder binder = (ThreadServiceBinder) service;
threadService = binder.getService();
}
#Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent(this, ThreadService.class);
this.startService(intent);
/* if(threadConnection == null) {
Intent intent = new Intent(this, ThreadService.class);
this.startService(intent);
Toast.makeText(this, "Thread service is null", Toast.LENGTH_SHORT).show();
} else {
if(!threadService.ifThreadIsRunning()) {
Intent intent = new Intent(this, ThreadService.class);
this.startService(intent);
Toast.makeText(this, "Thread service is not null", Toast.LENGTH_SHORT).show();
}
}*/
}
#Override
public void onDestroy() {
this.stopService(new Intent(this, ThreadService.class));
super.onDestroy();
}
/*
private boolean isMyServiceRunning(Class<?> serviceClass) {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (RunningServiceInfo service : manager
.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}*/
}
Here is the service
public class ThreadService extends Service {
private final IBinder threadServiceBinder = new ThreadServiceBinder();
public class ThreadServiceBinder extends Binder {
ThreadService getService() {
return ThreadService.this;
}
}
final Handler handler = new Handler();
private BackgroundThread backgroundThread;
public ThreadService() {
/*
* if(backgroundThread == null) backgroundThread =new
* BackgroundThread(handler);
*/
backgroundThread = BackgroundThread.getInstance();
backgroundThread.setHandler(handler);
handler.removeCallbacks(backgroundThread);
handler.postDelayed(backgroundThread, 10000);
}
#Override
public IBinder onBind(Intent intent) {
return threadServiceBinder;
}
public boolean ifThreadIsRunning() {
if (backgroundThread.isAlive()) {
return true;
} else {
return false;
}
}
}
class BackgroundThread extends Thread {
private static BackgroundThread instance;
private Handler mHandler;
private BackgroundThread() {
}
public static synchronized BackgroundThread getInstance() {
if (instance == null) {
instance = new BackgroundThread();
}
return instance;
}
public void setHandler(Handler handler) {
if (mHandler == null) {
mHandler = handler;
}
}
/*
* public BackgroundThread(Handler handler) { super(); mHandler = handler; }
*/
#Override
public void run() {
try {
Log.d("com.example.timer", "We are in Runnable run try section");
mHandler.postDelayed(this, 10000);
} catch (Exception e) {
// TODO: handle exception
}
/*
* finally{ handler.postDelayed(runable, 2000); }
*/
}
}
I have a checked button in my MainActivity. If that button is checked it should start the service but if a user unchecked the button I want to stop the service.
So in uncheck condition I have written this stopService(intentname); but the problem is the service is not stopping. Here is my code snippet:
Service Class
public class SimpleService extends Service
{
String selectedAudioPath = "";
private MyThread myythread;
public Intent intent;
public boolean isRunning = false;
long interval=30000;
#Override
public IBinder onBind(Intent arg0)
{
return null;
}
#Override
public void onCreate()
{
super.onCreate();
myythread = new MyThread(interval);
}
#Override
public synchronized void onDestroy()
{
super.onDestroy();
if(!isRunning)
{
myythread.interrupt();
myythread.stop();
isRunning = false;
}
}
#Override
public synchronized void onStart(Intent intent, int startId)
{
super.onStart(intent, startId);
if(!isRunning)
{
//this.intent = intent;
//System.out.println("the intent is" + intent);
myythread.start();
isRunning = true;
}
}
class MyThread extends Thread
{
long interval;
public MyThread(long interval)
{
this.interval=interval;
}
#Override
public void run()
{
while(isRunning)
{
System.out.println("Service running");
try
{
String myString = intent.getStringExtra("name");
if(myString == null)
Log.d("Service","null");
else
{
Log.d("Service","not null");
if(myString.equalsIgnoreCase("image"))
{
uploadImages();
Thread.sleep(interval);
}
else if(myString.equalsIgnoreCase("audio"))
{
uploadAudio();
Thread.sleep(interval);
}
}
}
catch (InterruptedException e)
{
isRunning = false;
e.printStackTrace();
}
}
}
You can't stop a thread that has a running unstoppable loop like this
while(true)
{
}
To stop that thread, declare a boolean variable and use it in while-loop condition.
public class MyService extends Service {
...
private Thread mythread;
private boolean running;
#Override
public void onDestroy()
{
running = false;
super.onDestroy();
}
#Override
public void onStart(Intent intent, int startid) {
running = true;
mythread = new Thread() {
#Override
public void run() {
while(running) {
MY CODE TO RUN;
}
}
};
};
mythread.start();
}
Source: Stopping a thread inside a service
Don't use Threads. Use AsyncTask instead.
public class MyService extends Service {
private AsyncTask<Void,Void,Void> myTask;
#Override
public void onDestroy(){
super.onDestroy();
myTask.cancel(true);
}
#Override
public void onStart(Intent intent, int startid) {
myTask = new AsyncTask<Void,Void,Void>(){
#Override
public void doInBackground(Void aVoid[]){
doYourWorkHere();
}
}
myTask.execute();
}
}
I have tried to copy:
[http://stackoverflow.com/questions/11490236/android-comprehensive-failproof-music-service-across-multiple-activites][1]
However, I am getting a null pointer exception on: StartupActivity.getService().musicStart(); Any ideas why this might be null? Here is my version of the (abridged) main java:
public class homescreenfruit extends Activity {
// bounded service
private static MusicService mBoundService;
// whetere service is bounded or not
private boolean mIsBound;
SharedPreferences myPrefs;
SharedPreferences.Editor prefsEditor;
boolean snd1 = true;
boolean snd2 = true;
boolean snd3 = true;
Handler myHandler = new Handler();
// int lastsongplayed=1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.homescreen);
doBindService();
myPrefs = this.getSharedPreferences("myPrefs", MODE_WORLD_READABLE);
final SharedPreferences.Editor prefsEditor = myPrefs.edit();
SoundManager.getInstance();
SoundManager.initSounds(this);
SoundManager.loadSounds();
{ // audio settings setup and run
snd3 = myPrefs.getBoolean("snd3return", true);
// ********************FIALS BELOW*********************
if (snd3==true){
homescreenfruit.getService().musicStart(); // FAILS HERE WITH NPE
}
ImageButton ibs3 = (ImageButton) findViewById(R.id.sound3); // this is the music
ibs3.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Log.e("sound3 start : ", " yep");
ImageButton ibs3 = (ImageButton) findViewById(R.id.sound3);
if (snd3==true){
homescreenfruit.getService().musicStop();
prefsEditor.putBoolean("snd3return", false); snd3=false;
ibs3.setBackgroundResource(R.drawable.noteoff);
}
else if (snd3==false){
prefsEditor.putBoolean("snd3return", true); snd3=true;
ibs3.setBackgroundResource(R.drawable.noteon);
homescreenfruit.getService().musicStart();
// restart playing the music - add programming
homescreenfruit.getService().musicStart();
}
prefsEditor.commit();
}
});
final Runnable playmusic = new Runnable() //
{
public void run() {
if (snd3==true){
homescreenfruit.getService().musicStart();}
}
};
public void onBackPressed() {
if (snd3=true)
SoundManager.playSound(96, 1);
Log.e("onBack pressed", "onBack pressed");
finish();
}
public void onPause() {
super.onPause();
if (snd3=true)
{
homescreenfruit.getService().musicPause();
}
Log.e("onPause", "onPause");
}
public void onStop() {
super.onStop();
if (snd3=true){
homescreenfruit.getService().musicStop();
}
}
public void onResume() {
super.onResume();
if (snd3==true){
homescreenfruit.getService().musicStart();
}
}
public void onDestroy() {
super.onDestroy();
doUnbindService();
}
private final ServiceConnection mServiceConnection = new ServiceConnection() {
// removed override
public void onServiceConnected(ComponentName className, IBinder service) {
setService(((MusicService.LocalBinder) service).getService());
}
// removed override
public void onServiceDisconnected(ComponentName className) {
setService(null);
}
};
private void doBindService() {
Intent service = new Intent(getBaseContext(), MusicService.class);
// start service and bound it
startService(service);
bindService(new Intent(this, MusicService.class), mServiceConnection, Context.BIND_AUTO_CREATE);
mIsBound = true;
}
private void doUnbindService() {
if (mIsBound) {
// Detach existing connection.
unbindService(mServiceConnection);
mIsBound = false;
}
}
public static MusicService getService() {
return mBoundService;
}
private static void setService(MusicService mBoundService) {
homescreenfruit.mBoundService = mBoundService;
}
}
I have implemented CarefulMediaPlayer and Music Service both as well as per the link. Is that correct?
I have the folowing method in a Service in my appplication:
public void switchSpeaker(boolean speakerFlag){
if(speakerFlag){
audio_service.setSpeakerphoneOn(false);
}
else{
audio_service.setSpeakerphoneOn(true);
}
}
So my question is whats the best and most effective way to be able to use this method in an Activity like follows
final Button speaker_Button = (Button) findViewById(R.id.widget36);
speaker_Button.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){
switchSpeaker(true); //method from Service
}
});
Do I have to do an AIDL or is there a simpler way?
There are 3 ways to binding service with your activity.
IBinder Implementation
Using Messanger
Using AIDL
Among these IBinder Implementation is the best suit in your case
Example of IBinder class
1. Server.java Service
public class Server extends Service{
IBinder mBinder = new LocalBinder();
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
public class LocalBinder extends Binder {
public Server getServerInstance() {
return Server.this;
}
}
public void switchSpeaker(boolean speakerFlag){
if(speakerFlag){
audio_service.setSpeakerphoneOn(false);
}
else{
audio_service.setSpeakerphoneOn(true);
}
}
}
2. Client.java Activity
public class Client extends Activity {
boolean mBounded;
Server mServer;
TextView text;
Button button;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
text = (TextView)findViewById(R.id.text);
button = (Button) findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
mServer.switchSpeaker(true);
}
});
}
#Override
protected void onStart() {
super.onStart();
Intent mIntent = new Intent(this, Server.class);
bindService(mIntent, mConnection, BIND_AUTO_CREATE);
};
ServiceConnection mConnection = new ServiceConnection() {
public void onServiceDisconnected(ComponentName name) {
Toast.makeText(Client.this, "Service is disconnected", 1000).show();
mBounded = false;
mServer = null;
}
public void onServiceConnected(ComponentName name, IBinder service) {
Toast.makeText(Client.this, "Service is connected", 1000).show();
mBounded = true;
LocalBinder mLocalBinder = (LocalBinder)service;
mServer = mLocalBinder.getServerInstance();
}
};
#Override
protected void onStop() {
super.onStop();
if(mBounded) {
unbindService(mConnection);
mBounded = false;
}
};
}
Example of Messanger class
1. Server.java service
public class Server extends Service{
Messenger messenger = new Messenger(new LocalHandler());
Messenger clientMessenger;
static final int SysterTime = 0;
static final int AddHandler = 1;
List<Handler> mHandlers;
#Override
public void onCreate() {
super.onCreate();
mHandlers = new ArrayList<Handler>();
}
#Override
public IBinder onBind(Intent intent) {
return messenger.getBinder();
}
public class LocalHandler extends Handler {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case SysterTime:
SimpleDateFormat mDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
clientMessenger.send(Message.obtain(null, SysterTime, mDateFormat.format(new Date())));
} catch (RemoteException e) {
e.printStackTrace();
}
break;
case AddHandler:
clientMessenger = new Messenger((Handler) msg.obj);
try {
clientMessenger.send(Message.obtain(null, AddHandler, "Registed messanger"));
} catch (RemoteException e) {
e.printStackTrace();
}
break;
default:
break;
}
super.handleMessage(msg);
}
}
}
2. Client.java Activity
public class Client extends Activity {
Messenger messenger;
boolean mBounded;
TextView text;
Button button;
Button register;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
text = (TextView)findViewById(R.id.text);
button = (Button) findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Message message = Message.obtain(null, Server.SysterTime, null);
try {
messenger.send(message);
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
register = (Button) findViewById(R.id.register);
register.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Message message = Message.obtain(null, Server.AddHandler, new ClientHandle());
try {
messenger.send(message);
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
public class ClientHandle extends Handler {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case Server.SysterTime:
text.setText(msg.obj.toString());
break;
case Server.AddHandler:
text.setText(msg.obj.toString());
break;
default:
break;
}
super.handleMessage(msg);
}
}
#Override
protected void onStart() {
super.onStart();
bindService(new Intent(this, Server.class), mConnection, BIND_AUTO_CREATE);
}
#Override
protected void onStop() {
super.onStop();
if(mBounded) {
unbindService(mConnection);
}
}
ServiceConnection mConnection = new ServiceConnection() {
public void onServiceDisconnected(ComponentName name) {
mBounded = false;
messenger = null;
}
public void onServiceConnected(ComponentName name, IBinder service) {
Toast.makeText(Client.this, "Service is connected", 1000).show();
messenger = new Messenger(service);
mBounded = true;
}
};
}
Example of AIDL
1. IRemoteService.aidl
package com.example.bindservice.aidl;
interface IRemoteService {
String getMessage(String msg);
}
2. Server.java Service
public class Server extends Service{
#Override
public IBinder onBind(Intent intent) {
return mStub;
}
IRemoteService.Stub mStub = new IRemoteService.Stub() {
public String getMessage(String msg) throws RemoteException {
return msg;
}
};
}
3. Client.java Activity
public class Client extends Activity {
Button button;
TextView text;
boolean mBound;
IRemoteService mIRemoteService;
EditText etMsg;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
text = (TextView)findViewById(R.id.text);
button = (Button) findViewById(R.id.button);
etMsg = (EditText)findViewById(R.id.etMsg);
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if(mBound) {
try {
text.setText(mIRemoteService.getMessage(etMsg.getText().toString()));
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
});
}
#Override
protected void onStart() {
super.onStart();
bindService(new Intent(Client.this, Server.class), mConnection, BIND_AUTO_CREATE);
}
#Override
protected void onStop() {
super.onStop();
if(mBound) {
unbindService(mConnection);
mBound = false;
}
}
ServiceConnection mConnection = new ServiceConnection() {
public void onServiceDisconnected(ComponentName name) {
mIRemoteService = null;
mBound = false;
}
public void onServiceConnected(ComponentName name, IBinder service) {
mIRemoteService = IRemoteService.Stub.asInterface(service);
mBound = true;
}
};
}
For more study you can refer this document
You have to expose service`s switchSpeaker method for clients. Define your .aidl file. Than bind to that service from your activity and simply call switchSpeaker.
See documentation
No other simple way to call this method, only if it static)
It's public, right :)
You can call bindService(Intent) method. Tale a look at ApiDemos, the class LocalServiceBinding.
In the callback method onServiceConnected, you can see:
public void onServiceConnected(ComponentName className, IBinder service) {
// This is called when the connection with the service has been
// established, giving us the service object we can use to
// interact with the service. Because we have bound to a explicit
// service that we know is running in our own process, we can
// cast its IBinder to a concrete class and directly access it.
mBoundService = ((LocalService.LocalBinder)service).getService();
// Tell the user about this for our demo.
Toast.makeText(LocalServiceBinding.this, R.string.local_service_connected,
Toast.LENGTH_SHORT).show();
}
Now, use the service object (mBoundService) to call the method.
That's all :)