I'm trying to stop my service with stopService(), but it will still running. It only stops when I unregister the brodcast receiver, but when I register that again, there will be two actions activated at the same time.
The thread is still running somehow, I really tried everything and reading every single post on the forum but I dind't find a solution.
Service Class
public class MyService extends Service {
final static String MY_ACTION = "MY_ACTION";
private static Context context;
private Timer timer;
public String Data;
String ok = "Database\n";
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
MyThread myThread = new MyThread();
myThread.start();
return super.onStartCommand(intent, flags, startId);
}
public class MyThread extends Thread{
#Override
public void run() {
// TODO Auto-generated method stub
try {
int delay = 1000; // delay for 1 sec.
int period = 5 * 1000; // repeat every 120 sec.
timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
Calendar c = Calendar.getInstance();
Data = String.valueOf((c.get(Calendar.MILLISECOND)));
Intent intent = new Intent();
intent.setAction(MY_ACTION);
intent.putExtra("DATAPASSED", ok);
sendBroadcast(intent);
}
}, delay, period);
} catch (Exception ex) {
ex.printStackTrace();
}
stopSelf();
}
}
}
MainActivity
final IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(MyService.MY_ACTION);
registerReceiver(broadcastReceiver, intentFilter);
final Intent intent = new Intent(MainActivity.this, MyService.class);
//Start our own service
btnStart.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//registerReceiver(broadcastReceiver, intentFilter);
startService(intent);
}
});
btnStop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//unregisterReceiver(broadcastReceiver);
stopService(intent);
}
});
}
#Override
protected void onStop() {
// TODO Auto-generated method stub
unregisterReceiver(broadcastReceiver);
super.onStop();
}
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
int datapassed = intent.getIntExtra("DATAPASSED", 0);
String s = intent.getAction().toString();
String s1 = intent.getStringExtra("DATAPASSED");
textview.append(s1);
}
};
What I'm doing wrong is calling stopSelf() inside my Thread which is causing the service calling the onDestroy() method. I just removed that and added myTimer and myTask as local variables, then I could add myTimer.cancel() onDestroy and it worked.
Related
I am trying to run intent service in background even if the app is closed and have written this code. But the service doesn't runs in the background.Here is my code.
MainActivity.java
package com.example.h.intentservice;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void startService(View view){
Intent intent = new Intent(this,MyIntentService.class);
startService(intent);
}
public void stopService(View view){
Intent intent=new Intent(this,MyIntentService.class);
stopService(intent);
}
}
MyIntentService.java
public class MyIntentService extends IntentService {
public MyIntentService() {
super("My_Worker_Thread");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this,"Service started",Toast.LENGTH_LONG).show();
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this,"Stopped",Toast.LENGTH_LONG).show();
}
#Override
protected void onHandleIntent(Intent intent) {
synchronized (this){
int count=0;
while(count<=10)
{
try{
wait(1500);
count++;
}
catch (InterruptedException e){
e.printStackTrace();
}
}
}
}
}
First of all an intent service cannot run in the background after closing the application. An intentService is run only once and it automatically closes the thread once the task assigned to it is done. You will have to use a service for background requests.
Secondly you have not called the startService() method from the onCreate and therefore the serviceIntent has not been initiated.
In both the startService() method and the stopService() method you are passing a view which i can see is unused inside the method body. So therefore i can advice you to adjust your code this way
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startService();
//here you have started the service intent
//if you want to stop the same just call stopService()
}
public void startService(){
Intent intent = new Intent(this,MyIntentService.class);
startService(intent);
}
public void stopService(){
Intent intent=new Intent(this,MyIntentService.class);
stopService(intent);
}
Am also posting sample code for a service that can run in the background.
Below is sample code for a service
public class UploadService extends Service {
public int counter = 0;
public UploadService(Context applicationContext) {
super();
Log.i("SERVICE", "hService started");
}
public UploadService() {
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
//instantiate your variables here
//i call my startUpload method here to doing the task assigned to it
startUpload();
return START_STICKY;
}
public void startUpload() {
//call the method with your logic here
//mine is a sample to print a log after every x seconds
initializeTimerTask();
}
/**
* it sets the timer to print the counter every x seconds
*/
public void initializeTimerTask() {
// timerTask = new TimerTask() {
//we can print it on the logs as below
Log.i("in timer", "in timer ++++ " + (counter++));
//or use the print statement as below
System.out.println("Timer print " + counter++);
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onDestroy() {
super.onDestroy();
stopSelf();
}
}
I am making a game app but the music still keeps playing even when I closed the game. how to stop? and how to change background music once I go to another activity after I clicked a button
public class BackgroundSoundService extends Service {
private static final String TAG = null;
MediaPlayer player;
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
player = MediaPlayer.create(this, R.raw.rysk);
player.setLooping(true); // Set looping
player.setVolume(100,100);
}
public int onStartCommand(Intent intent, int flags, int startId) {
player.start();
return 1;
}
public void onStart(Intent intent, int startId) {
// TO DO
}
public IBinder onUnBind(Intent arg0) {
// TO DO Auto-generated method
return null;
}
public void onStop() {
}
public void onPause() {
}
#Override
public void onDestroy() {
player.stop();
player.release();
}
#Override
public void onLowMemory() {
}
}
this is my main activity (PlayActivity.class)
Intent svc=new Intent(this, BackgroundSoundService.class);
startService(svc);
I want to change the music when I clicked a button and went to CatActivity
You should have to work with registerReceiver,unregisterReceiver.
May this helps you.
MainActivity.java
public class MainActivity extends AppCompatActivity {
private Button btn_startservice;
private Button btn_stopservice;
private TextView tv_servicecounter;
ServiceDemo myService;
boolean isBound;
BroadcastReceiver broadcastRec = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
int datapassed = intent.getIntExtra("value", 0);
tv_servicecounter.setText(String.valueOf(datapassed));
}
};
#RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_servicecounter = (TextView) findViewById(R.id.tv_activity_main_count);
btn_startservice = (Button) findViewById(R.id.btn_activity_main_startservices);
btn_stopservice = (Button) findViewById(R.id.btn_activity_main_stopservices);
btn_startservice.setOnClickListener(
new View.OnClickListener() {
#RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
#Override
public void onClick(View v) {
Intent objIntent = new Intent(MainActivity.this, ServiceDemo.class);
if (!isBound) {
bindService(objIntent, myConnection, Context.BIND_AUTO_CREATE);
isBound = true;
startService(objIntent);
} else {
isBound = false;
unbindService(myConnection);
}
}
}
);
btn_stopservice.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent objIntent = new Intent(MainActivity.this, ServiceDemo.class);
if (isBound) {
isBound = false;
unbindService(myConnection);
stopService(objIntent);
} else {
stopService(objIntent);
}
}
}
);
}
#Override
protected void onResume() {
registerReceiver(broadcastRec, new IntentFilter("USER_ACTION"));
super.onResume();
}
#Override
protected void onStop() {
this.unregisterReceiver(broadcastRec);
super.onStop();
}
private ServiceConnection myConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className,
IBinder service) {
myService = ((ServiceDemo.MyLocalBinder) service).getService();
isBound = true;
}
public void onServiceDisconnected(ComponentName arg0) {
isBound = false;
}
};
#Override
protected void onDestroy() {
super.onDestroy();
if (isBound) {
unbindService(myConnection);
isBound = false;
}
}
}
And ServiceDemo.java
public class ServiceDemo extends Service {
int i;
private MyThread mythread;
public boolean isRunning = false;
Notification notification;
#Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "onCreate");
mythread = new MyThread();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "Service Started", Toast.LENGTH_SHORT).show();
if (!isRunning) {
mythread.start();
isRunning = true;
}
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
mythread.interrupt();
Toast.makeText(this, "Service Destroyed", Toast.LENGTH_SHORT).show();
}
public void sendBrodcastMsg(int value) {
Intent intent = new Intent();
intent.setAction("USER_ACTION");
intent.putExtra("value", value);
sendBroadcast(intent);
}
#RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
class MyThread extends Thread {
static final long DELAY = 100;
#Override
public void run() {
while (isRunning) {
try {
i++;
Thread.sleep(DELAY);
sendBrodcastMsg(i);
shownotification();
} catch (InterruptedException e) {
isRunning = false;
e.printStackTrace();
}
}
stopSelf();
}
}
#RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
public void shownotification() {
Intent in = new Intent(this, MainActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(this, (int) System.currentTimeMillis(), in, 0);
notification = new NotificationCompat.Builder(this)
.setContentTitle(String.valueOf(i))
.setContentText(String.valueOf(i))
.setSmallIcon(R.drawable.musicplayer)
.setContentIntent(pIntent)
.setAutoCancel(true).build();
;
startForeground(101, notification);
}
public class MyLocalBinder extends Binder {
ServiceDemo getService() {
return ServiceDemo.this;
}
}
private final IBinder myBinder = new MyLocalBinder();
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return myBinder;
}
}
put this two lines in manifest.
<service android:name=".ServiceDemo"
android:enabled="true"/>
You need to stop the player in onPause(). Following code can be used:
#Override
protected void onPause() {
super.onPause();
if (this.isFinishing()){
player.stop();
}
}
Check Android Stop Background Music for more details
for that you should stop the service in the onCreate method of the Activity. Below is the code for it :
stopService(new Intent(MyService.MY_SERVICE));
Best of Luck!
In Your MainActivity , You Should Call stopService() Inside MainActivity
#Override
public void OnPause() {
stopService(svc);
}
It has been asked a few times before but the solution provided couldn't solve my problem. I am working on the app which has several classes: mainactivity, SMS, and MService. service has a timer. I am trying to call SMS to send a text message every time timer is over. Can please someone help me ....
Thanks for consideration...
public class MService extends Service {
private Handler HandleIt = new Handler();
private final int INTERVAL = 60 * 1000;
private Timer timer = new Timer();
boolean timeout = false;
public interface SmsService
{
void SmsServiceSenter();
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
class TimeDisplayTimerTask extends TimerTask {
#Override
public void run() {
HandleIt.post(new Runnable(){
public void run(){
Toast.makeText(getApplicationContext(), TextonScreen(), Toast.LENGTH_SHORT).show();
// Intent smsintent = new Intent(getBaseContext(), SMS.class);
// startService(smsintent);
}
});
}
}
private String TextonScreen()
{
timeout = true;
return "it is running";
}
boolean isTimeout()
{
return timeout;
}
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
Toast.makeText(this, "Service is created", Toast.LENGTH_SHORT).show();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
// Display the Toast Message
Toast.makeText(this, "Start it", Toast.LENGTH_SHORT).show();
// Execute an action after period time
//comes from the TimeDisplayTimerTask class
timer.scheduleAtFixedRate(new TimeDisplayTimerTask(), 0, INTERVAL);
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy() {
// Display the Toast Message
Toast.makeText(this, "Stop it", Toast.LENGTH_SHORT).show();
super.onDestroy();
}
}
public class SMS extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
message();;
}
boolean issent = false;
String text = "I am here";
String num = "2085578209";
SmsManager smsManager = SmsManager.getDefault();
public void message()
{
// if(Timeout.isTimeout()) {
smsManager.sendTextMessage(num, null, text, null, null);
issent = true;
// }
}
boolean isSent()
{
return issent;
}
}
It is really simple.
After you create your Intent variable, before starting activity add a flag to it like below
Intent launch = new Intent(this, MyActivity.class);
launch.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(launch);
With this above code you can call activity from service
I have an android application, which contains a main activity which displays information to the user.
When MainActivity starts, A service is created/started which checks a web service on every 10 seconds - if the Web service result will show in a notification.
I start the service from Main activity using Intent,
getActivity().startService(new Intent(getActivity(), NotificationService.class));
I Also try this code, (But same result).
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
getActivity().startService(new Intent(getActivity(), NotificationService.class));
}
});
If service started I get warning In my Logcat,
Skipped 91 frames! The application may be doing too much work on its main thread.
My notification service code,
public class NotificationService extends Service {
// constant
public static final long NOTIFY_INTERVAL = 10 * 1000; // 10 seconds
long current_times;
String c_time;
// run on another Thread to avoid crash
private Handler mHandler = new Handler();
// timer handling
static HttpClient client = new DefaultHttpClient();
private Timer mTimer = null;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#TargetApi(Build.VERSION_CODES.GINGERBREAD) #SuppressLint("NewApi") #Override
public void onCreate() {
// cancel if already existed
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
SharedPreferences.Editor editor = getSharedPreferences("notification_oldtime", MODE_PRIVATE).edit();
editor.putInt("old_trail_time", 0);
editor.putInt("old_sample_time", 0);
editor.putInt("old_neworder_time", 0);
editor.commit();
if(mTimer != null) {
mTimer.cancel();
} else {
// recreate new
mTimer = new Timer();
}
// schedule task
mTimer.scheduleAtFixedRate(new TimeDisplayTimerTask(), 0, NOTIFY_INTERVAL);
}
public long current_time_get(){
return current_times;
}
class TimeDisplayTimerTask extends TimerTask {
#TargetApi(Build.VERSION_CODES.JELLY_BEAN) #Override
public void run() {
// run on another thread
mHandler.post(new Runnable() {
#Override
public void run() {
// My webservice code for notification
}
}
}
Try using IntentService instead of Service. IntentService does its work on a separate thread.
serviceConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName className,
IBinder binder) {
try {
((NoteBinder) binder).service.startService(new Intent(
MyActivity.this, NotificationService.class));
MyLog.d(TAG, "onServiceConnected is called; "
+ className.getClassName());
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
#Override
public void onServiceDisconnected(ComponentName className) {
MyLog.d(TAG, "onServiceDisconnected is called; "
+ className.getClassName());
}
};
bindService(
new Intent(BaseActivity.this, NotificationService.class),
serviceConnection, Context.BIND_AUTO_CREATE);
instead of using start service use bind service.
I am using a Service to play background Music. The problem is that the music continues playing when i have finished the activity.
Here is code From Main Activity which starts the service
Intent svc=new Intent(HomeActivity.this, BackgroundSoundService.class);
startService(svc);
BackgroundSoundService.java
public class BackgroundSoundService extends Service {
private static final String TAG = null;
public static MediaPlayer player;
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
Log.d("atMedia", "Backround Music playing");
player = MediaPlayer.create(this, R.raw.background);
player.setLooping(true); // Set looping
player.setVolume(100,100);
}
public int onStartCommand(Intent intent, int flags, int startId) {
player.start();
return 1;
}
public void onStart(Intent intent, int startId) {
// TO DO
}
public IBinder onUnBind(Intent arg0) {
// TO DO Auto-generated method
return null;
}
public void onStop() {
}
public void onPause() {
}
#Override
public void onDestroy() {
super.onDestroy();
player.stop();
player.release();
}
#Override
public void onLowMemory() {
}
}
Try to stop service from your MainActivity:
Intent svc=new Intent(HomeActivity.this, BackgroundSoundService.class);
stopService(svc);
You have to call selfStop() method inside your service.
or use stopService() API