How do i start a service when an activity is opened, I am using intent but the service isn't starting at all. Music is meant to be played when a certain page is opened, but no service is running at all.
This is the code i am using to start the service on the MainPage class.
public class BackgroundMusic extends Service implements Application.ActivityLifecycleCallbacks, Runnable {
MediaPlayer player;
private static final Handler uiHandler = new Handler(Looper.getMainLooper());
#Override
public void onCreate() {
super.onCreate();
player = MediaPlayer.create(this, R.raw.backgroundmusic);
player.setLooping(true);
player.setVolume(100, 100);
player.start();
Intent BackgrndMusic = new Intent(this, MainPage.class);
startService(BackgrndMusic);
getApplication().registerActivityLifecycleCallbacks(this);
}
#Override
public void onDestroy() {
super.onDestroy();
// stop listening for activities
getApplication().unregisterActivityLifecycleCallbacks(this);
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onActivityStarted(Activity activity) {
// do not destroy this service
uiHandler.removeCallbacks(this);
}
#Override
public void onActivityStopped(Activity activity) {
// if an activity don't show up in 1 second, destroy this service
uiHandler.postDelayed(this, 1000);
}
#Override
public void run() {
// no more activity, destroy this service
stopSelf();
}
#Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
Intent BackgrndMusic = new Intent(BackgroundMusic.this, MainPage.class);
startService(BackgrndMusic);
}
#Override
public void onActivityResumed(Activity activity) {
Intent BackgrndMusic = new Intent(BackgroundMusic.this, MainPage.class);
startService(BackgrndMusic);
}
#Override
public void onActivityPaused(Activity activity) {
Intent BackgrndMusic = new Intent(BackgroundMusic.this, MainPage.class);
stopService(BackgrndMusic);
}
#Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
#Override
public void onActivityDestroyed(Activity activity) {
Intent BackgrndMusic = new Intent(BackgroundMusic.this, MainPage.class);
stopService(BackgrndMusic);
}
}
Use
#Override
protected void onResume()
{
super.onResume();
startService(foo);
}
#Override
protected void onDestroy()
{
super.onDestroy();
StopService(foo);
}
Related
in my app while i am making a communication between service and broadcastreceiver my apps extremely slowing down. if i use only service my apps running ok, but problem occurs when i try to show service's result through broadcast. below my code.
manifest:
<service
android:name=".ServiceClass_GetGps"
android:exported="false" />
broadcastreceiver :
public class FragmentMap extends Fragment implements OnMapReadyCallback{
double lat,lng;
GoogleMap googleMap=null;
public FragmentMap() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
setRetainInstance(true);
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_map, null, false);
SupportMapFragment mapFragment=(SupportMapFragment)this.getChildFragmentManager().findFragmentById(R.id.map_FragmentMapId);
mapFragment.getMapAsync(this);
Intent intent=new Intent(getActivity(),ServiceClass_GetGps.class);
getActivity().startService(intent);
return view;
}
#Override
public void onResume() {
super.onResume();
IntentFilter intentFilter=new IntentFilter("imran");
LocalBroadcastManager.getInstance(getActivity()).registerReceiver(broadcastReceiver,intentFilter);
}
#Override
public void onPause() {
super.onPause();
LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(broadcastReceiver);
}
//broadcast receiver
private BroadcastReceiver broadcastReceiver=new BroadcastReceiver() {
#Override
public void onReceive(final Context context, final Intent intent) {
//String result=intent.getStringExtra("result");
// Toast.makeText(getActivity(), "Lat " +intent.getStringExtra("LAT") +" Lng "+intent.getStringExtra("LNG"), Toast.LENGTH_SHORT).show();
Handler handler=new Handler();
handler.post(new Runnable() {
#Override
public void run() {
context.startService(new Intent(context.getApplicationContext(),ServiceClass_GetGps.class));
if(intent.getStringExtra("LAT")!=null && intent.getStringExtra("LNG")!=null){
lat=Double.valueOf(intent.getStringExtra("LAT"));
lng=Double.valueOf(intent.getStringExtra("LNG"));
LatLng latLng=new LatLng(lat,lng);
if(googleMap!=null){
googleMap.addMarker(new MarkerOptions().position(latLng));
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng,16));
}else {
Toast.makeText(getActivity(),"Map is null",Toast.LENGTH_LONG).show();
}
}
}
});
}
};
#Override
public void onMapReady(GoogleMap googleMap) {
this.googleMap=googleMap;
}
service class:
public class ServiceClass_GetGps extends Service implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,LocationListener{
private HandlerThread handlerThread;
ServiceHandler serviceHandler;
LocalBroadcastManager localBroadcastManager;
private final static class ServiceHandler extends Handler {
public ServiceHandler(Looper looper){
super(looper);
}
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
}
}
#Override
public void onCreate() {
super.onCreate();
handlerThread=new HandlerThread("com.example.imranrana.datingapp");
handlerThread.start();
serviceHandler=new ServiceHandler(handlerThread.getLooper());
localBroadcastManager=LocalBroadcastManager.getInstance(this);
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(final Intent intent, int flags, int startId) {
final Handler handler=new Handler();
new Thread(new Runnable() {
#Override
public void run() {
// Intent intent=new Intent("com.example.imranrana.datingapp");
// intent.putExtra("result","Imran");
// localBroadcastManager.sendBroadcast(intent);
handler.post(new Runnable() {
#Override
public void run() {
Intent intent1=new Intent("imran");
intent1.putExtra("LAT","23.8758448");
intent1.putExtra("LNG","90.3981515");
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent1);
Toast.makeText(getApplicationContext(),"Service test",Toast.LENGTH_LONG).show();
}
});
handler.postDelayed(this,5000);
}
}).start();
return START_STICKY;
}
#Override
public void onConnected(#Nullable Bundle bundle) {
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
}
#Override
public void onLocationChanged(Location location) {
}
#Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(getApplicationContext(),"apps stopped",Toast.LENGTH_LONG).show();
sendBroadcast(new Intent());
}
can anyone please solve my problem .
i just solved my problem by myself just removing restart command of service from broadcastreceiver . thanks
I have trouble to play music across all activity, I had implement service and handle onPause to stop the music when going to background (not visible to user).
The problem is when i navigate to another activity, the onPause method is called that make my music stop. How to fix this issue? I need to play my music across all my activity in foreground only and dont wan to play it when the application in the background. Appeciate anyone know how to solve this.
This is my base activity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
startIntent = new Intent(getApplicationContext(), MusicService.class);
if(binder==null){
bindService(startIntent,this, Context.BIND_AUTO_CREATE);
}
}
#Override
protected void onDestroy() {
super.onDestroy();
if(binder.getMyService()!=null){
stopService(startIntent);
unbindService(this);
}
}
#Override
protected void onStart() {
super.onStart();
}
#Override
protected void onPause() {
super.onPause();
if(binder!=null) {
binder.getMyService().pauseMusic();
}
}
#Override
protected void onResume() {
super.onResume();
if(binder!=null){
binder.getMyService().resumeMusic();
}
}
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
binder = (MusicService.Binder) service;
}
#Override
public void onServiceDisconnected(ComponentName name) {
}
this is my mainactivity extends base activity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startIntent = new Intent(MainActivity.this, MusicService.class);
startService(startIntent);
}
#Override
protected void onDestroy() {
super.onDestroy();
}
public void how(View view) {
Intent intent = new Intent(this, AboutActivity.class);
this.startActivity(intent);
}
You could implement code that will track current activity in your app. (Good example: How to get current activity)
And stop music only when "current activity" is null.
PS: depending on your implementation of tracking current activity you might want to check current activity not onPause() right away but with some delay .
Don't stop the audio play in onPause() as Harin Kaklotar suggested. You can use his method of onDestroy() or you can have it in an asynchronous task and turn off the sound by using surfaceDestroyed(). You can refer the android documentation of AudioManager if you need anything else of the sort.
https://developer.android.com/reference/android/media/AudioManager.html
Hope I Helped :D
UPDATE
You can create a system to check if your app is in the foreground or background. This involves counting how many activities are paused. Add this to all your activities:
#Override
protected void onPause() {
super.onPause();
MainActivity.Pause++;
}
#Override
protected void onResume() {
super.onResume();
MainActivity.Pause--;
}
And in your MainActivty,
if (Pause == NUMBER_OF_ACTIVITIES) {
//PAUSE MUSIC HERE
}
You have to use ActivityLifecycleCallbacks to tell if you app is in the foreground or background.
For example:
public class DummyActivityLifecycleCallbacks implements ActivityLifecycleCallbacks {
#Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) { }
#Override public void onActivityStarted(Activity activity) { }
#Override public void onActivityResumed(Activity activity) { }
#Override public void onActivityPaused(Activity activity) { }
#Override public void onActivityStopped(Activity activity) { }
#Override public void onActivityDestroyed(Activity activity) { }
#Override public void onActivitySaveInstanceState(Activity activity, Bundle savedInstanceState) { }
}
public class OnApplicationForegroundBackgroundEnterCallbacks extends DummyActivityLifecycleCallbacks {
private Listener listener;
private int activityStartStopCounter = 0;
public interface Listener {
public void onEnterForeground();
public void onEnterBackground();
}
public OnApplicationForegroundBackgroundEnterCallbacks(Listener listener) {
this.listener = listener;
}
#Override public void onActivityStarted(Activity activity) {
if(++activityStartStopCounter == 1) listener.onEnterForeground();
}
#Override public void onActivityStopped(Activity activity) {
if(--activityStartStopCounter == 0) listener.onEnterBackground();
}
}
Then in Application.onCreate call:
registerActivityLifecycleCallbacks(new OnApplicationForegroundBackgroundEnterCallbacks(this));
i would developing a feature in my app that when click on button on my activity launch a service that start,pause and resume a Chronometer.
But I have a problem how start and stop in my background service.
I created my Activity
public class StartWorkActivity extends ActivityGeneralToolbar {
protected final void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState, R.layout.activity_start_work);
Chronometer chronometer = (Chronometer) findViewById(R.id.chronometer);
}
#Override
protected void onStop() {
super.onStop();
}
public void startWork(View v){
Intent msgIntent = new Intent(StartWorkActivity.this, WorkTimerService.class);
msgIntent.setAction("START_TIMER");
getBaseContext().startService(msgIntent);
}
public void pauseWork(View v){
Intent msgIntent = new Intent(StartWorkActivity.this, WorkTimerService.class);
msgIntent.setAction("PAUSE_TIMER");
}
public void resumeWork(View v){
//call service
Intent msgIntent = new Intent(StartWorkActivity.this, WorkTimerService.class);
msgIntent.setAction("RESUME_TIMER");
}
#Override
protected void onPause() {
super.onPause();
}
#Override
protected void onResume() {
super.onResume();
}
}
And my WorkTimerService
public class WorkTimerService extends IntentService {
long timeWhenStopped = 0;
Chronometer chronometer;
public WorkTimerService() {
super("SystemService");
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
protected void onHandleIntent(Intent intent) {
if(intent.getAction() == "START_TIMER"){
startWork();
}
if(intent.getAction() == "PAUSE_TIMER"){
pauseWork();
}if(intent.getAction() == "RESUME_TIMER"){
resumeWork();
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags,startId);
return START_STICKY;
}
public void pauseWork(){
timeWhenStopped = chronometer.getBase() - SystemClock.elapsedRealtime();
chronometer.stop();
}
public void resumeWork(){
chronometer.setBase(SystemClock.elapsedRealtime() + timeWhenStopped);
timeWhenStopped = 0;
chronometer.start();
}
public void startWork(){
chronometer.start();
}
}
But my problem is that Chronometer obviously is null in my service, because I read that is not possible, in the service, interact with the ui.
And so, how i can send, or work with Chronometer in background?
Chronometer is a UI widget (actually a TextView) in Android. So, you can't use it for non-UI purposes. Try to use Timer or CountDownTimer instead.
See this for an example usage of Timer inside Service: https://stackoverflow.com/a/3819721/5250273
This is my service class in that i increment the i value based on time...
public class BackService extends Service {
int i=0;
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
pollForUpdates();
super.onCreate();
}
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
}
private void pollForUpdates() {
Timer timer=new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
Log.v("Service class called", "service class called "+i);
getRunningApps();
i++;
}
},0,1000);
}
private void getRunningApps()
{
}
#Override
public void onDestroy() {
super.onDestroy();
}
}
I want to append the i value to the TextView. i.e the TextView value is dynamically change based on i value...
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
startService(new Intent(this, BackService.class));
TextView tx=(TextView)findViewById(R.id.textView1);
}}
how to append the i value to tx...
Thank you in advance..
You will need to register Broadcast receiver for Sending data back from Service to Activity.see these usefull example for communication between Activity to service :
http://androidexperinz.wordpress.com/2012/02/14/communication-between-service-and-activity-part-1/
http://androidexperinz.wordpress.com/2012/02/21/communication-between-service-and-activity-part-2/
http://blog.philippheckel.com/2012/06/10/android-example-communication-between-activity-and-service-using-messaging/
Use this
public class MainActivity extends Activity {
TextView tx;
RefreshBroadcastReciver mBroadCastReciver;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
startService(new Intent(this, BackService.class));
tx =(TextView)findViewById(R.id.textView1);
}
#Override
protected void onResume() {
super.onResume();
mBroadCastReciver = new RefreshBroadcastReciver();
registerReceiver(mBroadCastReciver, new IntentFilter("sendData"));
}
private class RefreshBroadcastReciver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
tx.setText(intent.getIntExtra("i", 0)+"");
}
}
#Override
protected void onStop() {
super.onStop();
if(mBroadCastReciver!=null)
unregisterReceiver(mBroadCastReciver);
}
}
and your service is here
public class BackService extends Service {
int i=0;
Intent intent1;
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
pollForUpdates();
super.onCreate();
}
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
intent1=new Intent("sendData");
}
private void pollForUpdates() {
Timer timer=new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
Log.v("Service class called", "service class called "+i);
getRunningApps();
i++;
Message msg=new Message();
msg.arg1=i;
handler.sendMessage(msg);
}
},0,1000);
}
private void getRunningApps()
{
}
#Override
public void onDestroy() {
super.onDestroy();
}
protected Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
intent1.putExtra("i", msg.arg1);
sendBroadcast(intent1);
}
};
}
I added a listener to the service called "BindService".
And then I killed the Activity which have added the listener to the "BindService".
"BindService" is still running. I can see it on DDMS of eclipse.
Now I started the Activity again and I want to add a listener to the "BindService" again.
How could I?
"BindService" is just a service which is counting number.
With the following code, after I start the Activity again and tap the button "button_sendwords", it starts to count number from 0 again. That is not my purpose.
public class MainActivity extends Activity {
private ICallbackService service;
private static final int CALLBACK_MESSAGE = 1;
private Handler handler = new Handler(){
#Override
public void dispatchMessage(Message msg){
if(msg.what == CALLBACK_MESSAGE){
TextView resultlbl = (TextView)findViewById(R.id.label_result);
resultlbl.setText((String)msg.obj);
}else{
super.dispatchMessage(msg);
}
}
};
private ICallbackListener listener = new ICallbackListener.Stub() {
#Override
public void receiveMessage(String message) throws RemoteException {
handler.sendMessage(handler.obtainMessage(CALLBACK_MESSAGE, message));
}
};
private ServiceConnection conn = new ServiceConnection(){
#Override
public void onServiceConnected(ComponentName name, IBinder binder) {
service = ICallbackService.Stub.asInterface(binder);
try{
service.addListener(listener);
}catch(RemoteException e){
}
}
#Override
public void onServiceDisconnected(ComponentName name) {
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnSendWords = (Button)findViewById(R.id.button_sendwords);
btnSendWords.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, BindService.class);
bindService(intent, conn, BIND_AUTO_CREATE);
}
});
}
}