eliminate the value of a variable in a service in android - android

my program is an activity to identify a user when that user is identified by pressing a button sends the string to another class (alarmChecker) that extends to a service. This service does is check every 30 seconds if the value of a database has changed, and if you notice changes launches.
Sending the String in the main class (MainActivity) I do it like this:
/ / Class MainActivity
Intent intent = new Intent (MainActivity.this, alarmChecker.class);
Bundle data = new Bundle ();
data.putString ("user", user);
intent.putExtras (data);
pendingIntent = PendingIntent.getService (MainActivity.this, 0, intent, 0);
Then the class "alarmChecker" receives the parameter as follows:
/ / class alarmChecker
#Override
public int onStartCommand(Intent intent, int flags, int startId){
super.onStartCommand(intent, flags, startId);
// Toast.makeText(this, "MyAlarmService.onStart()", Toast.LENGTH_LONG).show();
Bundle data = intent.getExtras();
user = data.getString("user");
Toast.makeText(getApplicationContext(), "user: "+user, Toast.LENGTH_LONG).show();
}
and I want to do is if the user presses the Return button or exit the application and return to the main screen (MainActivity) and identifies with another different user, alarmChecker class take the new values​​, but the problem is that the grabs. Always have the values ​​you enter the first time.
How to solve it?
Thanks for answering and greeting.

For your immediate question, your service can be updated with new values if you implement onStartCommand() in your service - it gets called every time the service receives a start intent, regardless of whether or not it has already started..
Unrelated to the question, in the long term, you might consider rethinking your design, as watching the database is a solved problem for you through the ContentObserver API, which does this kind of event from database it sounds like you're looking for.

Related

How to update value in Service from activity

I have a service start in Activity A with
private void startService() {
Intent pushIntent = new Intent(this, MyService.class);
pushIntent.putExtra(MyService.TYPE_SCREEN, 1);
startService(pushIntent);
}
in my Service I get data from onStartCommand
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
typeScreen = intent.getExtras().getInt(TYPE_SCREEN);
return Service.START_STICKY;
}
I want when change from activity A to activity B, I will update type of screen from 1 to 2 in Service.
How I can do it?
Android only create one instance of a service.
Request that a given application service be started. The Intent can
either contain the complete class name of a specific service
implementation to start, or an abstract definition through the action
and other fields of the kind of service to start. If this service is
not already running, it will be instantiated and started (creating a
process for it if needed); if it is running then it remains running.
So in your case, the service is already running, then you just have to send the intent with the screen 2 extra. It will only call the onStartCommand Override method.
Intent pushIntent = new Intent(this, MyService.class);
pushIntent.putExtra(MyService.TYPE_SCREEN, 2);
startService(pushIntent);

onStartCommand() called only once even when Service is started multiple times

The below service is triggered via button click from some other app (by firing pending Intent). The onStartCommand() creates a Messages and dispatches using send() method. Ideally, I expect onStartCommand to be called everytime button is clicked, as a pending intent is used to fire the service on buttonClick.
But onstartCommand() is called only once, for the first time the button is clicked. Subsequent button clicks do not trigger the onStartCommand().
Interestingly if I comment the line
replyTo.send(msg);
onStartCommand gets called each time the button from other app is clicked.
Therefore dispatching the Message using android IPC Messenger from within the service might be causing the issue. I confirmed the Message reaches the destination app successfully. Am I missing some detail about Messages , like blocking send call?
I am returning 'START_STICKY' from onStartCommand(), that also might be the reason.
Any insights on what is happening will be welcome.
//MyService.java
#Override
public void onCreate() {
// create RemoteViews -> rView
Intent intent = new Intent(getBaseContext(), MyService.class);
PendingIntent pendingIntent = PendingIntent.getService(getBaseContext(), 0, intent, 0);
rView.setOnClickPendingIntent(buttonId, pendingIntent);
//On click of the above button, this MyService will be started usingthe given pendingintent
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e("debug","Service onStartCommand");
Message msg = Message.obtain(null, UPDATE_REMOTE_VIEW, rView);
try {
replyTo.send(msg);
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return START_STICKY;
}
Bonus Detail: The pendingIntent on the Button (from other app) is set using setOnclickPendingIntent() (RemoteViews class).
What I did in my similar case is to implement onStartCommand as follow:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//
// ... HERE support for intent sent by setOnClickPendingIntent ...
//
return super.onStartCommand(intent, flags, startId);
}
And it seems to work. onStartCommand is called multiple times (as many as the number of click on my RemoteViews).
From Docs:
Clients can also use Context.bindService() to obtain a persistent
connection to a service. This likewise creates the service if it is
not already running (calling onCreate() while doing so), but does not
call onStartCommand(). The client will receive the IBinder object that
the service returns from its onBind(Intent) method, allowing the
client to then make calls back to the service. The service will remain
running as long as the connection is established (whether or not the
client retains a reference on the service's IBinder). Usually the
IBinder returned is for a complex interface that has been written in
aidl.
So, it may be because of the use of bindService

Launch an app from notification

I am building an application using PhoneGap, which revolves around a timer I have created. I am struggling at the moment as I need a way of having the app open itself if the timer reaches zero. I have currently put in place a notification for when the timer runs out, and the user can launch the app from there. However I need a way of launching the app if the user "misses" the notification or something similar.
For example, when the timer on the local "timer" app on a mobile device runs out, it will open itself to notify the user that the time has ran out.
Any suggestion would be appreciated,
Thanks.
Just write the code for opening the launcher Activity instead of showing notification in your service class.When the timer runs out the launcher activity will start instead of notification.
the code will look similar to this:
public class AlarmService extends Service {
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//calling Launcher Activity
Intent alarmIntent = new Intent(getBaseContext(), AlarmScreen.class);
alarmIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
alarmIntent.putExtras(intent);
getApplication().startActivity(LauncherActivity.class);
AlarmManagerHelper.setAlarms(this);
return super.onStartCommand(intent, flags, startId);
}
}
I hope you are satisfied with this answer.

Android Service Activity Intent

I want to pass a string from activiy to service.
Bundle mBundle = new Bundle();
mBundle.putString("MyString", string);
mIntent.putExtras(mBundle);
startService(mIntent);
this is in Activity class
Intent myIntent = getIntent();
String value = myIntent.getExtras().getString(key);
and this is in Service class
It doesn't accept getIntent() method :S I don't know what I'll do
The code in the service must be placed in onStart(Intent intent, int startid) method and the code becomes String value = intent.getExtras().getString(key);
When you start the service using startService(mIntent) the service's onStartCommand is called which is good place to handle the intent.
Move the part of your code that depends on the intent to onStartCommand: http://developer.android.com/reference/android/app/Service.html#onStartCommand(android.content.Intent, int, int)
OnStartCommand was called OnStart before api version 5, follow link to documentation for further information about backwards compatibility in your app.
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
String value = intent.getExtras().getString(key);
}
Also remember to move heavy code into a background thread that you start in onStartCommand, as otherwise you will run into an Application Not Responding error.

Confused by Android Services

I've read the documentation on Services thoroughly, but I'm still completely confused as to how to use/code a service.
What I'm trying to accomplish:
My main activity:
The user selects all options for a timer and then clicks a button to start up a timer (in a service) with the click. I'm trying to pass the options to the service with putExtra.
The service will collect the variables into new variables for the service's use.
I have an onCreate section that calls my public counter which I've declared inside of the service, but not in the onCreate section. I've also declared all my variables that need to be enumerated from options being passed from the activity here.
Do I need to bind to the service to truely pass the variables with putExtra?
I have an onStart which is where I'm trying to enumerate the variable values by doing a series of gets. This is triggered by the button mentioned earlier in the activity. Inside of the activity - Ex:
mSet.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
//if toggled on
if (mEnableDisable.isChecked()){
getCurrentTime();
//start passing our variables to the service
Intent passvars = new Intent(getBaseContext(),TimerService.class);
passvars.putExtra("mHour24", mHour24);
//start the service now
startService(new Intent(TimerService.class.getName()));
}
}
});
Inside of the service - Ex:
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
//Collecting data from Activity for calcs
Bundle getvars = intent.getExtras();
mHour24 = getvars.getInt("mHour24");
//start the counter now that I have my values
countDown.start();
}
Also if I can get the service to start without crashing I need to pass a value back to the activity. So I imagine I am doing that with putExtra in the service and getExtra in the activity. Once again, will I need to bind to the service to obtain the new values?
To bind if I need to I would do this on the button press. I would also add in a section to the main activity if the program exits, but then resumes to re-bind and collecting that value. The value I'm trying to pull is the time remaining from the counter. So inside of the counter service I would have an onTick put the remaining time into a variable and do a putExtra of that variable, where in the activity I want to collect that value and display it in the UI.
This is my first service attempt and I'm just not sure how to create and use properly. Thanks in advance for all the help and sorry for such a long convoluted post.
UPDATE:
So I have the service working now. I'm just having trouble getting information back from the service to the main activity.
I have added a function to try and retrieve the data from the service which is launched after the button click launches the service:
startService(passvars);
//Init. variable for getDisplayInf() function to update the display with counter strings
Running = 1;
getDisplayInf();
And the getDisplayInf() ex:
public void getDisplayInf() {
//Intent stIntent = new Intent(MainActivity.this,MainActivity.class);
//Intent passvars = new Intent(MainActivity.this,Service.class);
Bundle getvars = getIntent().getExtras();
String Remaining;
String CountDown;
do {
Remaining = getvars.getString("Remaining");
CountDown = getvars.getString("CountDown");
mRemaining.setText(Remaining);
mCountDown.setText(CountDown);
Running = getvars.getInt("Running");
}
while (Running == 1);
};
The timer will set the Running variable to 0 on finish.
As soon as I click the button with this new function in place is crashes the app.
In the service I'm doing this on the counter's onTick:
#Override
public void onTick(long millisUntilFinished) {
Running = 1;
Remaining = "Time Remaining: ";
CountDown = formatTime(millisUntilFinished);
ticker();
}
ticker's code:
public void ticker () {
Intent passvars = new Intent(Service.this,MainActivity.class);
//this is for the activity to keep looping to grab the countdown values while running this timer
//now send it to the activity
passvars.putExtra("Running", Running);
//String Values to be passed to the activity
//now send it to the activity
passvars.putExtra("mRemaining", Remaining);
//now send it to the activity
passvars.putExtra("mCountDown", CountDown);
};
Try starting your service with the passvars Intent rather than creating a new second intent:
Intent passvars = new Intent(MainActivity.this,TimerService.class);
passvars.putExtra("mHour24", mHour24);
//start the service now
startService(passvars);
If your Activity wants to get a value back from your Service you have a couple of choices:
Send an Intent from the Activity to the Service and get the result asynchronously using a ResultReceiver. The link given here by Claszen is excellent.
Use Binder. You can make a synchronous call that returns with the result.
Implement a Content Provider. This choice is for making your own data retrieval and storage component.
I realized I could obtain the amount of awareness that I wanted for the user by using the Notification Manager. So I implemented the notification manager and displayed my countdown information onTick() there.
The reason this worked best for me was because my service is technically a remote service (setup to run in its own process, which is defined in the manifest file.) It is far more complex to connect to a remote service and obtain data synchronously (which is what I wanted.) The notification manager option actually worked best for me here, as the program docks it's icon and updates the notification on each second.

Categories

Resources