Android In App Billing Access from another activity - android

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.

Related

surfaceview, activity, startactivityforresult, dialog in activity

Im working on a little game and having some issues.
There is the Menu
public void onClick(View arg0) {
// TODO Auto-generated method stub
switch (arg0.getId()){
case R.id.bStartGame:
Intent a = new Intent(Menu.this, Action.class);
startActivityForResult(a, 1);
break; }
then the activity which starts a surfaceview
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(new GameView(this));
}
and then the the surfaceView with the game mechanics.
Most of my code is in this view.
Now I have the problem to find a good solution for the gameoverscreen.
If I start a new activity inside the surfaceview, it works - but i dont get the result() which is the score achieved during a session.
So now I wanted to ask you guys how to solve this issue.
I thought of a way, but dont know how to implement it.
It would be to pass the highscore from the surfaceview to the activity and set it as a result(which the menu activity gets back) there.
And start an xml file via dialog, which would be the gameoverscreen and as soon as the player touches the back button he gets back to the menu where he can see his achieved score.
Can you please tell me how to code this?
Kind regards
Denis
There's a number of ways to solve this:
-use startActivityForResult and then send it back from your new activity, catching it in the old activity using onActivityResult (check https://developer.android.com/reference/android/app/Activity.html)
-do what i did (the lazy, hacky way :): start the new activity with startActivity() and add the highscore as extra data added to the intent. In your new activity, use getIntent().getInt (ow whatever) to get the sent score data and do with it what you will. Then close that activity and you'll return to the previous one holding your surfaceview.
NOW THE TRICK: before you start your new activity with it's score added to the intent, just run the same score calculation in your surfaceview's activity as you would in your new activity! That way, when you return to your surfaceview's activity, you will still have the correct, new score (if stored/onresume'd correctly; don't forget to add it to your save/restore state and/oror the surfaceview's private variables)!
The only downside is that you'll have two location you have to update your scoring mechanics at. And it's not good programming. But it works and it's easy.

Android Launching the current activity with different Intent Action

[Update Solution]
Referring to the post in the link
ViewPager PagerAdapter not updating the View
public void onSomeButtonClicked(View view) { // registered to Button's android:onClick in the layout xml file
Log.w(TAG,"Some button clicked !!");
getIntent().setAction(IntentManager.Intents.ACTION_SPAWN_LIST_BY_SOMETHING);
mViewPager.getAdapter().notifyDataSetChanged();
}
// And inside my PagerAdapter
#Override
public int getItemPosition(Object object) {
return 0;
}
Fixed all my problems, i just used Intent.setAction().
[Update to below Post]
My problem is i have a ViewPager PagerAdapter in my Main Activity. On clicking one of the 3 buttons., any specific intent will be fired (i used intent, i could have gone with just State variable as well, just that i pass some Uri with the intent). What happens is., i do
public void onSomeButtonClicked(View view) { // registered to Button's android:onClick in the layout xml file
Log.w(TAG,"Some button clicked !!");
getIntent().setAction(IntentManager.Intents.ACTION_SPAWN_LIST_BY_SOMETHING);
mViewPager.getAdapter().notifyDataSetChanged();
}
This is why i was guessing maybe i should just do startActivity again, with the new Intent Action on the same Activity.
Spawning a new Activity, i would have to redraw every other view in the layout which is basically the same code, for the most part in the current activity.
Any suggestions here? Please help
[Original Post]
I have a PagerAdapter and 3 Buttons in the my Main Activity. This activity is enter from Main Launcher.
When i press any one of the buttons, the Intent Action is changed.
My question:
The changed Intent action reflects some changed view in the ViewPager and does_not spawn a new Activity as such, only the view is updated.
What approach should i take to get this task?
Can i start the currentActivity using startActivity() and different Intent actions on button click?
or is there any other efficient way in android to do this?
[No need code, just explanation of logic / method would suffice]
Thanks in advance
If you are saying that you are trying to use startActivity to bring up the same activity again, and its not working, it could be because you set something like singleTop in your Android manifest.
If you are asking whether or not you should use an intent to change the state of your Activity, then the answer is "it depends". If the user would expect the back button to return your app to its previous state (instead of going back to the home screen), then it might be a good choice for you. If that is the case, however, I would ask why not just make 2 different Activities? Otherwise, just do as Dan S suggested and update the state of your Activity as the user interacts with it.
You can always use the onNewIntent() hook. Do something like this in your activity:
protected void onNewIntent(Intent intent){
//change your activity based on the new intent
}
Make sure to set the activity to singleTop in your manifest. Now whenever startActivity is called the onNewIntent() will be executed. Also, note that per the documentation:
Note that getIntent() still returns the original Intent. You can use setIntent(Intent) to update it to this new Intent.

Kill and destroy activity

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.

How to check if an activity is the last one in the activity stack for an application?

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.

Android Activity Update

I am calling an activity from within itself - basically i've a list of new storys and two filter buttons that when clicked restart the activity with an intent passed that changes the news stories.
When i run the app it works, but for a second i get the old activity UI while the app reads from the new xml feed and then the UI updates. Is there any way to stop this from happening and get the activity to restart cold.
here's the code I am currently attaching to the onclicklistener
public void openFootballNews(View v) {
Intent i = new Intent(this, News_Landing.class); // News_landing class is the class this code is in
Bundle bundle = new Bundle();
bundle.putString("code", "football"); // this, if set, changes the xml feed to read
i.putExtras(bundle);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
this.onCreate(null); //this has halved the time the old UI is on the screen for but I cant get rid of it completely
startActivity(i);
}
any help would be great, thanks!
Starting an activity from itself doesn't make much sense (unless your aim is to do something esoterically recursive ;) ). Also, I may be mistaken, but I believe activities are kept in a stack so that as you flip between news stories, you're piling up one nearly-identical activity after another. I'd similarly think calling onCreate() by hand is bad form.
Would need to see all of your code, but my guess is that you are reading your feed and creating your list inside onCreate(), and that your best bet is to refactor that into a openNews(String sport) method, which you call once in onCreate() and again in your listener(s).

Categories

Resources