The first screen of my application is a login screen, so I used the method finish () after user have logged. However when i return the application I would like to be already logged. I tried to use onDestroy (), but without success.
It'll be better if you implement your logic otherwise. The first screen in your application can be HomeScreenActivity in which you'll check if the user is logged and start LoginActivity if needed.
public class HomeScreenActivity extends Activity {
/* some declaration */
public void onCreate(Bundle savedInstanceState) {
/* some other stuff */
if (!userIsLogged()) {
Intent intent = new Intent(this,LoginActivity.class);
startActivity(intent);
}
}
}
You have to use SharedPreferences.
See Data Storage on Android Developer
You might want to have a look at the Activity Life Cycle... Furthermore SharedPreferences can be used to save username/login details but im of the understanding that they can be accessed by any application, so be careful what you put there.
Related
I just want to Clear all the data of Previous Activity. Means when i will go back to previous activity it need to call all the asyncatsk again as a fresh new activity.
Because when i was goes in a next activity i was doing some changes in data sequence but i will come back i need to call agin asynctask for original data
So anyone have idea about it ??
and yes i just want to clarify that Below's Function is not working
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
There are a couple options depending on your situation.
First, you could try clearing your savedInstanceState like this:
public void onCreate(Bundle savedInstanceState){
super.onCreate(null);
}
Or like this:
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.clear();
}
Second, if you're hoping to have this specifically on the "backpressed" event,
you could override onBackPressed to create a new instance of your activity, rather than the default of returning to the activity with its saved state.
#Override
public void onBackPressed(){
//super.onBackPressed(); // EXCLUDE this line
Intent intent = new Intent(this,TheNextActivity.class);
startActivity(intent);
}
#iguarna 's answer is also something to try, it all depends on the situation and what you're hoping to accomplish
If you want to re-initialize your activity in any way when you come back to it, just reset the values you want in onResume().
If that is not what you were looking for, please clarify your question.
I have all the In App Billing code working fine on my MainActivity.
The problem is that I want to access that code from another activity.
The code I'm trying to reach is here on my main Activity:
public void buyCode() {
Log.d(TAG, "2. Button pressed");
mHelper.launchPurchaseFlow(MainActivity.this, SKU_TEST, 10001,
mPurchaseFinishedListener, "abc123abc1234");
}
I've tried using this code on my OnClickListener on the Other Activity but it's not working, result NullPointerException
MainActivity myMainActivity = new MainActivity();
myMainActivity.buyCode();
How can I accomplish this?
Thanks
You cannot create an instance of activity by yourself and expect it behaving as a activity created by system. It won't work because system handles all the lifecycle events like create, start, stop, pause etc.
You either need to have a dedicated activity for in-app payments or you need to embed mHelper into every activity to execute buying (which is less preferable).
In the first case your main activity must be only responsible for buying operations and handling results. Then you can call it via Intent from any other activity. In the second case you implement same buying logic in multiple activities (which is bad idea) and you don't need to call main activity any longer.
If, in your case, main activity does more, than just handling in-app payments, then you can call it with an additional flag, saying a user want to buy something. You can do it as following.
// calling activity
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra("purchase", true);
startActivity(intent);
// MainActivity.java
#Override
public void onCreate(Bundle savedInstanceState) {
boolean executePurchase = getIntent().getBooleanExtra("purchase", false);
if (executePurchase) {
// start purchasing logic
...
} else {
// continue with the standard logic
...
}
}
But the MainActivity will be started in front of calling activity, and you cannot avoid this with the design you currently have.
I made 2 activities.
e.g] MainActivy and MediaActivity.
If user click home button in MediaActivity, App will hide.
I want launch MediaActivty again when screen on.
Open the gmail app, tap on an email to show it's contents. You have now gone from one activity (email list) to another (email details). Press the home button. Now open the gmail app again. Voila! You have returned to the email you selected.
What you ask for is the default behavior of an Android app. Unless you do something like call finish() in your onPause() method in MediaActivity you should return to MediaActivity when you open the app again.
If your app doesn't behave like this I suggest that you post some code.
Try to write your activities the following way :
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Put your own code here.
}
}
public class MediaActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Put your own code here.
}
}
What you're asking is Up Navigation / Ancestral Navigation(if I understood it correct). Refer to this guide: http://developer.android.com/training/implementing-navigation/ancestral.html
Othewise, if you want to have multiple instances of an activity, it's android:launchMode property should be set to standard in manifest. Refer:
http://developer.android.com/guide/topics/manifest/activity-element.html
I want to know if user would return to the home screen if he exit the current activity.
I'm going to improve on the comment of #H9kDroid as the best answer here for people that have a similar question. (Original link)
You can use isTaskRoot() to know whether the activity is the root of a task.
UPDATE (Jul 2015):
Since getRunningTasks() get deprecated, from API 21 it's better to follow raukodraug answer or Ed Burnette one (I would prefer second one).
There's possibility to check current tasks and their stack using ActivityManager.
So, to determine if an activity is the last one:
request android.permission.GET_TASKS permissions in the manifest.
Use the following code:
ActivityManager mngr = (ActivityManager) getSystemService( ACTIVITY_SERVICE );
List<ActivityManager.RunningTaskInfo> taskList = mngr.getRunningTasks(10);
if(taskList.get(0).numActivities == 1 &&
taskList.get(0).topActivity.getClassName().equals(this.getClass().getName())) {
Log.i(TAG, "This is last activity in the stack");
}
Please note, that above code will be valid only if You have single task. If there's possibility that number of tasks will exist for Your application - You'll need to check other taskList elements. Read more about tasks Tasks and Back Stack
Hope this will help new beginners, Based above answers which works for me fine, i am also sharing code snippet so it will be easy to implement.
solution : i used isTaskRoot() which return true if current activity is only activity in your stack and other than i also handle case in which if i have some activity in stack go to last activity in stack instead of opening new custom one.
In your activity
#Override
public void onBackPressed() {
if(isTaskRoot()){
startActivity(new Intent(currentActivityName.this,ActivityNameYouWantToOpen.class));
// using finish() is optional, use it if you do not want to keep currentActivity in stack
finish();
}else{
super.onBackPressed();
}
}
there is an easiest solution to this, you can use isTaskRoot()
in your activity
One way to keep track of this is to include a marker when you start a new activity and check if the marker exists.
Whenever you start a new activity, insert the marker:
newIntent=new Intent(this, NextOne.class);
newIntent.putExtra(this.getPackageName()+"myself", 0);
startActivity(newIntent);
And you can then check for it like this:
boolean islast=!getIntent().hasExtra(this.getPackageName()+"myself")
While there may be a way to achieve this (see other answers) I would suggest that you shouldn't do that. Normal Android applications shouldn't need to know if the Home screen is about to display or not.
If you're trying to save data, put the data saving code in your onPause() method. If you're trying to give the user a way to change their mind about existing the application, you could intercept the key up/down for the Back key and the onBackPressed() method and present them with an "Are you sure?" prompt.
I've created a base class for all my activities, extending the AppCompatActivity, and which has a static counter:
public abstract class BasicActivity extends AppCompatActivity {
private static int activityCounter = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
++activityCounter;
...
}
#Override
public void onDestroy() {
super.onDestroy();
--activityCounter;
if(activityCounter==0) {
// Last instance code...
}
}
public boolean isLastInstance() { return (activityCounter==1); }
}
This has worked well enough, so far; and regardless of API version. It requires of course that all activities extends this base class - which they do, in my case.
Edit: I've noticed one instance when the counter goes down to zero before the app completely exits, which is when the orientation is changed and only one activity is open. When the orientation changes, the activity is closed and another is created, so onDestroyed is called for the last activity, and then onCreate is called when the same activity is created with the changed orientation. This behaviour must be accounted for; OrientationEventListener could possibly be used.
The Problem with sandrstar's solution using ActivityManager is: you need a permission to get the tasks this way.
I found a better way:
getIntent().hasCategory(Intent.CATEGORY_LAUNCHER)
The Activity on the Stack bottom should allways get this category by default while other Activities should not get it.
But even if this fails on some devices you can set it while starting your Activity:
Intent intent = new Intent(startingActivity, SomeActivityClass.class);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
activity.startActivity(intent);
Android implements an Activity stack, I suggest you read about it here. It looks like all you want to do though is retrieve the calling activity: getCallingActivity(). If the current activity is the first activity in your application and the application was launched from the home screen it should (I assume) return null.
The one thing that missed here, is the "Home key" click, when activated, you can't detect this from your activity, so it would better to control activity stack programmatically with handling "Back key" press and moving to required activity or just doing necessary steps.
In addition, you can't be sure, that starting your activity from "Recent Activity" list can be detected with presetting some extra data into intent for opening activity, as it being reused in that case.
The official documentation describes tasks as follows:
*All the activities in a task move together as a unit. The entire task (the entire activity stack) can be brought to the foreground or sent to the background. Suppose, for instance, that the current task has four activities in its stack — three under the current activity. The user presses the HOME key, goes to the application launcher, and selects a new application (actually, a new task). The current task goes into the background and the root activity for the new task is displayed. Then, after a short period, the user goes back to the home screen and again selects the previous application (the previous task). That task, with all four activities in the stack, comes forward.
Is there a way to programmatically detect when the task of the current Activity moves into and out of the background? I would like to know when the user has switched switched to another application, vs. when the user navigated to another Activity in the current app.
Note: I've always had this design in my head but never got around to concrete tests (reasonably sure it works though), so if you end up trying this, tell me how it goes. :)
I don't think there's an official API method that'll give you this functionality (I may be wrong), but you can certainly construct your own. This is just my way of doing it; there may, of course, be better implementations.
In your application, you always know when you're starting another activity. With that said, you can create a global class that handles starting all of your application activities and keeps track of a boolean that represents when you're starting an activity:
public class GlobalActivityManager {
private static boolean isActivityStarting = true;
public static boolean isActivityStarting() {
return isActivityStarting;
}
public static void setIsActivityStarting(boolean newValue) {
isActivityStarting = newValue;
}
public static void startActivity(Activity previous, Class activityClass) {
isActivityStarting = true;
// Do stuff to start your activity
isActivityStarting = false;
}
}
Then in each of your activities (maybe make this a superclass), override the onPause() method to check if it's another one of your application's activities starting or a foreign task's application coming in front of your application. This works because onPause is executed when anything comes in front of the activity, meaning it's called when you start your activity in GlobalActivityManager where isActivityStarting is true.
public void onPause() {
super.onPause();
if (GlobalActivityManager.isActivityStarting()) {
// It's one of your application's activities. Everything's normal.
} else {
// Some other task has come to the foreground. Do what needs to be done.
}
}
public boolean isCurrentTaskInBackground() {
List<RunningTaskInfo> taskInfoList = mActivityManager.getRunningTasks(1);
if (taskInfoList != null && taskInfoList.size() > 0) {
RunningTaskInfo info = taskInfoList.get(0);
ComponentName componentName = info.baseActivity;
MobileTvLog.debug("App#isCurrentTaskInBackground -> baseActivity = " + componentName);
String packageName = componentName.getPackageName();
return !YOUR_PKG_NAME.equals(packageName);
} else {
return true;
}
}
Maybe this can be helpfull, tell me if it worked for you.
only when you return from background the value of activities would be 0 (zero)
the rest of the time would be a number higher than 0(zero) when the onRestart()
is executed.
public class FatherClass extends Activity {
private static int activities = 0;
public void onCreate(Bundle savedInstanceState, String clase) {
super.onCreate(savedInstanceState);
}
protected void onRestart()
{
super.onRestart();
if(activities == 0){
Log.i("APP","BACK FROM BACKGROUND");
}
}
protected void onStop(){
super.onStop();
activities -= 1;
}
protected void onStart(){
super.onStart();
activities += 1;
}
}
All of your classes must extend from this class for this to work.
That will not work. Your activity could get an onPause for reasons other than your app explicitly starting another activity. For instance, the user could have hit the back button, taking you back to a previous Activity in your stack.
Try to read about android:finishOnTaskLaunch
http://developer.android.com/guide/topics/manifest/activity-element.html#finish
It solved my similiar problem ;-)
I've been looking for a good answer to this question. It seems Andy Zhang had a good idea, but it may need a bit more work to handle other things, like the Back button.
Another approach which seems promising is to use the ActivityManager.getRunningAppProcesses() method, which will give you a list of RunningAppProcessInfo which each have an "importance" variable which can be used to detect if your process is in the foreground or other states.
The problem of course is there is no Detection technique here, just a way to tell what is running and its state, but no way to get informed when the state changes.
So possibly just run a background thread to poll this info. Seems a bit kludgy but it might work.
My app uses location services (GPS) so it automatically gets called when the location changes, and I can check the RunningAppProcessInfo list when this happens to determine if my App is still in the foreground. Seems like a lot of work, so maybe Andy's approach can be improved on.
I have been using the method I describe here:
Simple check for Android application backgrounding
It has been working wonderfully for me.
you might be able to use the isFinishing() method in onPause(). That will tell you if the application is actually finishing or is just being paused. When your task stack goes to the background, the activities aren't finished, they are just paused. This will also get called if you start another activity from this one though, so you would have to check for that.
#Override
public void onPause() {
super.onPause();
if(!isFinishing()) {
//app going to background
}
}