I've been fiddling around with sample codes and ran across a snippet and tried using it but problem is I don't know how to call this kind of method from the same activity I declared it in. The snippet only showed this kind of method and not how to call it. I don't even know what this is defined as so it's been hard finding the answer, a method with multiple parameters I guess?
This is the method I want to call, it's linked to another class Payments.
void Calculate(Context con, Payments Pay)
I've tried the usual Calculate() but it tells me that Calculate(Context,Payments) cannot be applied to ();
Can anyone explain what's going on ?
Generate an object of the class Payments:
Payments pay = New Payment(Paramters);
Then call calculate with the getApplicationContext and the Payment object:
Calculate(getApplicationContext(), pay);
I hope it helps.
you have to pass context means activity instance & instance of payment class
Like
Context con = getActivity();
Payments Pay = new Payments();
Calculate(con,pay);
//removed the "void"
I hope this help you
Related
I am trying to use a code snippet from the official android documentation (https://developer.android.com/training/printing/photos#kotlin) which is the doPhotoPrint() function in the code that I have attached, in order to learn how to use the PrintHelper class in Kotlin and Android Studio. See the attached image of the the code snippet:
The problem is that when I put the code in Main Activity in my test app, it keeps showing "activity?." as red. Why is this the case and how can I get the code to work so that is provides the user with the option to print? Thanks
The code you linked is just a general how to use a library function snippet - it's not put in any context, but we can assume it's probably written with a Fragment in mind. Fragments have a getActivity() method that returns the Activity it's currently attached to (or null if it's not)
Kotlin allows you to access getter and setter functions from Java code as if they were properties - so basically, instead of having to do value = getThing()
and setThing(newValue) you can treat it like a variable: value = thing, thing = newValue etc. So when you access the activity property in this code, it's really calling getActivity(). And because the result can be null, you use the ? to null-check it before trying to do anything with it.
Really what that snippet is saying is, this code needs access to a Context, and it's using an Activity as one in the example. If you have a Fragment, you can just drop this code right in. If you're in an Activity though, then you obviously don't need to get one - this is your Activity! And you don't need to null-check it either of course. (And there's no activity property or getActivity() method to access, which is why it's showing up red and unrecognised)
So you can just replace that stuff and the checking code around it with:
private fun doPhotoPrint() {
// using 'this' to pass the current activity as the context
val printHelper = PrintHelper(this).apply {
scaleMode = PrintHelper.SCALE_MODE_FIT
}
val bitmap = BitmapFactory.decodeResource(resources, R.drawable.droids)
printHelper.printBitmap("droids.jpg - test print", bitmap)
}
It is showing red because you have not declared the nullable object activity anyway before you use it
apologies in advance, I'm more of a iOS developer than Android and despite reading various tutorials I'm really struggling to create a simple Google review prompt in my app.
I'm using ReviewManagerFactory. I've adde the build.gradle dependency
implementation 'com.google.android.play:core:1.8.0'
Within my code, on one activity I have a simple function called 'reviewPrompt'. Creating an instance of ReviewManager and requesting start review flow.
private void reviewPrompt() {
ReviewManager manager = ReviewManagerFactory.create(this);
manager.requestReviewFlow();
}
Is this all I need to do to achieve a review prompt? A lot of other tutorials (including Google ) keep talking about creating an instance of ReviewManagerFactory first
ReviewManager manager = ReviewManagerFactory.create(context)
And then adding this:
ReviewManager manager = ReviewManagerFactory.create(this);
Task<ReviewInfo> request = manager.requestReviewFlow();
request.addOnCompleteListener(task -> {
if (task.isSuccessful()) {
// We can get the ReviewInfo object
ReviewInfo reviewInfo = task.getResult();
} else {
// There was some problem, log or handle the error code.
#ReviewErrorCode int reviewErrorCode = ((TaskException) task.getException()).getErrorCode();
}
});
Why are they advising creating 2 instances of ReviewManger? Firstly with (context) and then with (this)? If both are needed do they both go in the same function or does
ReviewManager manager = ReviewManagerFactory.create(context)
Go somewhere else??
They also seem to attach listeners etc (in various ways), but as far as I can see that isn't necessarily needed unless I wish to track whether the review flow completed or failed etc.
Please correct me if I'm missing anything here.
Finally, I wish to call this function only when a user has opened a particular activity 'x' number of times in the app's lifetime. I my iOS I used User Defaults and reviewWorthyActionCount. Is there anything similar in Android?
Thanks in advance
according to ReviewManagerFactory , you should pass context , by the way android activity is context too . when you mention "this" it means you pass current object(the activity ) . you don't need to create 2 diffrenet objects using this and context ( both are same)
for second case , first save a value called fooActivityVisited in android SharedPereference ( its a local storage to store values) , then in your activity you increate it and check when reached to "Count" you will show the review
The example on the documentation is separated into 3 sections, it can be a bit hard to understand if you are new to android. Here you have a fully working example integrating the 3 sections from the documentation.
ReviewManager manager = ReviewManagerFactory.create(this);
Task<ReviewInfo> request = manager.requestReviewFlow();
request.addOnCompleteListener(task -> {
if (task.isSuccessful()) {
ReviewInfo reviewInfo = task.getResult();
val flow = manager.launchReviewFlow(this#/*Your activity class name here(ie:MainActivity)*/, reviewInfo)
flow.addOnCompleteListener { _ ->
//do something after the review flow finishes, like logging that the review flow was completed successfully
}
} else {
// There was some problem, log or handle the error code.
#ReviewErrorCode int reviewErrorCode = ((TaskException) task.getException()).getErrorCode();
}
});
Explanation:
Both
ReviewManager manager = ReviewManagerFactory.create(context)
and
ReviewManager manager = ReviewManagerFactory.create(this)
are the same thing, the second section on the documentation includes the first one, assuming that "this" is an object of type "context".
Then the line:
val flow = manager.launchReviewFlow(activity, reviewInfo)
might be confusing too, it means that the first parameter of launchReviewFlow should be of type activity, and will not work if you copy and paste the code. You will have to use something like:
val flow = manager.launchReviewFlow(this, reviewInfo)
//or
val flow = manager.launchReviewFlow(this#MainActivity, reviewInfo)
when "MainActivity" is the class name of your activity.
Then to store a counter you can use SharedPreferences or the new DataStore library as dominicoder said.
Why are they advising creating 2 instances of ReviewManger? Firstly with (context) and then with (this)? If both are needed do they both go in the same function or does
ReviewManager manager = ReviewManagerFactory.create(context)
Go somewhere else??
Your post is lacking ... context (hehe) ... but I don't think they're advising creating two instances, you might be looking at two different examples. I can't tell since you posted random snippets instead of a full example.
In any case, you need to create an instance of the manager with a Context. In the first example it would seem the code is called from a View or a Fragment neither of which are themselves Contexts, but they do have a context property.
In the second example, it would seem the code is called from an Activity, which is a Context, so it can be called with this.
As to where this goes - well, it would go wherever you need this manager object.
It would be easier to answer your question with full code examples or links to whatever tutorial you're following.
They also seem to attach listeners etc (in various ways), but as far
as I can see that isn't necessarily needed unless I wish to track
whether the review flow completed or failed etc.
Please correct me if I'm missing anything here.
Is there a question here? Which listeners is it that "they seem to attach"? What is this assumption based on? Can you post some code or a link to an example you're looking at?
Finally, I wish to call this function only when a user has opened a
particular activity 'x' number of times in the app's lifetime. I my
iOS I used User Defaults and reviewWorthyActionCount. Is there
anything similar in Android?
You are asking Android developers if there's anything similar to some iOS constructs without explaining what those constructs are. I could tell you if there is anything similar on Android if you explain what "User Defaults" and "reviewWorthyActionCount" are.
Beyond that, if I wanted to track some simple persistent state like "viewed Activity X times" I'd probably use SharedPreferences or the new DataStore library.
I'm in the process of completely redesigning my Android app. Before, EVERYTHING was in the same class.
So I tried to redraw everything so that the code is clearer apart Admob than the doc advice to put in the Main thread, I separate the different part of my code in class. So I used two technique: I created a songleton that contains variables that I want to have access to constantly,and I call my classes via weak reference.
Here is what it looks like:
For example, the UIManager class that needs to update the game's IU have a weak reference looks like this:
private static SoftReference<UIManager> ManageUI;
static{ManageUI= new SoftReference<>(null);}
static UIManager get()
{
if(ManageUI.get()==null)
{
ManageUI= new SoftReference<>(new UIManager());
}
return ManageUI.get();
}
GameManager Manager=GameManager.getInstance();
to be able to use the findviewbyid for example I place in method argument the main class that is the mainthread
the singleton that contains all my variables that I want to have permanent access to looks like this:
private GameManager()
{}
/** Holder */
private static class Manager
{
/** Instance unique non préinitialisée */
private final static GameManager instance = new GameManager();
}
/** Point d'accès pour l'instance unique du singleton */
public static GameManager getInstance()
{
return Manager.instance;
}
To separate all in different class, I pass argument to my method so I can call au stuff belong to Activity like that:
(My main class is called GamePlay)
void OpenGlobalScene(GamePlay activity)
{
Manager.OnTitle=false;
if (!checkLayout(activity,R.id.globalscene)) {
LayoutInflater(activity,9, true);
LinearLayout GamePlan = (LinearLayout) activity.findViewById(R.id.globalscene);
GamePlan.setAlpha(Manager.AlphaBord);
}
}
For now, I have not noticed any problems except a few slownesses on old android phone 4.4.2.
Also compared to my old code were EVERYTHING was in the same class, it's much easier to change pieces of code (going to the inapp billing V3 was simpler since everything was in one class that I call like the others with weak referencre)
My questions are:
-What are the problems that such a structure might pose?
I had also chosen that structure to not load or leave in memory things that are not useful
-How are chance that Android will erase from memory an action in progress called with weak reference?
-As you can see I pass the activity has argument to the method, sometimes I pass it from a method to another. Is that fact can cause some trouble?
Thank you for your help.
Check Dagger2 is better than the clasic singleton https://developer.android.com/training/dependency-injection/dagger-android?hl=es-419
thanks for your answer and your tips. I'am gonna check this out.
Anyone else know something about consequences on memory when using weak references ?
I have a simple test using an activityTestRule that should check whether a method of the activity under test was called:
#Test
public void callLiveLocation() {
MapSettingsActivity spy = spy(activityRule.getActivity());
doNothing().when(spy).setLiveLocation();
onView(withId(R.id.btn_map_current_location)).perform(click());
verify(spy).setLiveLocation();
}
The method setLiveLocation() is being called when I check in debug mode.
However, the console tells me:
Wanted but not invoked: mapSettingsActivity.setLiveLocation();
-> at com.android.dx.mockito.InvocationHandlerAdapter.invoke(InvocationHandlerAdapter.java:53)
Actually, there were zero interactions with this mock.
How do I check if the method of the activity under test was called?
I use Android's databinding for the button click, which invokes a callback, which in turn calls a method on the activity under test.
Note:
The method is a simple method on the activity:
public void setLiveLocation() {
super.startLocationListener();
}
Edit:
I noticed that creating the spy returns null for a yet unknown reason:
MapSettingsActivity spy = spy(activityRule.getActivity());
First of all this is not exact solution of your problem, but maybe it will help you.
So this is how I handled similar problem. In general: in order Mockito could detect method call on spy object, this method must be called on spied object (if you understand what I'm talking about, cause I don`t)). It is not true in your case. Your setLiveLocation called on real instance of activity, which is stored in ActivityTestRule.
My example:
I need to verify that RecyclerView`s adpter updateDataSet() method is called exactly once. This is how I did it in Kotlin:
val adapter = activityTestRule.activity
.find<RecyclerView>(R.id.reviewsList)
.adapter as FlexibleAdapter<ReviewItem>
assertNotNull(adapter)
val spy = spy(adapter)
activityTestRule.activity
.runOnUiThread {
activityTestRule.activity
.find<RecyclerView>(R.id.reviewsList)
.adapter = spy
}
doNothing().`when`(spy).updateDataSet(ArgumentMatchers.any())
onView(withId(R.id.swipeRefresh)).perform(ViewActions.swipeDown())
verify(spy, times(1)).updateDataSet(MOCKED_REVIEWS_FROM_SERVER.map(::ReviewItem))
So basically I get adapter from Recycler and change it to my spy adapter. My test finished successfully only when I made this replacement.
In your case ActivityTestRule holds instance of real activity, so you need somehow to replace it with spy object. I`m not sure how to do it, but I suppose there is chance to create subclass of this rule and to create spy of activity maybe in constructor. Then you will get spied object and use it to verify any calls.
I am using the TextToSpeech API and I want to seperate some logic into another class.
In the separate class I have put the following method:
public static void sayHello() {
// Select a random hello.
int helloLength = SoundGameScore.Questions.length;
String hello = SoundGameScore.Questions[currentHelloIndex];
currentHelloIndex = (currentHelloIndex + 1) % helloLength;
mTts.speak(hello, TextToSpeech.QUEUE_FLUSH, // Drop all pending entries
// in the playback queue.
null);
I have then created a variable in the main class: static mainclass object;
Within a button in the main class I call the method through this object by using:
object.sayHello();
I am quite new to android, and I know I am doing something wrong as this gives me a process closed error in the emulator. This also shows a nullexception error in logcat. Please help me, thanks.
I think you are getting a NullPointerException because the reference object is null. You would need to initialise the object in order to call an instance method on it.
However since sayHello() is a static method, you do not need to create an instance of the class in order to call the method. Just use mainclass.sayHello().
Your question and code suggests to me that you do not have much experience with Java. Perhaps you should do some tutorials to brush up on your Java coding before jumping into Android development. For example, Java convention is for class names to be capitalised (MainClass) and for references to have meaningful names (i.e. not things like object).