Getting Data from Service to Activity - Help! - android

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 in the main activity 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 inside of the service.
As soon as I click the button with this new function in place it crashes the app, so I'm assuming it has to do with the Bundle/intent I'm using in the getDisplayInf() code.
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);
};
Am I going about this in the right way? Is there an easier way? Some help would be greatly appreciated!!!

Related

Passing values from a fragment to another activity

I have a DialogFragment which has a listView as container. I've set up OnItemClickListener on the listView.
How can I get the value when the user touchs an item and pass it to another activity then store that value into a variable? I need to set a count down timer depending on which item will be selected. Actually can only display simple toast message with the item position.
As a note, the activity to which the value will be passed is not the fragment activity.
I was thinking about Bundle but have not having much knowledge on programming is a pain even after reading documentation on Google site.
on the MainActivy, here is how I set the timer:
new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
String elapsedTime = String.valueOf(millisUntilFinished / 1000);
timer.setText(elapsedTime);
}
public void onFinish() {
timer.setText(R.string.text);
}
}.start();
}
Exemple:
If user touches item 1 then the timer gets value 15 minutes and so on...
Please guide me, thank you.
So, you want to pass data from Fragment to Activity. Here is how you do it.
Passing the data from Fragment to Activity:
final Intent intent = new Intent(getActivity(), ActivityName.class);
intent.putExtra("counter-value", counterValue);
getActivity().startActivity(intent);
Reading the value in the Activity:
final Bundle extras = getIntent().getExtras();
if(extras != null) {
final int counterValue = extras.getInt("counter-value", -1);
showCountDown(counterValue);
}
Now, Pass the value to the countdowntimer.
private void showCountDown(final int counterValue) {
new CountDownTimer(counterValue, 1000) {
public void onTick(long millisUntilFinished) {
String elapsedTime = String.valueOf(millisUntilFinished / 1000);
timer.setText(elapsedTime);
}
public void onFinish() {
timer.setText(R.string.text);
}
}.start();
}

How Can get my App to Startup On Random Activity?

How can I get my app to start on random activity?
for example, i have 10 Activity ..What i want is on each time my app startup it open on one of 10 Activity randomly.
Please help, .
Make use of java.util.Random
You can use it return a random integer number between 0 and a particular number.
Then use that random value to start your activities.
To start a random activity during the start of your app, you will need to use a dummy activity as the launcher activity and start a random activity from there and finish that dummy activity.
For eg.
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Random random = new Random();
int index = random.nextInt(10); // assuming you have 10 activities.
switch (index) {
case 0:
// start activity 1
break;
case 1:
// start activity 2
break;
// other cases
}
finish();
}
}
In you splash activity do write following code
List<Intent> intents = new ArrayList<>();
intents.add(new Intent(this,Random1Activity.class));
intents.add(new Intent(this,Random2Activity.class));
intents.add(new Intent(this,Random3Activity.class));
Random rand = new Random();
int n = rand.nextInt(intents.size()) + 0;
new Handler().postDelayed(new Runnable(){
#Override
public void run() {
startActivity(intents.get(n));
finish();
}
}, 1000);
here is complete code , instead of thread use handler

Start a Service to get data from server after specified time Interval

I have a requirement to get data from server by sending a call after specified interval like 5 minutes. So app would keep checking for new data after 5 minutes. It is just like gmail or facebook. Which automatically get new feeds or emails after some time and show in list. I am using service for this like following:
public class MessagesLoaderService extends Service {
// constant
// run on another Thread to avoid crash
private Handler mHandler = new Handler();
// timer handling
private Timer mTimer = null;
//********************************************************************************************************************************/
#Override
public IBinder onBind(Intent intent) {
return null;
}
//********************************************************************************************************************************/
#Override
public void onCreate() {
// cancel if already existed
if (mTimer != null)
{
mTimer.cancel();
}
else
{
// recreate new
mTimer = new Timer();
}
// schedule task
mTimer.scheduleAtFixedRate(new MessageLoaderTask(), 0, Commons.TIME_INTERVAL_REFRESH_MESSAGES);
}
//********************************************************************************************************************************/
class MessageLoaderTask extends TimerTask
{
#Override
public void run() {
// run on another thread
mHandler.post(new Runnable()
{
#Override
public void run() {
//Get Data from Server and store in local db
}
});
}
}
#Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Utils.showToast_msg(getApplicationContext(), "Service Destroyed");
}
//********************************************************************************************************************************/
}
//////////////////////////////////////////////////////////////////
Starting service from main activity MainActivity:
startService(new Intent(this, MessagesLoaderService.class));
I want service to run (send calls after 5 minutes) only when the app is running or in foreground/background. But the problem is that it keeps running even if I exit from the application. I want service to stop when Application is closed. Any solution for this?
Shouldn't you stop your timer in "OnDestroy" with mTimer.cancel() if you want it to stop ?
This method works when you enter the activity which actually queries the server. Call the method in onCreate. If value returned is true, then fetch data from server, if false, do whatever is in youf flow.
This Example below uses Singleton class. The current system time, plus five minutes is stored in singleton class variable, while local variable stores the current time. If current time exceeds the time of Singleton variable, then true is returned and it is time to call server.
SingletonClass app;
app = (SingletonClass ) getApplication();
public boolean serverQueryFrequency() {
boolean isTimeElapsed;
Calendar cal = Calendar.getInstance();
long time = cal.getTimeInMillis();
// If No Time is set, only then Set the Current time + 10 into
// application variable. This should fire only once, until 10 minutes
// have passed
if (app.getServerCallTime() == 0) {
Calendar cal2 = Calendar.getInstance();
// updating calendar to get current time + 10
cal2.add(Calendar.MINUTE, 5);
long timeTen = cal2.getTimeInMillis();
app.setServerCallTime(timeTen);
// returning true, to enable server check
return true;
}
// Log.v("******", "Current : " + time);
// Log.v("******", "App Time : " + app.getServerCallTime());
// Comparing current time with SeverCalltime which is set 10 minutes
// ahead. Code below fires conditionally as stated
if (time == app.getServerCallTime() || time > app.getServerCallTime()) {
isTimeElapsed = true;
// Once true fired from here, reset serverCallTime
app.setServerCallTime(0);
} else {
// 5 minutes have not passed
isTimeElapsed = false;
}
// returning the related value
return isTimeElapsed;
}
you can stop service by using this line
stopService(new Intent(this, MessagesLoaderService.class));
so your service get stopped
you need to identify in your app from where your exiting the app at that point you need to call above code also OS automatically kill the service in certain circumstances like low battery and so on but this is not good solution so you can stop it by above line in your exit point of application
I have learned when the app is closed the service get closed also because they are in a one thread, so the service should be on another thread in order fot it not to be closed, look into that and look into keeping the service alive with alarm manager here an example http://www.vogella.com/articles/AndroidServices/article.html this way your service won't be shown in notification.
lastly, after all the research I've done I'm coming to realize that the best use of a long running service is start foreground(); because it is made for that and the system actually deals with your service well.
when the user presses back button on the first page of your app..means they want out.
override the onbackpressed and put the stopService call there.
else..
use an exit button..give it an onclick and inside it put the stopService there

android show an activity for every 24 hrs

in my app next to the splash screen i need to show an activity called Tips Page. This activity to be shown once in a day. When the user opens the app again within 24 hrs it should not be shown.
First i tried to show based on the current date, when the first the activity shown i will store the current date in shared preference and next time when the app gets opened i will check whether the current date and date in shared preference are equal or not. If equal i will not show the activity if not i will show the activity.
But here there is a logic mistake, if the user opens the app first in midnight of 11 PM in a date, and again opens the app after t hour the Tips activity will be shown, but i need to show it after 24 hrs, how can it be done. pls help me in this ligic
I think you need such a flow, see this the implementation of Jason Hessley's Answer
SharedPreferences settings = getSharedPreferences("Preferences",
MODE_PRIVATE);
long timeFromPrefs = settings.getLong("time", System.currentTimeMillis());
final long TIME_DIFF = 24*60*60*1000;
if ((System.currentTimeMillis()-timeFromPrefs)>TIME_DIFF) {
// show Activity...........
Editor editor = settings.edit();
editor.putLong("time", System.currentTimeMillis());
editor.commit();
}
Android applications can run periodic timers using android.os.Handler & java.lang.Runnable classes. As simple example is shown below.
Key Points
1. Service classes extending android.app.Service should implement onBind, onCreate & onDestroy, life cycle methods.
2. periodicTask is an instance of Runnable implementation, that runs a Thread. Execution of run() will print the message "Awake".
3. mHandler is an instance of Handler, that is attached the periodicTask thread.
4. The Handler is informed to execute the thread every minute, by postDelayed.
5. When the service is destroyed, the periodicTask instance is removed from the Handler, by invoking removeCallbacks.
Sample Code
public class PeriodicTimerService extends Service {
private Handler mHandler = new Handler();
public static final int ONE_DAY = 86400000;
private Runnable periodicTask = new Runnable() {
public void run() {
Log.v("PeriodicTimerService","Awake");
mHandler.postDelayed(periodicTask, ONE_DAY );
}
};
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
mHandler.postDelayed(periodicTask, ONE_DAY );
}
#Override
public void onDestroy() {
super.onDestroy();
mHandler.removeCallbacks(periodicTask);
Toast.makeText(this, "Service onDestroy() ", Toast.LENGTH_LONG).show();
}
}
Save the last time the activity was started in a shared pref as you stated in your question. Then subtract the last time from the current time. If it is greater then 24 hours, show your tips.

Android Rotation with IntentService

I have an application that uses IntentService to run a background task where I pull data from a website, parse the data out, and create calendar events based on the results. Everything seems to be working create, except I'm running into an issue with rotation.
Using the code below, when I rotate the screen, the ProgressDialog box stays visible, but is never updated with new text when the process is updated, and never goes away once the call is completed. I'm using an IntentService instead of an ASyncTask because the user can also schedule the IntentService to run at other times without having to interface with the app. Any help is appreciated, thanks!
public void onCreate(Bundle savedInstanceState) {
Object retained = getLastNonConfigurationInstance();
if (retained instanceof CalendarHandler) {
// CH is a class level variable defined at the top which references my IntentService, aptly named CalendarHandler
ch = (CalendarHandler) retained;
ch.setActivity(this);
} else {
ch = null;
}
activity = this;
btnLogin.setOnClickListener(OnClickListener(View view) {
ch = new CalendarHandler();
ch.setActivity(MyTlc.this);
// Do other stuff, like run the intent service
}
}
public Handler handler = new Handler() {
public void handleMessage(Message message) {
// We read the information from the message and do something with it
// based on what the result code is
String result = message.getData().getString("status");
if (result.equals("ERROR")) {
activity.removeDialog(PROGRESS_DIALOG);
results.setText(message.getData().getString("error"));
} else if (result.equals("DONE")) {
activity.removeDialog(PROGRESS_DIALOG);
int count = message.getData().getInt("count", 0);
activity.results.setText("Added " + count + " shifts to the calendar");
} else {
activity.pDialog.setMessage(result);
}
super.handleMessage(message);
}
};
From what I understand, this should work, and like I said the ProgressDialog box does stay properly, I just can't seem to pass information to the dialog box after rotating.

Categories

Resources