I have a service and an activity that communicate.
When I click the button(I have galaxy s3 there is only one button) then my activity of course disapear and my service is keep running but if I click the back (touch) button then my service is destroyed.
How can I change that?I want the service to keep running untill the activity destroys it.
EDIT
Here is the code:
Service:
public class MyService extends Service
{
private static final String TAG = "BroadcastService";
public static final String BROADCAST_ACTION = "com.websmithing.broadcasttest.displayevent";
private final Handler handler = new Handler();
private 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, 1000); // 10 seconds
}
};
private void DisplayLoggingInfo() {
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();
}
}
Activity:
public class MainActivity extends Activity {
private static final String TAG = "BroadcastTest";
private Intent intent;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
intent = new Intent(this, MyService.class);
startService(intent);
registerReceiver(broadcastReceiver, new IntentFilter(MyService.BROADCAST_ACTION));
}
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
updateUI(intent);
}
};
#Override
public void onDestroy() {
super.onPause();
unregisterReceiver(broadcastReceiver);
stopService(intent);
}
private void updateUI(Intent intent)
{
String counter = intent.getStringExtra("counter");
Log.d(TAG, counter);
TextView txtCounter = (TextView) findViewById(R.id.textView1);
txtCounter.setText(counter);
}
}
you can put your app in the background instead off finishing it.
#Override
public void onBackPressed() {
moveTaskToBack(true);
// super.onBackPressed();
}
Ofcourse your service stops, when you press the back button. The back button most calls finish() on the activity, and it is destroyed. When you press the other button (the home button), it just minimizes your app, and it will be only destroyed later, when the OS wants to free up space.
If you want to keep your service running, make it a foreground service, and dont stop it on activity destroy.
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.
To know the difference between IntentService and Service in Android, I created the below posted small test of a Service class. The MainActivity has a Button, when pressed, the
service will be started using startService() as shown below in the code, which will result in a call to onStartCommand(). In onStartCommand(), i run a loop for 10 seconds, and I
expected that, that loop will block the UI "the butoon". Actually that what happened exactly when I first time start the Service, but when I press the button after the 10 seconds
elapsed, it will result in a call to onStartCommand() but the log message inside the onStartCommand() never get displayed plus the UI is never blocked.
can anyone please explain what the body of the onStartCommand() is executed and blocks the UI only when the Service first started and never afterwards?
MainActivity
public class MainActivity extends AppCompatActivity {
private Button mbtnSend = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.mbtnSend = (Button) findViewById(R.id.btn_send);
this.mbtnSend.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(getApplicationContext(), MyService.class);
startService(intent);
}
});
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
registerReceiver(this.mBCR_VALUE_SENT, new IntentFilter(MyIntentService.INTENT_ACTION));
this.mbtnSend = (Button) findViewById(R.id.btn_send);
this.mbtnSend.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(getApplicationContext(), MyIntentService.class);
intent.putExtra("intent_key", ++i);
startService(intent);
}
});
}
}
MyIntentService:
public class MyService extends Service{
private final String TAG = this.getClass().getSimpleName();
private long mStartTime;
#Override
public void onCreate() {
super.onCreate();
Log.w(TAG, SubTag.msg("onCreate"));
this.mStartTime = TimeUtils.getTSSec();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.w(TAG, SubTag.msg("onStartCommand"));
while ( (TimeUtils.getTSSec() - this.mStartTime) <=10) {
Log.w(TAG, SubTag.msg("time: " + (TimeUtils.getTSSec() - this.mStartTime)));
SystemClock.sleep(1000);
}
return Service.START_STICKY;
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
Log.w(TAG, SubTag.msg("onBind"));
return null;
}
#Override
public void onDestroy() {
super.onDestroy();
Log.w(TAG, SubTag.msg("onDestroy"));
}
}
You are setting mStartTime to TimeUtils.getTSSec() in onCreate(), which means that it will get intialized only once.
Afterwards, onStartCommand() is called, but the mStartTime timestamp is not being updated, so the while loop never runs.
I believe that moving the line where you initialize mStartTime to onStartCommand() before the while loop will make your thread hang again.
I am trying to pass a value from a service to an activity. Here is what I do:
In my service I have:
public class MyService extends Service {
...
private long b;
public static final String BROADCAST_ACTION = "test";
private final Handler handler = new Handler();
Intent intentDisp;
...
#Override
public void onCreate() {
...
b = 0;
intentDisp = new Intent(BROADCAST_ACTION);
...
}
#Override
public int onStartCommand( Intent intent, int flags, int startId ) {
handler.removeCallbacks(sendUpdatesToUI);
handler.postDelayed(sendUpdatesToUI, 1000); // 1 second
...
}
private Runnable sendUpdatesToUI = new Runnable() {
public void run() {
b = (long) 2.0;
intentDisp.putExtra("connected", b);
sendBroadcast(intentDisp);
handler.postDelayed(this, 2000); // 5 seconds
}
};
In my main Activity I have:
public class MainActivity extends Activity implements OnClickListener {
...
private Intent intentDisp1;
#Override
public void onCreate(Bundle savedInstanceState) {
...
intentDisp1 = new Intent(this, MyService.class);
}
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
updateUI(intent);
}
};
#Override
public void onResume() {
super.onResume();
startService(intentDisp1);
registerReceiver(broadcastReceiver, new IntentFilter(MyService.BROADCAST_ACTION));
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(broadcastReceiver);
stopService(intentDisp1);
}
private void updateUI(Intent intent) {
long c = intentDisp1.getLongExtra("connected",-1);
...
}
When I debug the program I always get the value of -1 for c while I am passing the value of 2 from MyServive. Any idea what is wrong?
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 );
Hi friends i have a one problem to solve...I want to destroy the service completely, once i call onDestroy() method from Activity. But my problem is that i am unable to destroy it completely.. in background its keep on running, i am sharing the sample code what i tried..
//Activity Class
public class ServiceToAct extends Activity {
private static final String TAG = "BroadcastEvent";
private Intent intent;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
intent = new Intent(this, BroadcastService.class);
startService(intent);
registerReceiver(broadcastReceiver, new IntentFilter(myService.BROADCAST_ACTION));
}
/*#Override
protected void onResume() {
super.onResume();
}*/
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(broadcastReceiver);
}
#Override
protected void onDestroy() {
stopService(intent);
Toast.makeText(this, "Destroy Completely", Toast.LENGTH_LONG).show();
}
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
}
};
}
// service class
public class myService extends Service {
private static final String TAG = "BroadcastEvent";
public static final String BROADCAST_ACTION = "com.service.activity.myService";
private final Handler handler = new Handler();
Intent intent;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
Toast.makeText(this, "created", Toast.LENGTH_LONG).show();
intent = new Intent(BROADCAST_ACTION);
}
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Toast.makeText(this, "start", Toast.LENGTH_LONG).show();
handler.removeCallbacks(sendToUI);
handler.postDelayed(sendToUI, 1000);
}
#Override
public void onDestroy() {
super.onDestroy();
stopSelf();
//stopService(intent);
Toast.makeText(this, "Destroy", Toast.LENGTH_LONG).show();
}
private Runnable sendToUI = new Runnable() {
#Override
public void run() {
myData();
handler.postDelayed(this, 10000);
}
};
private void myData() {
Log.d(TAG, "keep on entering");
Toast.makeText(this, "Keep on despling in UI", Toast.LENGTH_LONG).show();
sendBroadcast(intent);
}
}
Here Actually i want to update my UI from service, Mine everything is working, but if i destroy the service its keep on calling myData() method, and i am getting the Toast msg if i close the application also.
My issue is i don't want that toast msg once the service is desroyed
I used stopService(intent) method, which destroy the service, but background method myData() is keep on calling
for stop service completely use this ..
myActivity.java
#Override
public void onDestroy() {
stopService(intent);
super.onDestroy();
Toast.makeText(this, "Destroy", Toast.LENGTH_LONG).show();
}
service.java
#Override
public void onDestroy()
{
stopSelf();
super.onDestroy();
}
You'd better never call onXxx() derectly.
Use stopService(Intent i) in your activity and stopSelf() in you service to stop instead.
use stopService() method after updating UI
or
Instead of using startService use bindService in the activity. When activity destroys, service also destroys