I have a thread inside a service and I would like to be able to stop the thread when I press the buttonStop on my main activity class.
In my main activity class I have:
public class MainActivity extends Activity implements OnClickListener {
...
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
buttonStart = (Button) findViewById(R.id.buttonStart);
buttonStop = (Button) findViewById(R.id.buttonStop);
buttonStart.setOnClickListener(this);
buttonStop.setOnClickListener(this);
}
public void onClick(View src) {
switch (src.getId()) {
case R.id.buttonStart:
startService(new Intent(this, MyService.class));
break;
case R.id.buttonStop:
stopService(new Intent(this, MyService.class));
break;
}
}
}
And in my service class I have:
public class MyService extends Service {
...
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
int icon = R.drawable.myicon;
CharSequence tickerText = "Hello";
long when = System.currentTimeMillis();
Notification notification = new Notification(icon, tickerText, when);
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.setLatestEventInfo(this, "notification title", "notification message", pendingIntent);
startForeground(ONGOING_NOTIFICATION, notification);
...
}
#Override
public void onStart(Intent intent, int startid) {
Thread mythread= new Thread() {
#Override
public void run() {
while(true) {
MY CODE TO RUN;
}
}
}
};
mythread.start();
}
}
what is the best way to stop the mythread?
Also is the way that I have stopped the service by stopService(new Intent(this, MyService.class)); correct?
You can't stop a thread that has a running unstoppable loop like this
while(true)
{
}
To stop that thread, declare a boolean variable and use it in while-loop condition.
public class MyService extends Service {
...
private Thread mythread;
private boolean running;
#Override
public void onDestroy()
{
running = false;
super.onDestroy();
}
#Override
public void onStart(Intent intent, int startid) {
running = true;
mythread = new Thread() {
#Override
public void run() {
while(running) {
MY CODE TO RUN;
}
}
};
};
mythread.start();
}
You call onDestroy() method for stop service.
Related
I wanna implement a Countdown timer with updating TextView and a service so the counting can keep going if the app is in background, foreground or even fully closed.
I examined these codes in a simple project and they worked very well
Service
public class MyService extends Service {
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
final Integer[] timeRemaining = {intent.getIntExtra("TimeValue", 0)};
final Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
Intent intent1local = new Intent();
intent1local.setAction("Counter");
timeRemaining[0]--;
if (timeRemaining[0] <= 0) {
timer.cancel();
}
intent1local.putExtra("TimeRemaining", timeRemaining[0]);
sendBroadcast(intent1local);
}
},
0, 1000);
return super.onStartCommand(intent, flags, startId);
}
}
Main Activity
public class MainActivity extends AppCompatActivity {
private TextView textView;
private EditText editText;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ActivityCompat.requestPermissions(this,
new String[]{FOREGROUND_SERVICE},
PackageManager.PERMISSION_GRANTED);
textView = findViewById(R.id.textView);
editText = findViewById(R.id.editText);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("Counter");
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Integer integerTime = intent.getIntExtra("TimeRemaining",
0);
textView.setText(integerTime.toString());
}
};
registerReceiver(broadcastReceiver, intentFilter);
}
public void startButton(View view) {
Intent intentService = new Intent(this, MyService.class);
Integer integerTimeSet =
Integer.parseInt(editText.getText().toString());
intentService.putExtra("TimeValue", integerTimeSet);
startService(intentService);
}
}
But when i implement these codes in an app with fragments (Service codes are in a seperate service class and i put MainActivity codes in a fragment), if you close the app, everything will gone off and you will get an error.
Please help me
I need your detailed advices.
please explain me how does android call lock screen after closing emergency dialer. I've tried to check every second if emergency call is the top activity if it's not then i just lock device but this didn't do it's job in android 5.0 and higher. So, I need another solution.
My code:
private static final long INTERVAL = TimeUnit.SECONDS.toMillis(1/100);
private Thread t = null;
private Context ctx = null;
private boolean running = false;
public MyService2() {
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
final ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
running = true;
ctx = this;
Log.i("Point","PreRun");
t = new Thread(new Runnable() {
#Override
public void run() {
Log.i("Point","preloop");
do {
Log.i("Point", "Prechech");
if (activityManager.getRunningTasks(1).get(0).topActivity.getPackageName().equals("com.android.phone") || activityManager.getRunningTasks(1).get(0).topActivity.getPackageName().equals("com.android.dialer"))
{
try {
Thread.sleep(INTERVAL);
} catch (InterruptedException e) {
Log.i("Point", "Thread interrupted: 'KioskService'");
}
} else {
running=false;
Log.i("Task is",activityManager.getRunningTasks(1).get(0).topActivity.getPackageName());
stopSelf();
}
}while (running) ;
}
});
t.start();
Log.i("Point","Done");
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy() {
super.onDestroy();
Log.i("Point","Service is stopped");
}
}
And this:
public class MyActivity extends Activity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent("com.android.phone.EmergencyDialer.DIAL");
startActivity(intent);
Intent intent1 = new Intent(MyActivity.this,MyService2.class);
startService(intent1);
}
});
}
}
You can launch your emergency dialer like this:
Intent intent = new Intent("android.intent.action.MAIN");
intent.setComponent(ComponentName.unflattenFromString("com.android.phone/.EmergencyDialer"));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
Moreover please check if you have declared your service properly in manifest.
<service
android:name=".MyService2">
</service>
I have created a Service and started using an Activity on Button click, but the Service gets stops after I closes an Activity. So what should I do to keep running the Service without gets stopped?
MainActivity.java
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public void startService(View v){
Intent i = new Intent(this, NotStickyService.class);
startService(i);
}
public void stopService(View v){
Intent i = new Intent(this, NotStickyService.class);
stopService(i);
}
Service.java
public class NotStickyService extends Service{
MediaPlayer mp;
#Override
public void onCreate() {
showToast("onCreate");
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
showToast("onStart");
mp = new MediaPlayer();
AssetFileDescriptor descriptor;
descriptor = getAssets().openFd("msg.mp3");
mp.setDataSource(descriptor.getFileDescriptor(),
descriptor.getStartOffset(),descriptor.getLength());
descriptor.close();
mp.prepare();
mp.start();
return Service.START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
showToast("onDestroy");
}
private void showToast(String message){
Toast toast = Toast.makeText(this, message, Toast.LENGTH_SHORT);
toast.show();
}
}
I have a brodcastReciver , an activity and a service , in the activity i send an intent to service to set an alarm , and alarm is sending broadcast to brodcastReciver to show toast.
but i cant cancel alarm from activiy. here is my code :
public class MainActivity extends Activity {
Button start, stop;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
start = (Button) findViewById(R.id.button1);
stop = (Button) findViewById(R.id.button2);
start.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
start();
}
});
stop.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
stop();
}
});
}
void stop() {
Intent i = new Intent(this, Reci.class);
i.putExtra("c", "cancel");
startService(i);
Toast.makeText(this, "stop clicked!", Toast.LENGTH_SHORT).show();
}
void start() {
Intent i = new Intent(this, Serv.class);
i.putExtra("d", "do");
startService(i);
Toast.makeText(this, "start clicked!", Toast.LENGTH_SHORT).show();
}
}
service :
public class Serv extends Service {
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent.getStringExtra("d").equalsIgnoreCase("do")) {
Toast.makeText(this, "onStart", Toast.LENGTH_SHORT).show();
Intent i = new Intent(this, Reci.class)
.setAction("ir.test.code.Reci.noti");
PendingIntent pi = PendingIntent.getBroadcast(this, 1234, i, 0);
G.AM.setRepeating(AlarmManager.RTC_WAKEUP,
System.currentTimeMillis() + 5000, 5000, pi);
} else if (intent.getStringExtra("c").equalsIgnoreCase("cancel")) {
Toast.makeText(this, "onCancel", Toast.LENGTH_SHORT).show();
Intent i = new Intent(this, Reci.class)
.setAction("ir.test.code.Reci.noti");
PendingIntent pi = PendingIntent.getBroadcast(this, 1234, i, 0);
G.AM.cancel(pi);
}
return super.onStartCommand(intent, flags, startId);
}
}
broadcastReciver
public class Reci extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equalsIgnoreCase("ir.test.code.Reci.noti")) {
Toast.makeText(context, "ir.test.code.Reci.noti",
Toast.LENGTH_SHORT).show();
}
}
}
and Application class :
public class G extends Application{
public static AlarmManager AM;
#Override
public void onCreate() {
super.onCreate();
AM = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
}
}
what should i do?
you are not starting service because of diffent class name you provided ...change void stop() method
Intent i = new Intent(this, Reci.class);
to
Intent i = new Intent(this, Serv.class);
in stop() method of mainactivity
I want to display an alert when a sms is received, so my idea is to start a new activity that launch the alertdialog.
My service starts with no problem, and starts receiver as well..
I can receive sms and display toast alerts fine.. but i'd like to show a custom alertdialog instead.
This is the activity that starts my service (ServiceExampleActivity ):
public class ServiceExampleActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button btnStartService = (Button) findViewById(R.id.btnStart);
Button btnStopService = (Button) findViewById(R.id.btnStop);
btnStartService.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
StartMyService();
}
});
btnStopService.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
StopMyService();
}
});
}
private void StartMyService() {
Intent myServiceIntent = new Intent(this, ServiceTest.class);
startService(myServiceIntent);
}
private void StopMyService() {
Intent myServiceIntent = new Intent(this, ServiceTest.class);
stopService(myServiceIntent);
}
}
This is my Service (ServiceTest):
public class ServiceTest extends Service {
private static final String ACTION = "android.provider.Telephony.SMS_RECEIVED";
private BroadcastReceiver myBroadcastReceiver = null;
#Override
public void onCreate() {
super.onCreate();
final IntentFilter theFilter = new IntentFilter();
theFilter.addAction(ACTION);
this.myBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
StartDialogActivity(context, intent);
}
};
this.registerReceiver(myBroadcastReceiver, theFilter);
}
#Override
public IBinder onBind(Intent arg) {
return null;
}
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Log.d("ServiceTest", "Started");
Toast.makeText(this, "Service started...", 3000).show();
}
#Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(myBroadcastReceiver);
Toast.makeText(this, "Service destroyed...", 3000).show();
}
private void StartDialogActivity(Context context, Intent intent) {
Intent dlgIntent = new Intent(context, DialogActivity.class);
dlgIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(dlgIntent);
}
}
And this is the activity i want to launch to display the alertdialog normally..
public class DialogActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dialog);
}
}
When it tries to start the activity, the app crashes..
Can you tell me were is the error..??
Like this, you want start activity from service
Intent dlgIntent = new Intent(context, DialogActivity.class);
dlgIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getApplication().startActivity(dlgIntent );