I'm using following code to stop my service
Intent intent = new Intent(MainActivity.this, UsageRecorderService.class);
stopService(intent);
And this is my service that works indefinitely
public class UsageRecorderService extends IntentService {
public UsageRecorderService() {
super("UsageRecorder");
}
#Override
protected void onHandleIntent(Intent intent) {
while (true) {
UsageRecorder.recordUsages(this, false);
SystemClock.sleep(10000);
}
}
}
Why does not stop my service?
This code would work
public class UsageRecorderService extends IntentService {
private boolean mStop = false;
public UsageRecorderService() {
super("UsageRecorder");
}
public final Object sLock = new Object();
public void onDestroy() {
synchronized (sLock) {
mStop = true;
}
}
#Override
protected void onHandleIntent(Intent intent) {
while (true) {
synchronized (sLock) {
if (mStop) break;
}
UsageRecorder.recordUsages(this, false);
SystemClock.sleep(10000);
}
}
}
You can use stopService
Intent intent = new Intent(MainActivity.this, UsageRecorderService.class);
stopService(intent);
Also I recommend to read Services guide to understand what is going there.
Activity:
sendBroadcast(new Intent(ACTION_STOP));
IntentService
public class UsageRecorderService extends IntentService {
private static final String TAG = "UsageRecorderService";
String ACTION_STOP = "com.xxx.UsageRecorderService.ACTION_STOP";
boolean stop;
public UsageRecorderService() {
super("UsageRecorder");
}
private BroadcastReceiver receiver = new BroadcastReceiver() {
#Override public void onReceive(Context context, Intent intent) {
if (ACTION_STOP.equals(intent.getAction())) {
stop = true;
}
}
};
#Override public void onCreate() {
super.onCreate();
IntentFilter intentFilter = new IntentFilter(ACTION_STOP);
registerReceiver(receiver, intentFilter);
}
#Override
protected void onHandleIntent(Intent intent) {
Log.i(TAG,"onHandleIntent");
while (true && !stop) {
Log.i(TAG,"----running----");
//UsageRecorder.recordUsages(this, false);
SystemClock.sleep(10000);
}
}
#Override public void onDestroy() {
super.onDestroy();
unregisterReceiver(receiver);
}
}
An IntentService is designed to stop itself only when all the requests present in the work queue have been handled.Android stops the service after all start requests have been handled.
Related
On button click I am opening activity(ActionListActivity) and sending intent to IntentService (later this service sends broadCast intent to ActionListActivity). But I am usually receiving only the first intent after launch. Is it real that intent is sent before the receiver is registred?
I want to get data providet by the intentService, and update my UI using it.
Scheme Activity->IntentService->BroadCastReceiver inside ActionListActivity
Activity:
private void selectDrawerItem(MenuItem menuItem)
{
switch (menuItem.getItemId()) {
case R.id.actions:{
Intent myIntent = new Intent(this, ActionListActivity.class);
this.startActivity(myIntent);
ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog.show();
Intent dataIntent = new Intent(this, DatabaseWorkIntentService.class);
dataIntent.putExtra(Utils.INTENT_SERVICE_INVOKE, Utils.READ_ACTIONS_DATA);
startService(dataIntent);
progressDialog.dismiss();
}
}
}
IntentService:
private void readActionData(){
Log.e("read actions data","data");
List<Action> actionList;
actionList = Action.listAll(Action.class);
Intent broadcastIntent = new Intent();
broadcastIntent.setAction(Utils.READ_ACTIONS_DATA);
broadcastIntent.putParcelableArrayListExtra(Utils.READ_ACTIONS_DATA, (ArrayList<? extends Parcelable>) actionList);
sendBroadcast(broadcastIntent);
}
ActionListActivity:
public class ActionListActivity extends BaseActivity {
boolean mIsReceiverRegistered = false;
DataBroadcastReceiver receiver;
TextView someTv;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.action_list_activity);
this.initToolbarAndDrawerWithReadableName(getString(R.string.our_actions));
someTv = (TextView)findViewById(R.id.someTv);
}
public void someTvTest(Action action){
someTv.append(action.getName());
Log.e("data",action.getName());
}
#Override
protected void onPause() {
super.onPause();
if (mIsReceiverRegistered) {
unregisterReceiver(receiver);
receiver = null;
mIsReceiverRegistered = false;
}
}
#Override
protected void onResume() {
super.onResume();
if (!mIsReceiverRegistered) {
if (receiver == null)
receiver = new DataBroadcastReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(Utils.READ_ACTIONS_DATA);
receiver.setMainActivityHandler(this);
registerReceiver(receiver, filter);
mIsReceiverRegistered = true;
}
}
}
class DataBroadcastReceiver extends BroadcastReceiver{
ActionListActivity activity = null;
ArrayList<Action> list;
public void setMainActivityHandler(ActionListActivity main){
activity = main;
}
#Override
public void onReceive(Context context, Intent intent) {
Log.e("reciever","reciev");
list = intent.getParcelableArrayListExtra(Utils.READ_ACTIONS_DATA);
for (Action action:list){
if(activity!=null) {
activity.someTvTest(action);
}
}
}
}
You start activity and service async.
You need to start service inside ActionListActivity and wait for response.
I'm sending a progress value like int progress = 10 via Broadcast from IntentService to display the progress of uploading file.
protected void onHandleIntent(Intent intent) {
broadcastIntent = new Intent();
broadcastIntent.setAction(SendList.mReceiver.TEST);
try {
broadcastIntent.putExtra("Count",mArraylist.size());
[...uploading data...]
for (int i = 0; i < mArrayList.size(); i++) {
broadcastIntent.putExtra("progress", i);
sendBroadcast(broadcastIntent);
//...
}
}
So in my Activity I register the receiver but it is never called.
public class SendList extends Activity {
TextView textResult;
ProgressBar progressbar;
boolean mIsReceiverRegistered = false;
BroadcastReceiver receiver;
#Override
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.sendlist);
textResult= (TextView)findViewById(R.id.maxFragments);
progressbar = (ProgressBar) findViewById(R.id.progressBar);
}
#Override
public void onResume() {
super.onResume();
if(!mIsReceiverRegistered) {
if (receiver == null)
receiver = new FragmentReceiver();
registerReceiver(receiver,new IntentFilter(mReceiver.TEST));
mIsReceiverRegistered = true;
}
}
#Override
public void onPause() {
super.onPause();
if(mIsReceiverRegistered) {
unregisterReceiver(receiver);
receiver = null;
mIsReceiverRegistered = false;
}
}
private void updateUI (Intent intent) {
progressbar.setProgress(intent.getIntExtra("progress", 0));
}
public class mReceiver extends BroadcastReceiver {
public static final String TEST = "upload";
#Override
public void onReceive(Context context, Intent intent) {
int count = intent.getIntExtra("Count",0);
progressbar.setMax(count);
textResult.setText(count);
updateUI(intent);
}
}
Where could be the problem? What am I doing wrong? Have I forgotten something?
Thanks for any help!
Kind Regards!
try to register you receiver as below -
IntentFilter filter = new IntentFilter();
filter.addAction(SendList.mReceiver.TEST);
registerReceiver(receiver,filter);
while broadcasting you are sending action as below
broadcastIntent.setAction(SendList.mReceiver.TEST);
and when you register it is different.
registerReceiver(receiver,new IntentFilter(FragmentReceiver.TEST));
Your action should be same while sending and receiving.
Hope this will help you.
I have an method like this:
public static boolean checkConnection(){
if(getConnection()!=null){
return true;
}else
return false;
}
I trying to listen to the result of this method throughout my application. Till my application is alive. Only inside my application
How should I create my own action so that in BroadcastReceiver I can listen to this method and show an dialog when it returns false and hide the dialog automatically when it start returning true?
How and what will be the best approach to do this?
public class BroadCastActivity extends Activity implements OnClickListener{
ConnectionReceverLocal mReceverLocal;
Button mSwithcOn,mSwitchOff;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_broad_cast);
/*Intent intent = new Intent();
intent.setAction("com.broadcast.myconnectionbroadcast");
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);*/
mReceverLocal = new ConnectionReceverLocal();
mSwitchOff = (Button)findViewById(R.id.switchoff);
mSwithcOn = (Button)findViewById(R.id.switchon);
mSwitchOff.setOnClickListener(this);
mSwithcOn.setOnClickListener(this);
}
private void sendMessage() {
new AsyncTask<Void, Void, Boolean>() {
#Override
protected Boolean doInBackground(Void... params) {
// TODO Auto-generated method stub
Log.d("Connection result Checking Asynctasks", ""+ConnectionProvider.checkConnection());
return ConnectionProvider.checkConnection();
}
#Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
Intent intent = new Intent("com.broadcast.myconnectionbroadcast");
// Add data
intent.putExtra("message", result);
LocalBroadcastManager.getInstance(BroadCastActivity.this).sendBroadcast(intent);
}
}.execute();
}
#Override
protected void onPause() {
super.onPause();
LocalBroadcastManager.getInstance(this).unregisterReceiver(mReceverLocal);
}
#Override
protected void onResume() {
super.onResume();
LocalBroadcastManager.getInstance(this).registerReceiver(mReceverLocal,
new IntentFilter("com.alignminds.broadcast.myconnectionbroadcast"));
sendMessage();
}
public class ConnectionReceverLocal extends BroadcastReceiver {
public ConnectionReceverLocal() {
}
#Override
public void onReceive(Context context, Intent intent) {
AlertDialog.Builder mDBuilder = new AlertDialog.Builder(BroadCastActivity.this);
Boolean intentAction = intent.getBooleanExtra("message", false);
if(intentAction==false)
{
Log.d("Connection is false in broadcast recever", "Connection is false");
if(mDBuilder!=null)
{
mDBuilder.setMessage("No Network");
mDBuilder.create().show();
}
}else {
Log.d("Connection is true in broadcast recever", "Connection is true");
if(mDBuilder!=null)
{
mDBuilder.setMessage("Network Ok");
mDBuilder.create().show();
}
}
}
}
#Override
public void onClick(View v) {
if(v==mSwithcOn)
{
WifiManager wifiManager = (WifiManager)this.getSystemService(Context.WIFI_SERVICE);
wifiManager.setWifiEnabled(true);
}
if(v==mSwitchOff)
{
WifiManager wifiManager = (WifiManager)this.getSystemService(Context.WIFI_SERVICE);
wifiManager.setWifiEnabled(false);
}
}
}
Send a broadcast with whatever action you want like this
Intent intent = new Intent();
intent.setAction("my_fancy_action");
intent.putExtra(EVENT_MESSAGE, message);
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
Subclass BroadcastReceiver class to listen for broadcasts
#Override
public void onReceive(Context context, Intent intent) {
String intentAction = intent.getAction();
// Do something
}
Register your receiver to listen to the broadcast
IntentFilter filter = new IntentFilter();
filter.addAction("my_fancy_action");
LocalBroadcastManager.getInstance(context).registerReceiver(myReceiver, filter);
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 );
I have an Android Activity that needs to catch two different broadcasts. My current approach is to have a single BroadcastReceiver within the Activity and catch both the broadcasts with it:
public class MyActivity extends Activity {
private MyActivity.BroadcastListener mBroadcastListener;
private boolean mIsActivityPaused = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mylayout);
// Create the broadcast listener and register the filters
mIsActivityPaused = false;
mBroadcastListener = new BroadcastListener();
IntentFilter filter = new IntentFilter();
filter.addAction(Params.INTENT_REFRESH);
filter.addAction(Params.INTENT_UPDATE);
registerReceiver(mBroadcastListener, filter);
}
#Override
protected void onResume() {
super.onResume();
mIsActivityPaused = false;
}
#Override
protected void onPause() {
super.onPause();
mIsActivityPaused = true;
}
#Override
protected void onDestroy() {
unregisterReceiver(mBroadcastListener);
super.onDestroy();
}
private void refresh() {
// refresh
}
private void update() {
// update
}
private class BroadcastListener extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Params.INTENT_REFRESH && !mIsActivityPaused)) {
refresh();
} else if (intent.getAction().equals(Params.INTENT_UPDATE)) {
update();
}
}
}
}
I want to execute refresh() only if my Activity is visible on the screen, but I want to catch INTENT_UPDATE and execute update() during the entire lifetime of the Activity, regardless of whether the Activity is visible or not.
I didn't find any way to unregister only one of the two filters that I register in onCreate, so I use a flag to enable or disable the action to be executed when the INTENT_REFRESH broadcast is caught, depending on the state of the Activity.
The question is: is this the correct approach?
Or, would it be better to have two separate BroadcastReceivers as follows:
public class MyActivity extends Activity {
private MyActivity.BroadcastListenerRefresh mBroadcastListenerRefresh;
private MyActivity.BroadcastListenerUpdate mBroadcastListenerUpdate;
private boolean mIsBroadcastListenerRefreshRegistered = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Create the broadcast listeners
mBroadcastListenerRefresh = new BroadcastListenerRefresh();
mBroadcastListenerUpdate = new BroadcastListenerUpdate();
registerReceiver(mBroadcastListenerRefresh, new IntentFilter(Params.INTENT_REFRESH));
registerReceiver(mBroadcastListenerUpdate, new IntentFilter(Params.INTENT_UPDATE));
}
#Override
protected void onResume() {
super.onResume();
if (mBroadcastListenerRefresh != null && !mIsBroadcastListenerRefreshRegistered) {
registerReceiver(mBroadcastListenerRefresh, new IntentFilter(Params.INTENT_REFRESH));
mIsBroadcastListenerRefreshRegistered = true;
}
}
#Override
protected void onPause() {
super.onPause();
if (mBroadcastListenerRefresh != null && mIsBroadcastListenerRefreshRegistered) {
unregisterReceiver(mBroadcastListenerRefresh);
mIsBroadcastListenerRefreshRegistered = false;
}
}
#Override
protected void onDestroy() {
unregisterReceiver(mBroadcastListenerRefresh);
unregisterReceiver(mBroadcastListenerUpdate);
super.onDestroy();
}
private void refresh() {
// refresh
}
private void update() {
// update
}
private class BroadcastListenerRefresh extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Params.INTENT_REFRESH)) {
refresh();
}
}
}
private class BroadcastListenerUpdate extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Params.INTENT_UPDATE)) {
update();
}
}
}
}
And which one has better performance?
instead, you may provide two different intent filters:
filter for refresh only
IntentFilter filterRefresh = new IntentFilter(Params.INTENT_REFRESH);
filter for refresh and update
IntentFilter filterRefreshUpdate = new IntentFilter();
filterRefreshUpdate.addAction(Params.INTENT_REFRESH);
filterRefreshUpdate.addAction(Params.INTENT_UPDATE);
now you may switch between intent filters by registering and un-registering the desired one but your receiver's implementation would be same
For every action , create IntentFilter and register it.
#Override
protected void onResume() {
super.onResume();
BroadcastListener receiver = new BroadcastListener();
// Register the filter for listening broadcast.
IntentFilter filterRefresh = new IntentFilter(Params.INTENT_REFRESH);
IntentFilter filterUpdate = new IntentFilter(Params.INTENT_UPDATE);
registerReceiver(receiver, filterRefresh);
registerReceiver(receiver, filterUpdate);
}
private class BroadcastListener extends BroadcastReceiver {
public void onReceive(Context ctx, Intent intent) {
if (intent.getAction().equals(Params.INTENT_UPDATE)) {
update();
} else if(intent.getAction().equals(Params.INTENT_REFRESH)) {
refresh();
}
}
}
Using KOTLIN you can do it inline:
broadcastReceiver = NukeBroadcastReceiver()
registerReceiver(broadcastReceiver, IntentFilter().apply {
addAction(ACTION_DESTROY_EVERYTHING)
addAction(ACTION_RESTART_WORLD)
})