I am developing a very simple app that play a song forever until the user stop it.
I am using the bind/unbind service functions just to send a simple message ( hello ) from the activity to the service.
The problem is that when I tap to stop the song, it doesn't stop ( even if in the Logcat I see the "stop" string ). Why ?
This is my code:
MainActivity:
public class MainActivity extends AppCompatActivity {
boolean started = false;
boolean musicBound = false;
TextView button;
private Intent playIntent;
private PlayerService musicSrv;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (TextView) findViewById(R.id.playstopbutton);
playIntent = new Intent(this, PlayerService.class);
}
#Override
public void onResume(){
super.onResume();
// put your code here...
if(!started) {
// button.setText(">");
}else{
// button.setText("||");
}
}
//connect to the service
private ServiceConnection musicConnection = new ServiceConnection(){
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.i("My App", "conn");
PlayerService.MusicBinder binder = (PlayerService.MusicBinder)service;
//get service
musicSrv = binder.getService();
//pass list
musicSrv.tryit("hello");
musicBound = true;
}
#Override
public void onServiceDisconnected(ComponentName name) {
Log.i("My App", "disc");
musicBound = false;
}
};
public void playstop(View v)
{
if(!started) {
Log.i("My App", "start");
started = true;
// button.setText("||");
bindService(playIntent, musicConnection, Context.BIND_AUTO_CREATE);
startService(playIntent);
}else{
Log.i("My App", "stop");
started = false;
// button.setText(">");
stopService(playIntent);
musicSrv=null;
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
protected void onDestroy() {
if (musicConnection != null) {
unbindService(musicConnection);
}
stopService(playIntent);
musicSrv=null;
super.onDestroy();
}
}
PlayerService:
public class PlayerService extends Service
{
MediaPlayer mediaPlayer = null;
String title = "aaaa";
String msg = "bbbb";
String ticker = "just a ticker";
private final IBinder musicBind = new MusicBinder();
#Override
public void onCreate() {
mediaPlayer = MediaPlayer.create(this, R.raw.song);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (!mediaPlayer.isPlaying()) {
mediaPlayer.setLooping(true);
mediaPlayer.start();
}
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
Notification notification = new Notification.Builder(this)
.setContentTitle(title)
.setContentText(msg)
.setSmallIcon(R.drawable.note2)
.setContentIntent(pendingIntent)
.setTicker(ticker).setColor(0xff222222).build();
startForeground(11, notification);
return START_STICKY;
}
//binder
public class MusicBinder extends Binder {
PlayerService getService() {
return PlayerService.this;
}
}
//activity will bind to service
#Override
public IBinder onBind(Intent intent) {
return musicBind;
}
//release resources when unbind
#Override
public boolean onUnbind(Intent intent){
mediaPlayer.stop();
mediaPlayer.release();
return false;
}
public void tryit(String stringa){
Log.i("My App", stringa);
}
public void onDestroy() {
if (mediaPlayer.isPlaying()) {
mediaPlayer.stop();
}
mediaPlayer.release();
stopForeground(true);
Log.i("PROVA SERVICE", "Distruzione Service");
}
}
when I tap to stop the song, it doesn't stop
Because you are only calling stop() on the MediaPlayer if either:
the client unbinds from it (onUnbind()), which is not what your client is doing, or
the client unbinds from it and you stop it (onDestroy()), which is not what your client is doing
A service will be destroyed when both of the following statements are true:
Each client that had bound to is unbinds, and
If startService() had been called for this service, stopService() is called
In this case, you are calling stopService(), but you are still bound to the service, so onDestroy() is not called.
Related
In my app, I am using bound services. However, while running the code, I start the service and bind to it(OnBind() method works), but afterwards OnStartService() is never called, and my service is equal to null.
Here is my service code:
public class MyService extends Service{
boolean toExit = false;
boolean isThreatDetectionOn;
boolean isDanger = false;
int counter;
class MyServiceBinder extends Binder {
public MyService getService()
{
return MyService.this;
}
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
Log.i("Bind", "thats good");
return null;
}
#Override
public void onDestroy() {
stop();
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
isThreatDetectionOn = true;
new Thread(new Runnable() {
#Override
public void run() {
start();
}
}).start();
return START_STICKY;
}
}
start() and stop() are method that run in the service that start generating random numbers and stop generating random numbers, respectively.
Here is the bind/unbind code for the service:
private MyService ListeningService;
private boolean isServiceBound = false;
private ServiceConnection serviceConnection;
bindService = (Button) findViewById(R.id.button7);
bindService.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view)
{
Log.i("Great","Button Bind Clicked");
if(serviceConnection == null)
{
Log.i("Great","Service Connection is Null");
serviceConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
MyService.MyServiceBinder myBinder = (MyService.MyServiceBinder)iBinder;
listeningService = myBinder.getService();
isServiceBound = true;
Log.i("Yes", "Service Connected");
}
#Override
public void onServiceDisconnected(ComponentName componentName) {
isServiceBound = false;
Log.i("No", "Service DisConnected");
}
};
}
bindService(serviceIntent, serviceConnection, Context.BIND_AUTO_CREATE);
}
});
unbindService = (Button) findViewById(R.id.button8);
unbindService.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (isServiceBound)
{
unbindService(serviceConnection);
isServiceBound = false;
Log.i("No", "Service DisConnected");
}
}
});
Even after onBind() is called(in the logs it says "Bind:thats good") isServiceBound still remains false when it should now become true because the service is now connected.
I have searched a lot on stackoverflow regarding this issue but nothing seems to work.
I am developing a music player which plays music by binding to a service. I have two activities.The first activity(called as AllSongs) provides me with the list of songs.When I select a song it starts another activity(called as SongUI) which plays the song by binding to a service.
Now when I move back to my AllSongs activity the music stops.Now when I select a song again,my SongUI activity is started and when I go back to my AllSongs activity, the music does not stop and plays in the background.I am not able to understand what is causing this issue. I think I am doing something silly somewhere but am not able to figure it out. I want songs to be played in the background same as any music player does.Here is the code.
AllSongs activity:
public class AllSongs extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.allsongs_activity);
getSongList();
from = new String[]{MediaStore.Audio.Media.TITLE, MediaStore.Audio.Media.ARTIST, MediaStore.Audio.Media.DURATION};
to = new int[]{R.id.title_entry,R.id.artist_entry,R.id.duration_entry};
listView = (ListView) findViewById(R.id.listView);
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,R.layout.singlesong,myCursor,from,to,SimpleCursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent songUIIntent = new Intent(getApplicationContext(),SongUI.class);
songUIIntent.putExtra("position",id);
startActivity(songUIIntent);
}
});
}
private void getSongList() {
ContentResolver myContentResolver = getContentResolver();
myCursor = myContentResolver.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,null,null,null,null);
if(myCursor!=null && myCursor.moveToFirst()) {
int titleColumn = myCursor.getColumnIndex(MediaStore.Audio.Media.TITLE);
int idColumn = myCursor.getColumnIndex(android.provider.MediaStore.Audio.Media._ID);
int artistColumn = myCursor.getColumnIndex(android.provider.MediaStore.Audio.Media.ARTIST);
long albumID = myCursor.getLong(myCursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));
do {
long ID = myCursor.getLong(idColumn);
String title = myCursor.getString(titleColumn);
String artist = myCursor.getString(artistColumn);
songList.add(new currentSong(ID,title,artist));
}while (myCursor.moveToNext());
}
}
#Override
protected void onDestroy() {
super.onDestroy();
}
}
SongUI activity:
public class SongUI extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.song_ui);
button = (Button) findViewById(R.id.play);
isBound = false;
Intent receivedIntent = getIntent();
position = receivedIntent.getLongExtra("position",0);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main,menu);
return super.onCreateOptionsMenu(menu);
}
public void playAudio(View view) {
Intent objIntent = new Intent(this,MyService.class);
if(!isBound)
{
objIntent.putExtra("position", position);
startService(objIntent);
isBound=true;
button.setBackgroundResource(R.drawable.play);
bindService(objIntent, myConnection, Context.BIND_AUTO_CREATE);
}
else
{
myServiceObject.pauseAudio();
button.setBackgroundResource(R.drawable.play);
isBound=false;
unbindService(myConnection);
}
}
public void stopAudio(View view) {
Intent objIntent = new Intent(this,MyService.class);
if(isBound)
{
isBound=false;
unbindService(myConnection);
stopService(objIntent);
}
else {
stopService(objIntent);
}
button.setBackgroundResource(R.drawable.play);
}
private ServiceConnection myConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className,
IBinder service) {
myServiceObject = ((MusicBinder) service).getService();
isBound = true;
}
public void onServiceDisconnected(ComponentName arg0) {
isBound = false;
}
};
#Override
protected void onDestroy() {
super.onDestroy();
if (isBound) {
unbindService(myConnection);
isBound = false;
}
}
}
MyService class
public class MyService extends Service {
#Override
public void onCreate() {
super.onCreate();
player = new MediaPlayer();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "on startCommand is called");
long id = intent.getLongExtra("position",0);
Uri contentUri = ContentUris.withAppendedId(
android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, id);
Log.d(TAG, "Service is Started");
player = MediaPlayer.create(this,contentUri);
player.start();
Intent notIntent = new Intent(this, SongUI.class);
notIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendInt = PendingIntent.getActivity(this, 0,
notIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Notification.Builder builder = new Notification.Builder(this);
builder.setContentIntent(pendInt)
.setSmallIcon(R.drawable.play)
.setTicker(songTitle)
.setOngoing(true)
.setContentTitle("Playing")
.setContentText(songTitle);
Notification notification = builder.build();
startForeground(NOTIFY_ID, notification);
return Service.START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
Log.d(TAG, "on Bind is called");
return myBinder;
}
#Override
public boolean onUnbind(Intent intent){
Log.d(TAG,"onUnbind is called");
player.stop();
player.release();
return false;
}
public class MusicBinder extends Binder {
MyService getService() {
return MyService.this;
}
}
public void pauseAudio() {
if(player.isPlaying()) {
player.pause();
}
}
#Override
public void onDestroy() {
Log.d(TAG,"on destroy is called");
stopForeground(true);
}
I have figured out where I was going wrong. I was calling unbindService(myConnection) in onDestroy of my SongsUI activity which was stopping the playback.
And the reason why this was not the case the second time round was that I was returning false in onUnbind method. So the system was not calling onBind method the second time and subsequently onUnbind was also not getting called. Hence the playback was also not stopping.
onDestroy() is not being called after going main->map->main->map with stopping service in this case:
After Launching the app, the MainActivity is created which starts background tracking service. On the other hand, the user can use a checkbox list in the main activity to select his interested routes where the items of the checkbox list represents the routes.
After clicking the submit button, the alarmManager starts firing the data to the IntentService class every 30 seconds. Subsequently, connection with the server is established and retrieving data to the MapActivity is started after the user was redirected automatically to the MapActivity.
The user is able to stop and start the background service by using an icon in the menu of the both activities. I am facing problem to destroy the app in the case describes below.
With the current code:
After launching the app I can stop the service in the mainActivity and destory the app.
after launching the app when I change from the main activity to the map activity , I can stop and start the service as well as destroy the app with opening Mapactivity.
When I go as the following (mainActivity->mapActivity->MainAtivity->MapActivity) and closed the app with opening map view the app is not being destroyed and the service is not stoped. Also the onDestroy() in MapActivity is not being invoked. Here the app opens with the map view again.
But when I do the following:
adding startService(i)(as the code snippet four lines below) to the onStart() in the MapActivity after bindService I can destroy the app as well stoping and starting the service but the problem here is I dont want to start the service every time I am going from the MainActivity to the MapActivity since if the user stops the service in the MainActivity it must stay off when he goes from the main to the map.
#Override
protected void onStart() {
super.onStart();
// Bind to TrackingService.
Intent intent = new Intent(this, TrackingService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
Intent i = new Intent(this, TrackingService.class);
startService(i);
}
How can I destroy the app in this case in the MapActivity?
MainActivity:
public class MainActivity extends ActionBarActivity implements
AsyncTaskCallback {
boolean serviceStatus = true;
TrackingService mService;
boolean mBound = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.route_available);
// Start the TrackingService class.
Intent i = new Intent(this, TrackingService.class);
startService(i);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
System.out.println("ABC MainActivity onOptionsItemSelected was invoked.");
switch (item.getItemId()) {
case R.id.menu_toggle:
if (serviceStatus) {
item.setIcon(R.drawable.off);
item.setTitle("OFF");
serviceStatus = false;
mService.stopTrackingService();
} else {
item.setIcon(R.drawable.on);
item.setTitle("ON");
serviceStatus = true;
Intent i = new Intent(this, TrackingService.class);
startService(i);
System.out.println("ABC MainActivity onOptionsitemSelected ON");
}
return super.onOptionsItemSelected(item);
}
}
#Override
protected void onStart() {
super.onStart();
// Bind to TrackingService.
Intent intent = new Intent(this, TrackingService.class);
//To start the onPrepareOptionsMenue() after returning from the map activity to change the icon of the toggle button.
invalidateOptionsMenu();
}
#Override
protected void onStop() {
super.onStop();
//13.08.15
// Unbind from the service
if (mBound) {
unbindService(mConnection);
System.out.println("ABC MainActivity onStop() - unbindService(mConnection) was invoked. " + mBound);
mBound = false;
}else{
System.out.println("ABC MainActivity onStop() - unbindService(mConnection) was invoked. " + mBound);
}
}
#Override
protected void onDestroy() {
Intent i = new Intent(this, TrackingService.class);
stopService(i);
mService.stopTrackingService();
}
private ServiceConnection mConnection = new ServiceConnection(){
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
LocalBinder binder = (LocalBinder) service;
mService = binder.getService();
mBound = true;
}
#Override
public void onServiceDisconnected(ComponentName name) {
mBound = false;
}
};
}
MapActivity
public class MapActivity extends ActionBarActivity implements OnMapReadyCallback,
ConnectionCallbacks, OnConnectionFailedListener {
boolean serviceStatus;
TrackingService mService;
boolean mBound = false;
#Override
protected void onStart() {
super.onStart();
serviceStatus = getIntent().getExtras().getBoolean("ServiceStatusExtras");
if (serviceStatus) {
Intent i = new Intent(this, TrackingService.class);
bindService(i, mConnection, Context.BIND_AUTO_CREATE);
startService(i);
System.out.println("ABC MapActivity onStart serviceStatus = " + serviceStatus);
}
}
/** Defines callbacks for service binding, passed to bindService() */
private ServiceConnection mConnection = new ServiceConnection(){
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
// We've bound to LocalService, cast the IBinder and get LocalService instance
LocalBinder binder = (LocalBinder) service;
mService = binder.getService();
mBound = true;
//System.out.println("ABC Map onServiceConnected() - " + mBound);
}
#Override
public void onServiceDisconnected(ComponentName name) {
mBound = false;
//System.out.println("ABC Map onServiceDisconnected() - mBound");
}
};
#Override
protected void onStop() {
super.onStop();
if (mBound) {
unbindService(mConnection);
mBound = false;
}
}
#Override
protected void onDestroy() {
super.onDestroy();
markerMap.clear();
stopAlarm();
if(!serviceStatus){
Intent i = new Intent(this, TrackingService.class);
stopService(i);
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_toggle:
if (serviceStatus) {
item.setIcon(R.drawable.off);
item.setTitle("OFF");
serviceStatus = false;
if(mService!=null){
mService.stopTrackingService();
}
} else {
item.setIcon(R.drawable.on);
item.setTitle("ON");
serviceStatus = true;
Intent i = new Intent(this, TrackingService.class);
startService(i);
}
}
return super.onOptionsItemSelected(item);
}
}
TrackingService class:
public class TrackingService extends Service implements AsyncTaskCallback,
LocationListener {
LocationManager lm;
private final IBinder mBinder = new LocalBinder();
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
detectLocation();
return START_NOT_STICKY;
}
private void detectLocation() {
lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 12 * 1000, 0,
this);
}
public class LocalBinder extends Binder {
TrackingService getService() {
return TrackingService.this;
}
}
public void stopTrackingService(){
if(lm != null){
lm.removeUpdates(this);
}
}
}
}
I am working on android code that switches between two different activities. There is a service that plays music over both of these activities. The problem is that when i use the back button the service ( the music) stops. I have done research on the topic i have both onResume and onRestart methods in place....i can't figure out what to do next,any help will be greatly appreciated. Both activites and service are listed below.
MainActivity.java
public class MainActivity extends Activity {
MusicService myService;
private boolean isBound;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
isBound=false;
playAudio();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void onButtonClick(View v) {
Intent intent = new Intent(this, Second_activity.class);
startActivity(intent);
onStop();
///Intent i= new Intent(this,EmpireShips.class);
//// startActivity(i);
//// onStop();
}
public void playAudio() {
Intent objIntent = new Intent(this, MusicService.class);
if(!isBound)
{
bindService(objIntent, myConnection, Context.BIND_AUTO_CREATE);
isBound=true;
startService(objIntent);
}
else
{
myService.plauseAudio();
isBound=false;
unbindService(myConnection);
}
}
public void stopAudio(View view) {
Intent objIntent = new Intent(this, MusicService.class);
if(isBound)
{
isBound=false;
unbindService(myConnection);
stopService(objIntent);
}
else
stopService(objIntent);
}
private ServiceConnection myConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className,
IBinder service) {
myService = ((MusicService.MyLocalBinder) service).getService();
isBound = true;
}
public void onServiceDisconnected(ComponentName arg0) {
isBound = false;
}
};
#Override
protected void onDestroy() {
super.onDestroy();
if (isBound) {
// Disconnect from an application service. You will no longer
// receive calls as the service is restarted, and the service is
// now allowed to stop at any time.
unbindService(myConnection);
isBound = false;
}
}
public void onStop(){
super.onStop();
if (isBound) {
// Disconnect from an application service. You will no longer
// receive calls as the service is restarted, and the service is
// now allowed to stop at any time.
unbindService(myConnection);
isBound = false;
myService.plauseAudio();
}
}
Second_activity.java
public class Second_activity extends Activity {
MusicService myService;
private boolean isBound;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
isBound=false;
playAudio();
}
public void playAudio() {
Intent objIntent = new Intent(this, MusicService.class);
if(!isBound)
{
bindService(objIntent, myConnection, Context.BIND_AUTO_CREATE);
isBound=true;
startService(objIntent);
}
else
{
myService.plauseAudio();
isBound=false;
unbindService(myConnection);
}
}
public void stopAudio(View view) {
Intent objIntent = new Intent(this, MusicService.class);
if(isBound)
{
isBound=false;
unbindService(myConnection);
stopService(objIntent);
}
else
stopService(objIntent);
}
private ServiceConnection myConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className,
IBinder service) {
myService = ((MusicService.MyLocalBinder) service).getService();
isBound = true;
}
public void onServiceDisconnected(ComponentName arg0) {
isBound = false;
}
};
#Override
protected void onDestroy() {
super.onDestroy();
if (isBound) {
// Disconnect from an application service. You will no longer
// receive calls as the service is restarted, and the service is
// now allowed to stop at any time.
unbindService(myConnection);
isBound = false;
}
}
public void onStop(){
super.onStop();
if (isBound) {
// Disconnect from an application service. You will no longer
// receive calls as the service is restarted, and the service is
// now allowed to stop at any time.
unbindService(myConnection);
isBound = false;
myService.plauseAudio();
}
}
#Override
protected void onResume() {
super.onResume();
Intent objIntent = new Intent(this, MusicService.class);
if (!isBound) {
// Disconnect from an application service. You will no longer
// receive calls as the service is restarted, and the service is
// now allowed to stop at any time.
bindService(objIntent, myConnection, Context.BIND_AUTO_CREATE);
isBound=true;
startService(objIntent);
}
}
public void onRestart(){
super.onRestart();
Intent objIntent = new Intent(this, MusicService.class);
if (!isBound) {
// Disconnect from an application service. You will no longer
// receive calls as the service is restarted, and the service is
// now allowed to stop at any time.
bindService(objIntent, myConnection, Context.BIND_AUTO_CREATE);
isBound=true;
myService.play();
}
}
}
#Override
protected void onResume() {
super.onResume();
Intent objIntent = new Intent(this, MusicService.class);
if (!isBound) {
// Disconnect from an application service. You will no longer
// receive calls as the service is restarted, and the service is
// now allowed to stop at any time.
bindService(objIntent, myConnection, Context.BIND_AUTO_CREATE);
isBound=true;
startService(objIntent);
}
}
public void onRestart(){
super.onRestart();
Intent objIntent = new Intent(this, MusicService.class);
if (!isBound) {
// Disconnect from an application service. You will no longer
// receive calls as the service is restarted, and the service is
// now allowed to stop at any time.
bindService(objIntent, myConnection, Context.BIND_AUTO_CREATE);
isBound=true;
myService.play();
}
}
}
MusicService.java
public class MusicService extends Service{
private static final String LOGCAT = null;
MediaPlayer AudioPlayer;
public void onCreate(){
super.onCreate();
Log.d(LOGCAT, "Service Started!");
AudioPlayer = MediaPlayer.create(this,R.raw.starwars_song);
}
public int onStartCommand(Intent intent, int flags, int startId){
AudioPlayer.start();
Log.d(LOGCAT, "Media Player started!");
if(AudioPlayer.isLooping() != true){
Log.d(LOGCAT, "Problem in Playing Audio");
}
return START_STICKY;
}
public void onStop(){
AudioPlayer.stop();
AudioPlayer.release();
}
public void onPause(){
AudioPlayer.stop();
AudioPlayer.release();
}
public void onDestroy(){
AudioPlayer.stop();
AudioPlayer.release();
}
public class MyLocalBinder extends Binder {
MusicService getService() {
return MusicService.this;
}
}
private final IBinder myBinder = new MyLocalBinder();
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return myBinder;
}
public void plauseAudio() {
if(AudioPlayer.isPlaying())
AudioPlayer.pause();
}
public void play() {
AudioPlayer.start();
}
}
There are multiple issue on the way you implemented.
You have to start the service on activity create (if the service is already running Service.onStartCommand will be called. create MediaPlayer instance only if not null).
Bind to the service after the service started in OnCreate to establish the ServiceConnection
keep hold of the service instance till the activity is destroyed
You can pause the media in onPause if required and start again when onResume.
Unbind the service on onDestroy activity.
Stop the service if required when exit your application else service will be running. When the application is completely removed from stack, service will also be stopped. You can avoid service been killed, by running your service as Foreground using notification.
Just delete onDestroy method in your MusicService and music continues but your service become destroy.
I have a glass app using LiveCards. As such, I don't explicitly have running activities, but just a background service that interacts with the LiveCard for information. At some point, I'd like to bring up a voice input. The problem is that the code samples tell you to use startActivityForResult, which isn't something I can do from within a service. So - is there a different way to bring this up, or can I not do this in my current configuration?
I was having this problem too, not with speech input but I needed to run an activity to get the information to display in a "low-frequency rendering" live card without the user bringing up a menu first. I think you could use an activity to get your text input then send it back to the service.
Most of the information on how to bind the service came from http://developer.android.com/guide/components/bound-services.html
MainService
This is the service that is started by "ok glass, ..." The layout just has a single TextView with the id text.
public class MainService extends Service {
private static final String LIVE_CARD_TAG = "my_card";
private final IBinder mBinder = new LocalBinder();
LiveCard mLiveCard;
TimelineManager mTimelineManager;
RemoteViews mViews;
#Override
public void onCreate() {
super.onCreate();
mTimelineManager = TimelineManager.from(this);
}
public class LocalBinder extends Binder {
MainService getService() {
return MainService.this;
}
}
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
public int onStartCommand(Intent intent, int flags, int startId) {
mLiveCard = mTimelineManager.createLiveCard(LIVE_CARD_TAG);
mViews = new RemoteViews(this.getPackageName(),R.layout.activity_main);
mLiveCard.setViews(mViews);
Intent mIntent = new Intent(this, MenuActivity.class);
mIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mLiveCard.setAction(PendingIntent.getActivity(this, 0, mIntent, 0));
mLiveCard.publish(LiveCard.PublishMode.REVEAL);
new android.os.Handler().postDelayed(
new Runnable() {
public void run() {
// run the test activity after the initial text has displayed
Intent testIntent = new Intent(getBaseContext(), TestActivity.class);
testIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getApplication().startActivity(testIntent);
}
}, 3000);
return START_STICKY;
}
public void updateText(String textString) {
mViews.setTextViewText(R.id.text,textString);
mLiveCard.setViews(mViews);
}
#Override
public void onDestroy() {
if (mLiveCard != null && mLiveCard.isPublished()) {
Log.d("debug", "Unpublishing LiveCard");
mLiveCard.unpublish();
mLiveCard = null;
}
super.onDestroy();
}
}
TestActivity
This is run after a delay from the MainService and updates the text on the live card automatically with no user input.
public class TestActivity extends Activity {
MainService mService;
boolean mBound = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
protected void onStart() {
super.onStart();
Intent intent = new Intent(this, MainService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
#Override
protected void onStop() {
super.onStop();
if (mBound) {
unbindService(mConnection);
mBound = false;
}
}
#Override
public void onResume() {
super.onResume();
new android.os.Handler().postDelayed(
new Runnable() {
public void run() {
// this crashes if run right away, so give it a little time
mService.updateText("Updated from TestActivity");
finish();
}
}, 500);
}
private ServiceConnection mConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName className, IBinder service) {
LocalBinder binder = (LocalBinder) service;
mService = binder.getService();
mBound = true;
}
#Override
public void onServiceDisconnected(ComponentName arg0) {
mBound = false;
}
};
}
MenuActivity
This is the activity that is set as the pending intent for the live card. It brings up a menu to exit or update the text when the touchpad is tapped.
public class MenuActivity extends Activity {
MainService mService;
boolean mBound = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
protected void onStart() {
super.onStart();
Intent intent = new Intent(this, MainService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
#Override
protected void onStop() {
super.onStop();
if (mBound) {
unbindService(mConnection);
mBound = false;
}
}
#Override
public void onResume() {
super.onResume();
openOptionsMenu();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.stop:
stopService(new Intent(this, MainService.class));
return true;
case R.id.update:
mService.updateText("Updated from MenuActivity");
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
public void onOptionsMenuClosed(Menu menu) {
finish();
}
private ServiceConnection mConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName className, IBinder service) {
LocalBinder binder = (LocalBinder) service;
mService = binder.getService();
mBound = true;
}
#Override
public void onServiceDisconnected(ComponentName arg0) {
mBound = false;
}
};
}