Timer on onDraw - android

start button -> game.class -> gameview.class then loop again on game.class when player finish the 1st level it will call gameview.class to generate again the 2nd level. My problem is that my timer will also regenerate and restarts when going on the 2nd level. How can I make my timer pause and resume in this kind of flow of game?
on my Game.Class:
public void onCreate(Bundle savedInstanceState) {
timeCounter = new TimeCounter();
super.onCreate(savedInstanceState);
Intent intent = getIntent();
Bundle extras = intent.getExtras();
this.maze = (Maze) getLastNonConfigurationInstance();
if (this.maze == null) {
this.maze = (Maze) extras.get("maze");
}
gview = new GameView(this);
gview.setTimeCounter(timeCounter);
gview.setMaze(this.maze);
setContentView(gview);
and on my GameView.Class:
protected void onDraw(Canvas canvas) {
if (startTimer) {
timeCounter.start();
invalidate();
int secondss = timeCounter.getTimeSeconds();
String text = String.format("%02d:%02d", secondss / 60,
secondss % 60);
timer.getTextBounds(text, 0, text.length(), textBounds);
canvas.drawText(text, (this.getWidth() - textBounds.right) - 5,
(this.getHeight() - textBounds.bottom) - 5, timer);
}
and when the 1st level finish it will call this method:
void shownextmaze() {
Random rand = new Random();
Intent game = new Intent(context, Game.class);
nextmaze = rand.nextInt(6) + 1;
Maze maze = MazeCreator.getMaze(nextmaze);
game.putExtra("maze", maze);
context.startActivity(game);
timeCounter.resume();
}
How can I make my timer run until the 4 levels are cleared?

It is logical that onDraw will be called and timer will be start again. You should start your timer in a service and run it in background thread. Each time you want to access it value you can bind to service.
Check this guideline.
In this code each time you open the app you will see updated value:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startService(new Intent(MainActivity.this, MyService.class));
doBindService();
((Button) findViewById(R.id.button1))
.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (mBoundService != null) {
((TextView) findViewById(R.id.textView1))
.setText(mBoundService.getValue() + "");
}
}
});
((Button) findViewById(R.id.button2))
.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
mBoundService = null;
stopService(new Intent(MainActivity.this,
MyService.class));
doUnbindService();
}
});
}
private MyService mBoundService;
private boolean mIsBound;
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
mBoundService = ((MyService.LocalBinder) service).getService();
((TextView) findViewById(R.id.textView1)).setText(mBoundService
.getValue() + "");
}
public void onServiceDisconnected(ComponentName className) {
mBoundService = null;
}
};
void doBindService() {
bindService(new Intent(MainActivity.this, MyService.class),
mConnection, Context.BIND_AUTO_CREATE);
mIsBound = true;
}
void doUnbindService() {
if (mIsBound) {
// Detach our existing connection.
unbindService(mConnection);
mIsBound = false;
}
}
#Override
protected void onDestroy() {
super.onDestroy();
doUnbindService();
}
}
And a service:
public class MyService extends Service {
private final IBinder mBinder = new LocalBinder();
// private TimeCounter timeCounter;
int x = 0;
public class LocalBinder extends Binder {
MyService getService() {
return MyService.this;
}
}
#Override
public void onCreate() {
new Thread(new Runnable() {
public void run() {
while (true) {
x++;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
public int getValue() {
return x;
}
}
Maybe you need activity_main.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="${relativePackage}.${activityClass}" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#+id/textView1"
android:text="Show Updated value" />
<Button
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#+id/button1"
android:layout_marginTop="28dp"
android:text="Stop Service" />
</RelativeLayout>

Related

Trouble running background service Android

I have some simple code intended to start a background service that updates a static integer from my MainActivity every second. I also have a button that when clicked, updates a TextView with the value of that static integer. However, every time I start the service, it only increments the value once and stops, instead of continuously incrementing it until I press stop service.
This is my code:
public class MainActivity extends AppCompatActivity {
public static int count;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
count = 0;
}
public void pressButton(View view) {
TextView textView = (TextView) findViewById(R.id.textView);
textView.setText("" + count);
}
public void startService(View view) {
startService(new Intent(getBaseContext(), MyService.class));
}
public void stopService(View view) {
stopService(new Intent(getBaseContext(), MyService.class));
}
}
And my service:
public class MyService extends Service {
public MyService() {
}
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
MainActivity.count++;
}
}, 1000);
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
}
}
I can't figure out what seems to be the problem.
public class DownloadService extends IntentService {
String pdfName = "";
public DownloadService() {
super("DownloadService");
}
#Override
protected void onHandleIntent(#Nullable Intent intent) {
showNotificationProgress();
if (intent != null) {
pdfName = intent.getStringExtra("pdfName");
}
downloadPDF ( ) // Implement this method
}
public void writeBytesToFile(boolean status, String encodedString) {
if (status && !TextUtils.isEmpty(encodedString)) {
byte[] decodedArry = decodeBase64String(encodedString);
String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + File.separator + pdfName;
File fileOut = new File(path);
// if file doesnt exists, then create it
if (!fileOut.exists()) {
try {
//noinspection ResultOfMethodCallIgnored
fileOut.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
try (FileOutputStream fileOuputStream = new FileOutputStream(fileOut)) {
fileOuputStream.write(decodedArry);
completed = true;
} catch (IOException e) {
completed = false;
e.printStackTrace();
} finally {
if (completed) {
//do something
}
}
} else {
hideNotificationProgress();
}
}
private static byte[] decodeBase64String(String encodedString) {
return Base64.decode(encodedString, Base64.DEFAULT);
}
public static void hideNotificationProgress() {
mNotifyManager.cancel(1);
}
private void showNotificationProgress() {
final int id = 1;
mNotifyManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
final NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this);
mBuilder.setContentTitle("PDF Download")
.setContentText("Download in progress")
.setSmallIcon(android.R.drawable.stat_sys_download);
// Start a lengthy operation in a background thread
new Thread(
new Runnable() {
#Override
public void run() {
// Do the "lengthy" operation 20 times
// Sets the progress indicator to a max value, the
// current completion percentage, and "determinate"
// state
mBuilder.setProgress(0, 0, true);
// Issues the notification
mNotifyManager.notify(id, mBuilder.build());
// Sleeps the thread, simulating an operation
// that takes time
try {
// Sleep for 5 seconds
Thread.sleep(1000);
} catch (InterruptedException ignored) {
}
}
}
// Starts the thread by calling the run() method in its Runnable
).start();
}
}
Why don't you try Intent Service like this.
And start this service as below
Intent intent = new Intent(AActivity, DownloadService.class);
intent.putExtra("pdfName", pdfName);
holdingActivity.startService(intent);
This code shows how to update the UI in an Android Activity from a background Service.
BroadcastTest.java
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
public class BroadcastTest extends Activity {
private static final String TAG = "BroadcastTest";
private Intent intent;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
intent = new Intent(this, BroadcastService.class);
}
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
updateUI(intent);
}
};
#Override
public void onResume() {
super.onResume();
startService(intent);
registerReceiver(broadcastReceiver, new IntentFilter(BroadcastService.BROADCAST_ACTION));
}
#Override
public void onPause() {
super.onPause();
unregisterReceiver(broadcastReceiver);
stopService(intent);
}
private void updateUI(Intent intent) {
String counter = intent.getStringExtra("counter");
String time = intent.getStringExtra("time");
Log.d(TAG, counter);
Log.d(TAG, time);
TextView txtDateTime = (TextView) findViewById(R.id.txtDateTime);
TextView txtCounter = (TextView) findViewById(R.id.txtCounter);
txtDateTime.setText(time);
txtCounter.setText(counter);
}
}
BroadcastService.java
import java.util.Date;
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
public class BroadcastService extends Service {
private static final String TAG = "BroadcastService";
public static final String BROADCAST_ACTION = "com.websmithing.broadcasttest.displayevent";
private final Handler handler = new Handler();
Intent intent;
int counter = 0;
#Override
public void onCreate() {
super.onCreate();
intent = new Intent(BROADCAST_ACTION);
}
#Override
public void onStart(Intent intent, int startId) {
handler.removeCallbacks(sendUpdatesToUI);
handler.postDelayed(sendUpdatesToUI, 1000); // 1 second
}
private Runnable sendUpdatesToUI = new Runnable() {
public void run() {
DisplayLoggingInfo();
handler.postDelayed(this, 10000); // 10 seconds
}
};
private void DisplayLoggingInfo() {
Log.d(TAG, "entered DisplayLoggingInfo");
intent.putExtra("time", new Date().toLocaleString());
intent.putExtra("counter", String.valueOf(++counter));
sendBroadcast(intent);
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onDestroy() {
handler.removeCallbacks(sendUpdatesToUI);
super.onDestroy();
}
}
res/layout/main.xml
<?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"
>
<TableLayout android:id="#+id/tableGPS"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="7px"
android:stretchColumns="1">
<TableRow
android:layout_margin="1dip">
<TextView android:layout_gravity="right"
android:text="Time:"
android:layout_marginRight="7px"
android:layout_width="60px" />
<TextView android:id="#+id/txtDateTime"
android:gravity="left"
android:layout_span="2" />
</TableRow>
<TableRow
android:layout_margin="1px">
<TextView android:layout_gravity="right"
android:text="Counter:"
android:layout_marginRight="7px"
android:layout_width="60px" />
<TextView android:id="#+id/txtCounter"
android:gravity="left" />
</TableRow>
</TableLayout>
</LinearLayout>
Post delay only runs one time. You need to schedule a reoccurring task or just create a Runnable that will recall the task over and over.
final Handler mHandler = new Handler();
Runnable runner = new Runnable() {
#Override
public void run() {
MainActivity.count++;
mHandler.postDelayed(runner, 1000);
}
}
mHandler.postDelayed(runner, 1000);

Cannot stop timer in Android? How to solve it?

I am writing a class to control start and stop timer in Android. The controller is an Activity that will send start or stop value. In the TimerControl class, I write two functions that use to start and stop the timer. I can start the timer, but I cannot stop it. How can I solve it? This is my code
//In Controller class
//===========Start========
Intent smsTimer = new Intent(getApplicationContext(), TimmerControl.class);
smsTimer.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
smsTimer.putExtra("input_timer", "start");
getApplicationContext().startActivity(smsTimer);
//===========Stop========
Intent smsTimer = new Intent(getApplicationContext(), TimmerControl.class);
smsTimer.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
smsTimer.putExtra("input_timer", "stop");
getApplicationContext().startActivity(smsTimer);
This is my code of TimerControl
public class TimmerControl extends Activity {
private CountDownTimer timer_SMS;
private String TAG="TimmerControl";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
if (intent != null &&intent.getExtras() != null) {
Bundle bundle = intent.getExtras();
if (!bundle.getString("input_timer").equals(null)) {
String input_timer = bundle.getString("input_timer");
if(input_timer.equals("start")) {// start
startSMSTimer();
}
else if(input_timer.equals("stop")) {// stop
stopSMSTimer();
}
else{}
}
}
finish();
}
public void startSMSTimer(){
if (timer_SMS != null) {
timer_SMS.cancel();
timer_SMS = null;
}
timer_SMS = new CountDownTimer(100000, 20000) {
#Override
public void onTick(long millisUntilFinished) {
long timOver = 100000 - millisUntilFinished;
Log.d(TAG, String.valueOf(timOver));
}
#Override
public void onFinish() { }
};
timer_SMS.start();
}
public void stopSMSTimer(){
if (timer_SMS != null) {
timer_SMS.cancel();
timer_SMS = null;
}
}
}
You need to send "stop" while sending intent for stop as follows :
//In Controller class
//===========Start========
Intent smsTimer = new Intent(getApplicationContext(), TimmerControl.class);
smsTimer.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
smsTimer.putExtra("input_timer", "start"); // start
getApplicationContext().startActivity(smsTimer);
//===========Stop========
Intent smsTimer = new Intent(getApplicationContext(), TimmerControl.class);
smsTimer.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
smsTimer.putExtra("input_timer", "stop"); // stop
getApplicationContext().startActivity(smsTimer);
public class TimmerControl extends Service {
CountDownTimer timer_SMS;
private BroadcastReceiver mReceiver;
#Override
public void onCreate() {
super.onCreate();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("start");
intentFilter.addAction("stop");
mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//extract our message from intent
if (intent.getAction().equals("start")) {
startSMSTimer();
}
if (intent.getAction().equals("stop")) {
stopSMSTimer();
}
}
};
this.registerReceiver(mReceiver, intentFilter);
}
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
this.unregisterReceiver(this.mReceiver);
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
public void startSMSTimer() {
if (timer_SMS != null) {
timer_SMS.cancel();
timer_SMS = null;
}
timer_SMS = new CountDownTimer(100000, 1000) {
#Override
public void onTick(long millisUntilFinished) {
long timOver = 100000 - millisUntilFinished;
Log.e("Time: ", ""+timOver);
}
#Override
public void onFinish() {
Log.e("finished: ","");
}
};
timer_SMS.start();
}
public void stopSMSTimer() {
if (timer_SMS != null) {
timer_SMS.cancel();
timer_SMS = null;
Log.e("Stop: ","");
}
stopSelf();
}
}
SMSControllerActivity.java
public class SMSControllerActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_smscontroller);
findViewById(R.id.btn_start).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (!isServiceRunning(TimmerControl.class))
startService(new Intent(SMSControllerActivity.this, TimmerControl.class));
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
sendBroadcast(new Intent("start"));
}
}, 500);
}
});
findViewById(R.id.btn_stop).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
sendBroadcast(new Intent("stop"));
}
});
;
}
private boolean isServiceRunning(Class<?> serviceClass) {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
}
activity_smscontroller.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="#+id/btn_start"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="Start" />
<Button
android:id="#+id/btn_stop"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="Stop" />
</LinearLayout>

Null pointer exception when trying to play game background music with MediaPlayer

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?

Pausing a service

i am writing a music player example using services.i am able to start and stop the service by using the activity which is in other application.but now i need to pause the player.how can i do this because their are no onpause method in services
Media Player
utilise : pause();
to restart: prepare()
start()
**LocalService.java** public class LocalService extends Service {
private NotificationManager mNM;
MediaPlayer mMediaPlayer;
private final IBinder mBinder = new LocalBinder();
public class LocalBinder extends Binder {
LocalService getService() {
return LocalService.this;
}
}
#Override
public void onCreate() {
mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
}
#Override
public void onDestroy() {
mNM.cancel(R.string.local_service_started);
Toast.makeText(this, R.string.local_service_stopped, Toast.LENGTH_SHORT).show();
}
public void startMp3Player() {
mMediaPlayer = MediaPlayer.create(getApplicationContext(),
R.raw.abc);
mMediaPlayer.start();
}
public void mp3Stop() {
mMediaPlayer.stop();
mMediaPlayer.release();
}
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
}
**LocalServiceBinding.JAVA** public class LocalServiceBinding extends Activity {
private boolean mIsBound;
private LocalService mBoundService;
Button mPlayButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.local_service_binding);
Button button = (Button)findViewById(R.id.bind);
button.setOnClickListener(mBindListener);
button = (Button)findViewById(R.id.unbind);
button.setOnClickListener(mUnbindListener);
mPlayButton = (Button)findViewById(R.id.play);
mPlayButton.setOnClickListener(mPlayListener);
mPlayButton.setText("Play");
mPlayButton.setEnabled(false);
}
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
mBoundService = ((LocalService.LocalBinder)service).getService();
Toast.makeText(LocalServiceBinding.this, R.string.local_service_connected,
Toast.LENGTH_SHORT).show();
}
public void onServiceDisconnected(ComponentName className) {
mBoundService = null;
Toast.makeText(LocalServiceBinding.this, R.string.local_service_disconnected,
Toast.LENGTH_SHORT).show();
}
};
private OnClickListener mBindListener = new OnClickListener() {
public void onClick(View v) {
bindService(new Intent(LocalServiceBinding.this,
LocalService.class), mConnection, Context.BIND_AUTO_CREATE);
mIsBound = true;
mPlayButton.setEnabled(true);
}
};
private OnClickListener mPlayListener = new OnClickListener() {
public void onClick(View v) {
if(mPlayButton.getText() == "Play")
{
mBoundService.startMp3Player();
mPlayButton.setText("Stop");
}
else
{
mBoundService.mp3Stop();
mPlayButton.setText("Play");
}
}
};
private OnClickListener mUnbindListener = new OnClickListener() {
public void onClick(View v) {
if (mIsBound) {
unbindService(mConnection);
mIsBound = false;
mPlayButton.setEnabled(false);
}
}
};
}

Android - Using method from a Service in an Activity?

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 :)

Categories

Resources