I'm trying to write a simple test app to run in JUnit. I've been having trouble getting clickView to click on the proper view. Below is some sample code that can be used on SkeletonActivity sample app that comes with the SDK.
public class SkeletonInstrumentation extends ActivityInstrumentationTestCase2<Activity>{
private Activity act;
private Button bClear;
private Button bBack;
private EditText eMain;
public SkeletonInstrumentation(){
super("com.example.android.skeletonapp", Activity.class);
}
public void setUp() {
String app = this.getInstrumentation().getTargetContext().getPackageName();
this.setActivityInitialTouchMode(true);
act = this.launchActivity(app, SkeletonActivity.class, Bundle.EMPTY);
bClear = (Button) act.findViewById(R.id.clear);
bBack = (Button) act.findViewById(R.id.back);
eMain = (EditText) act.findViewById(R.id.editor);
}
public void testClick()
{
TouchUtils.clickView(this, bClear);
}
public void testSendKeys()
{
act.runOnUiThread(
new Runnable(){
public void run(){
bClear.clearFocus();
eMain.requestFocus();
}
}
);
this.sendKeys("A B C D E F G ENTER");
}
}
testClick runs, but clicks on the main EditText view that has focus when the Activity starts and ends up bringing up the on-screen keyboard. I want it to click on the 'Clear' button below the EditText. Can someone tell me what's wrong here?
Adding the min and max target SDK in the AndroidManifest.xml worked for me; I got the idea from this answer. In the project that is being tested (not the test project) I added the following line to AndroidManifest.xml:
<uses-sdk android:targetSdkVersion="17" android:minSdkVersion="17"/>
and all of my uses of TouchUtils started behaving consistently again.
I had the same problem in this question and while I was able to find a workaround but it became really cumbersome so I spent more hours getting to the bottom of it.
The use of clickView here is correct. The problem was in the AndroidManifest.xml. Min and Target SDK must be set for it to work properly.
Related
I've been trying to get a simple calculator app working for the past couple of days but I can't seem to narrow the problem. I am a total newbie at android development so there could be a problem with my mainActivity code but I've made some precautions and tried them out. I tried deleting all the code I personally made and redoing the whole emulator process and the app still does not open. I have tried deleting the app on the emulator and restarting, I tried rebuilding, cleaning and turning off instant run. I don't believe it's an Android Studio issue because I created a new project and tossed some XMl elements in and it ran perfectly fine on my computer. I think there's something wrong with my code.
I have deleted code I've written and running the application to no avail. I have uninstalled the application on the emulator and ran it again. I have trying rebuilding and cleaning the project. I have tried syncing the gradle. And I have tried turning on instant run. By the title this may seem like the same thing but it isn't.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
buttonAdd = findViewById(R.id.Add_Button);
buttonSub = findViewById(R.id.Sub_Button);
buttonDiv = findViewById(R.id.Div_Button);
buttonMult = findViewById(R.id.Mul_Button);
mText = findViewById(R.id.Answer);
//Conversion of textview to double
UserInput = findViewById(R.id.FirstNumber);
UserInput2 = findViewById(R.id.SecondNumber);
userinput = Double.parseDouble(UserInput.getText().toString());
userinput2 = Double.parseDouble(UserInput2.getText().toString());
//functions for the operations.
buttonAdd.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View a){
mText.setText("Answer = " + Double.toString((userinput+userinput2)));
}
});
buttonSub.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mText.setText("Answer = " + Double.toString((userinput - userinput2)));
}
});
buttonMult.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mText.setText("Answer = " + Double.toString((userinput*userinput2)));
}
});
buttonDiv.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mText.setText("Answer = " + Double.toString ((userinput / userinput2)));
}
});
}
}
I would expect to run the program but it doesn't run. I'm hoping that the above code is enough because I must be making an obvious mistake.
LogCat:
My LogCat Errors
I've figured it out! It was a number exception error. My .getText() values are trying to get values before the user even clicks anything. In my case, these editText values were set to "Input first number" and "Input second number" respectively. You can't hope to get an integer value from a string! So obviously it threw it. After putting those two .getText() things inside each onClick, it was fixed. I appreciate the help guys! I've learned a lot about the whole debugging process in the last 15 minutes, I appreciate it. Thanks again!
Your problem lies here:
UserInput = findViewById(R.id.FirstNumber);
userinput = Double.parseDouble(UserInput.toString());
Your UserInput variable is an instance of TextView. You are trying to extract the current text of the TextView, but toString() is not the right method to do that, it only prints out metadata about that class. You can replace it with:
Double.parseDouble(UserInput.getText().toString());
You use 2 TextViews: UserInput and UserInput2 which you use to get the user's input!! How? TextViews are not editable. You should have used EditTexts.
So when your app starts you get their text with these lines:
userinput = Double.parseDouble(UserInput.toString());
userinput2 = Double.parseDouble(UserInput2.toString());
Do these TextViews contain any text and if yes is it valid number?
If not then an error will be thrown because you try to cast text to number but that text cannot be casted.
But even if the TextViews contained valid numbers the way you use to obtain their text is wrong, it should be by getText().toString():
userinput = Double.parseDouble(UserInput.getText().toString());
userinput2 = Double.parseDouble(UserInput2.getText().toString());
Edit
These 2 lines above copy them in all 4 listeners just before the calculation.
After that delete them from where you originally had placed them because when you start the app the EditTexts are empty and if you try to cast them to a number the app crashes.
Your made a problem by writing
userinput = Double.parseDouble(UserInput.getText().toString());
userinput2 = Double.parseDouble(UserInput2.getText().toString());
in onCreate() function. onCreate() only runs when the application starts at first. and is currently the only place you call getText(). Therefore, the values in UserInput and UserInput2 are empty. that is the reason java.lang.numberformatexception is raising.
make these changes and your application will work correctly.
delete these two lines of code from onCreate() function.
UserInput = findViewById(R.id.FirstNumber);
UserInput2 = findViewById(R.id.SecondNumber);
Create the following function outside of onCreate function
public void getInput(){
UserInput = findViewById(R.id.FirstNumber);
UserInput2 = findViewById(R.id.SecondNumber);
}
Call this function inside every OnClickListener. like the following..
buttonSub.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getInput();
mText.setText("Answer = " + Double.toString((userinput - userinput2)));
}
});
I hope your problem is solved. ask me any question in comment below if you have any doubt
I got a problem when I navigate between two activities, it shows me error and I don't know what is the problem. I am very sure that my code is correct, because it just simple Intent navigate by on click Button.
When I Press the button to go to the next activity it returns me to the fist activity (not the desire one). Note that both activity has background image.
Fist Activity
public class firstActivity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.first_activity);//has a background img and one button
}
public void nextPage(View view){
Intent StartNewActivity = new Intent(firstActivity.this, secondActivity.class);
startActivity(StartNewActivity);
overridePendingTransition(R.layout.slide_in_up, R.layout.slide_out_up);
}
}
Second Activity
public class secondActivity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second_activity);// has a background img and one button
}
public void nextPage(View view){
Intent StartNewActivity = new Intent(secondActivity.this, thirdActivity.class);
startActivity(StartNewActivity);
overridePendingTransition(R.layout.slide_in_up, R.layout.slide_out_up);
}
}
This is the error message
Could not find class 'android.graphics.drawable.RippleDrawable', referenced from method android.support.v7.widget.AppCompatImageHelper.hasOverlappingRendering
Also, I did not use any ripple drawable in my app.Even though I don't know what does it mean?
Thanks,
Something you have wants to to find a refwrence to that ripple component, you need to find out what.
Otherwise, you can try to make sure you have added a reference to the support.v7.widget in the second activity and see if the exception goes away.
Aside from that, we would need to see more code to help further.
When I Press the button to go to the next activity it returns me to the fist activity (not the desire one)
It means that your app crashes when loading your new activity, so it comes back the first one.
Check your activity layout, style configuration => clean your project => Run again.
Hope it can help.
I solved my problem by resizing the background images of the activities, and I added this extra attribute in the manifests file
<application
android:largeHeap="true" >
</application>
I'm programming an app which one of its functionalities is that the users can tap on a plus button (typical (+)...) that has to create a new activity and a new XML file with a specific structure.
I'm beginner on Android and also in Stack Overflow, so due to that I'm unable to post images and make this question easier to understand.
I need you to summarize how to program this. I'm not telling you to codify my code, I just need to know if it's possible to do and ,more or less, the steps to get it.
Hope you can help me. Thanks!
Okay, so this is how you'd do it, if you're sure you want to create a new instance of the activity from that very same activity. First, make a reference to your "plus button". Assuming the android:id="#+id/plusButton, it'd be like this:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
//Initialize your layout and variables
findViewById(R.id.plusButton).setOnClickListener(new View.onClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(getApplicationContext(), MainActivity.class);
startActivity(i);
}
});
}
}
This would launch a new instance of the same Activity (MainActivity) and give it focus.
You can make the activity yourself and have a button open the activity.
You'd start by making a new android activity. With eclipse it's simply File >> New >> Other >> Android Activity and then just fill out the form and hit finish. Make sure your current project is open.
Draw the button in your xml file, make sure it has a unique Id to reference and your text is declared in your strings.xml file that should look like this.
<string name="strX">(x)</string>
then in your activity's xml file under your button make sure you have
android:text="#string/strX"
You can also reference this in the GUI in the properties window under text.
With the button code in your .java you could use OnClickListener and Intent and the code for the button would look something like this.
TextView buttonYourButton = (TextView) findViewById(R.id.ButtonYourButtonId);
Button pushYourButton = (Button) buttonPlay;
pushYourButton.setOnClickListener(new View.OnClickListener() {
#Override public void onClick(View v) {
Intent nameOfIntent = new Intent(NameOfCurrentClass.this, NameOfNewClass.class);
startActivity(nameOfIntent);
}
});
R.id.ButtonYourButton is the Id you gave the button, and the .class is the name of the public class in that .java file. Like:
public class MainActivity { ...
Anyways, good luck I was where you were about a month ago. Don't forget to check out tutorials on Android development on youtube, there are about a million of them. Also you can search stackoverflow for questions that already have been asked.
public class Menu extends Activity {
/** Called when the activity is first created. */
public void onCreate(Bundle icicle) {
//myIntent.setClassName("hello.World", "hello.World.mybuttonclick");
// myIntent.putExtra("com.android.samples.SpecialValue", "Hello, Joe!"); // key/value pair, where key needs current package prefix.
//startActivity(myIntent);
//Button myButton = (Button) findViewById(R.id.my_button);
super.onCreate(icicle);
setContentView(R.layout.main);
}
public void updateLayout(){
Intent myIntent = new Intent(Menu.this, mybuttonclick.class);
startActivity(myIntent);
// TextView sayHello = (TextView) findViewById(R.id.Hello);
}
}
Hey guys, I am a new android java student and we have to develop a simple hello world app.. I am finding some difficulty getting my onClick() activity to work, using android:Onclick in xml.. what i am trying to do is change the content view do display a simply a different layout and saying hello.. i am using setContentLayout to do this, every time i click said button tho the android app crashes out.. am i doing something wrong?
regards,
Stefan
When you set a click listener in xml you must have the method defined inside the activity you are clicking in. Lets say you set the onClick in xml to be "buttonClicked", you must create a method looking exactly like the one below.
public void buttonClicked(View view)
{
//Your code here
}
The thing to notice is that the method is a public void with only a single parameter of type View. XML defined click listeners must be like this to work. The view object in the example above is the view that was clicked.
You update layout function needs to read
public void updateLayout(View view)
In response to your question, there are a number of things that are issues causing the complication that you described. Let it first be said, that you don't have to do anything any particular way, provided that you make concessions for certain things. Android is a very flexible platform and Java, as an OOP language allows you to do things that many non OOP languages do not.
Whenever you create a "clickable" item, like a Button, if you want to have your program respond, you must have something "listen" to it. This is known as a Listener. In your case, you are looking for an OnClickListener. The OnClickListener does not have to be a part of the Activity necessarily. It just has to be a class that implements View.OnClickListener. Then, you have tell the setOnClickListener() method of the Button who its listener is. The following example shows what is necessary without your declaration in XML (but it is important).
class Menu extends Activity implements View.OnClickListener
{
public void onCreate(Bundle icicle)
{ setContentView(R.layout.main);
Button btn = (Button)findViewById(R.id.BUTTON_ID_AS_DEFINED_BY_YOUR_XML);
btn.setOnClickListener(this);
}
public void onClick(View view)
{ int id = view.getId();
if (id == R.id.BUTTON_ID_AS_DEFINED_BY_YOUR_XML)
updateLayout()//Do your Click event here
}
public void updateLayout()
{ //updateLayout code...
}
}
Something that needs to be noted is the OnClick() above. Every OnClickListener must use the same signature as theOnClick() That means itmust have the same return and same arguments even if it has a different name. For what you are trying to do (in XML), you have set your android:OnClick to updateLayout. This means that `updateLayout() must be declared as follows:
public void updateLayout(View view)
Now, getting the update method to actually work: While you provide your code, we don't actually know what errors you are getting. It is always much easier to solve a problem if we have a copy of the Logcat output that includes the error you are receiving. Once, we have that we can target your error specifically and I can edit my answer to include what you may additionally need.
FuzzicalLogic
I just start to use robotium. The demo can be run without any problem, but when I wrote first test script by using EditText and Button, problems occured. My environment is android 2.1 and the script is quite simple, just input username and psw, then click sumbit button to login.
The script is as follows:
package com.tpc.test;
import com.tpc.login.Login;
import com.jayway.android.robotium.solo.Solo;
import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.Smoke;
public class LoginTest extends ActivityInstrumentationTestCase2<Login>{
private Solo solo;
public LoginTest() {
super("com.tpc", Login.class);
}
public void setUp() throws Exception {
solo = new Solo(getInstrumentation(), getActivity());
}
#Smoke
public void testApp() throws Exception {
String appName = solo.getCurrentActivity().getClass().getSimpleName();
System.out.println(appName);
solo.getButton(0).getClass().getSimpleName();
solo.assertCurrentActivity("Expected login activity", appName);
System.out.println(solo.getButton(0).getText());//can get the text of button
solo.enterText(0, "name"); //input name to the 1st EditText is OK
solo.enterText(1, "psw"); // Actually inout psw after name to the 1st EditText
solo.clickOnButton(0); //Expect click the 1st button.Actually click the 1st EditText
//assert of sample, not been modified
boolean expected = true;
boolean actual = solo.searchText("Note 1") && solo.searchText("Note 2");
assertEquals("Note 1 and/or Note 2 are not found", false, actual);
}
#Override
public void tearDown() throws Exception {
try {
solo.finalize();
} catch (Throwable e) {
e.printStackTrace();
}
getActivity().finish();
super.tearDown();
}
}
One problem is both name and psw is filled in the first EditText,the other is solo.clickOnButton(0); click the first EditText, NOT the first Button. I also tried to use the text name of the Button, but the result was the same. It seems all the operations been put to the first EditText. I wanna what's the problem. Any suggestion?thanks
I have had a look at the application that you want to test and the problem is that you do not state that it supports high density screens. That gives Robotium problems as you are using it on a high density emulator/device.
You need to add the following tag in the AndroidManifest.xml:
<supports-screens android:anyDensity="true"/>
If you add that tag to your AndroidManifest.xml then it will work.
Hope you are taking the enter text as a array.. 0 and 1..
But hope you didn't initialize the array
import java.util.Arraylist;
Hope it will work if you initialize the arraylist. Have a try.
You could try to add this tag to your AndroidManifest.xml:
<uses-sdk android:targetSdkVersion="7"/> where 7 means Android 2.1.
If that does not work then please post this on the robotium developers page and I will have a look at it.
http://groups.google.com/group/robotium-developers
Sincerely,
Renas
I also had this issue and i couldn’t find a solution with robotium. Then i move to the android instrumentation provided with the SDK. What i have done is mentioned below. This worked without any issues for me. Here it is ..
First define a private variable for the button as a member variable
private Button msButton;
Then get the button instance with in the setup method.
mButton = (Button) solo.getCurrentActivity().findViewById(
com.marakana.android.simple_intent.R.id.sendButton);
Then call the button click with in the UI thread in the test method as mentioned below.
//Test button method
public void testButtonClick() {
//Get the current activity and request to run onUI thread
solo.getCurrentActivity().runOnUiThread(new Runnable() {
public void run() {
//Request focus for the button
mButton.requestFocus();
}
});
//Send the button click event
this.sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
}
That’s it .. Now you can test your button with other Robotium features.