Android Test Framework performClick() not starting Activity - android

I have an ActivityInstrumentationTestCase2 with a test executing Button.click(). The Button should start an other Activity to do some work.
I think Button.performClick() is performed correctly, but the test is finishing before the other Activity is executed.
#UiThreadTest
public void test() {
Intent i = new Intent(this.myActivity, MyActivity.class);
myActivity.startActivity(i);
Button button = (Button) myActivity.findViewById(R.id.button);
button.performClick();
}
I tried the following which worked but i think this is rather a work-around than a good solution.
public void test() {
Intent i = new Intent(this.myActivity, MyActivity.class);
myActivity.startActivity(i);
Button button = (Button) myActivity.findViewById(R.id.button);
button.performClick();
try {
Thread.sleep(50000);
} catch (InterruptedException e) {
Log.e("MyTest", e.getMessage());
}
}
Isn´t there a better way?

This is my final solution:
public void test() {
Instrumentation instrumentation = getInstrumentation();
// Prepare a monitor for your activity
Instrumentation.ActivityMonitor monitor = instrumentation.addMonitor(MyActivity.class.getName(), null, false);
// Start your activity manually
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setClassName(instrumentation.getTargetContext(), MyActivity.class.getName());
instrumentation.startActivitySync(intent);
Activity myActivity = getInstrumentation().waitForMonitor(monitor);
Button upSend = (Button) myActivity.findViewById(R.id.button);
upSend.performClick();
Log.d("MyTest", "button clicked");
//wait for SecondActivity to start (called by MyActivity)
monitor = instrumentation.addMonitor(SecondActivity.class.getName(), null, false);
Activity secondActivity = getInstrumentation().waitForMonitor(monitor);
int count = 0;
//wait until SecondActivity is finishing
while(!secondActivity.isFinishing()) {
Log.d("MyTest", "waiting - " + ++count);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Log.e("MyTest",e.getMessage());
}
}
}
Thx again to Erik; now the second activity gets started by button and test is waiting for it to finish.

Related

Pause CountDownTimer as long as the app is not visible

I have a problem with my app. I have created a button called "browse". By clicking it, the button performs a google search and the app is no longer visible. Additionally, I have a countdowntimer. Now I want that the countdowntimer pauses as long as the app is not visible.
Do you have any ideas?
I have already tried the methods onPause(); and onResume(); but its not properly working.
browse.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
String escapedQuery = null;
resume = true;
countDownTimer.cancel(); //I have no idea where to resume
try {
escapedQuery = URLEncoder.encode(begriff2, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
Uri uri = Uri.parse("http://www.google.com/#q=" + escapedQuery);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
}
});
You can cancel it ,in onPause() , like this :
#Override
public void onPause() {
countDownTimer.cancel();
super.onPause();
}

My app is freezing after running for 20 min

I have an application which runs a stack of activities-fragment; A > a1:fragment > B > C, automatically. Activity A and its fragment is the android.hardware.camera2, which I have added to my app as a library. In order to run the stack of activities automatically I have a handler in activity A for photo capture and a handler in activity C which launches activity A:
Pass from activity A to fragment a:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_A);
if (null == savedInstanceState) {
getSupportFragmentManager().beginTransaction().replace(R.id.container, a.newInstance()).commit();
}
final FragmentManager fragmentManager = getFragmentManager();
fragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
}
Handler for photo capture and pass from fragment a to activity B:
private final CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {
#Override
public void onOpened(#NonNull CameraDevice cameraDevice) {
mCameraOpenCloseLock.release();
mCameraDevice = cameraDevice;
createCameraPreviewSession();
handler.postDelayed(new Runnable() {
#Override
public void run() {
btn.callOnClick();
}
}, 5000);
}
#Override
public void run() {
ByteBuffer buffer = mImage.getPlanes()[0].getBuffer();
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);
FileOutputStream output = null;
try {
output = new FileOutputStream(mFile);
output.write(bytes);
} catch (IOException e) {
e.printStackTrace();
} finally {
mImage.close();
selectedPhotoPath2 = Uri.fromFile(mFile);
Intent launchIntent = new Intent(getActivity().getBaseContext(), B.class);
launchIntent.putExtra("uriFile2", selectedPhotoPath2);
getActivity().startActivity(launchIntent);
getActivity().finish();
if (null != output) {
try {
output.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
Pass from activity B to activity C:
String packageName = this.getPackageName();
Intent launchIntent2 = this.getPackageManager().getLaunchIntentForPackage(packageName);
try {
launchIntent2 = new Intent(this,Class.forName("com.example.ediamanti.imageprocessing.activities.C"));
launchIntent2.putExtra("uriFile3", path);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
startActivity(launchIntent2);
finish();
Pass from activity C back to A:
final Handler handler2 = new Handler(Looper.getMainLooper());
runnable = new Runnable() {
#Override
public void run() {
Intent intent = new Intent(C.this, A.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
finish();
}
};
handler2.postDelayed(runnable, 1000);
My code is working fine but it freezes on activity A after 20 min of running. I would like to have the app running for more than an hour. When the activity freezes, no error message appears in the Logcat, while I can go back to the main menu of the application, so the activity freezes but the app is not crashing.
I have tried different approaches to solve the issue:
Use of different combination of FLAGS in activity C (CLEAR_TOP, NEW_TASK etc.) to clear the back stack history.
Remove bundles when passing intents to avoid exceeding bundle transaction limit.
Change the logger size per log buffer of the mobile device from 256KB to 16MB.
Vary handlers´waiting time.
but none of them seems to be the solution to my problem.
Does anyone have any idea of how this could be solved or any suggestion of which steps I could follow to search for the bug?Thanks!
Android monitor main thread:
enter image description here

How to stop a thread onClick with a boolean?

I am trying to find a way to skip a flash screen by clicking on the screen of the activity. This is what I came to and it works. The problem is that after I click and the new activity is called, the boolean false default if runs again and the intent is called twice. What am I doing wrong?
RelativeLayout OnClickSkipScreen = (RelativeLayout)findViewById(R.id.SplashScreenView);
OnClickSkipScreen.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
OnClickSkip = true;
/*Loading.interrupt();
Intent SplashScreen = new Intent(SplashScreen.this, HomeScreen.class);
startActivity(SplashScreen);
overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
finish();*/
}
});
Thread Loading = new Thread() {
#Override
public void run() {
if (!OnClickSkip) {
try {
sleep(2573);
Intent SplashScreen = new Intent(SplashScreen.this, HomeScreen.class);
startActivity(SplashScreen);
overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
} catch (Exception e) {
e.printStackTrace();
} finally {
finish();
}
} else if (OnClickSkip) {
try {
Intent SplashScreen = new Intent(SplashScreen.this, HomeScreen.class);
startActivity(SplashScreen);
overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
} catch (Exception e) {
e.printStackTrace();
} finally {
finish();
}
}
}
};
Loading.start();
}
use SharedPreference. Then think is whenever your class loads up it loads your boolean to its initial status which is false. so you will only meet one condition,all the time, which is the condition you are meeting now.
When i say persist, i mean you need to save your boolean state so as you can load it up from storage and check,with this your boolean will not be dependent on the initial state which is always false
so in your oncreate it could be this
SharedPreference sp = getPreference(0);
boolean OnClickSkip = sp.getBoolean("onclick",false);
now you can continue; if you want to save your boolean state
Editor e = sp.edit();
e.putBoolean("onclick",onClickSkip);
e.commit();
now continue to your codes

Need help killing the splash event so app doesnt exit to it

I have created a splash event and have it set to sleep for 3secs. Everything works fine but when you go to exit the application it takes you back to the splash. Is there a way to kill this with the code that I have or do I need to write this in a different manner.
public class splash extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
Thread timer = new Thread(){
public void run(){
try{
sleep(3000);
} catch (InterruptedException e){
e.printStackTrace();
}finally{
Intent openApp = new Intent("com.iqmobile.chris.IQMOBILEACTIVITY");
startActivity(openApp);
}
}
};
timer.start();
}
}
splash.this.finish(); after you start startActivity(openApp);
Intent openApp = new Intent("com.iqmobile.chris.IQMOBILEACTIVITY");
startActivity(openApp);
splash.this.finish();
Second Solution
in AndroidManifest file
<activity android:noHistory="true"
android:name=".splash" />
add finsh(); in code as :
Intent openApp = new Intent("com.iqmobile.chris.IQMOBILEACTIVITY");
startActivity(openApp);
splash.this.finsh();
mSplashThread = new Thread() {
#Override
public void run() {
try {
synchronized (this) {
wait(3000);
}
} catch (InterruptedException ex) {
}
finish();
Intent intent = new Intent();
intent.setClass(FirstActivity.this,
SecondActivity.class);
startActivity(intent);
}
};
mSplashThread.start();
}

Can't start an activity in application onCreate

I am trying to start an activity after n seconds with a handler. The application was crashing on the startActivity call, so I put the handler code in my application's onCreate, and it is still crashing (which makes me think that the error comes from me not using startActivity well) :
#Override
public void onCreate(){
String roomName = this.getSettingValue(R.string.PREFERENCES_ROOM_NAME, "");
Room room;
try {
room = this.getRoomWithName(roomName);
} catch (ReservatorException ex) {
Toast err = Toast.makeText(this, ex.getMessage(),
Toast.LENGTH_LONG);
err.show();
return;
}
Intent i = new Intent(this, RoomActivity.class);
i.putExtra("room", room);
this.startActivity(i);
}
Strange thing is that this work when called from a view, by using exactly the same code, but different context :
Intent i = new Intent(getContext(), RoomActivity.class);
// ...
I am pretty new to Android ... so there may be information missing in that question, or I might even be trying to do something completely stupid who knows ?
EDIT
Link to the stacktrace : http://pastebin.com/vh2QC3xz
EDIT2
Here is the handler version of my code (so what I am trying to do in the end) :
public class ReservatorApplication extends Application {
private GoToFavouriteRoom goToFavouriteRoomRunable;
class GoToFavouriteRoom implements Runnable {
ReservatorApplication app;
public GoToFavouriteRoom(ReservatorApplication anApp){
app = anApp;
}
#Override
public void run() {
String roomName = app.getSettingValue(R.string.PREFERENCES_ROOM_NAME, "");
Room room;
try {
room = app.getDataProxy().getRoomWithName(roomName);
} catch (ReservatorException ex) {
Toast err = Toast.makeText(app, ex.getMessage(),
Toast.LENGTH_LONG);
err.show();
return;
}
RoomActivity.startWith(app, room);
}
}
private final ReservatorAppHandler handler = new ReservatorAppHandler();
class ReservatorAppHandler extends Handler{
#Override
public void handleMessage(Message msg){
return;
}
}
#Override
public void onCreate(){
String serverAddress = getSettingValue(R.string.PREFERENCES_SERVER_ADDRESS, "mail.futurice.com");// TODO: change to mail.futurice.com before delivery
proxy = new SoapDataProxy(serverAddress);
// proxy = new DummyDataProxy();
proxy = new CachedDataProxy(proxy);
addressBook = new FumAddressBook();
try {
addressBook.prefetchEntries();
} catch (ReservatorException e) {
// TODO: DIE!
}
goToFavouriteRoomRunable = new GoToFavouriteRoom(this);
handler.postDelayed(goToFavouriteRoomRunable, 20000);
}
Ok ... I finally solved my problem, mainly thanks to #Drax
Apparently, you just can't start an activity from an application ... you need an instance of an activity. So :
public class ReservatorApplication extends Application {
#Override
public void onCreate(){
Intent i = new Intent(this, RoomActivity.class);
this.startActivity(i);
}
}
Is just not valid, and causes a RunTimeException ...
As far as crashing is concern when you start activity in handler with "this". it will take handler's context. and when you do getContext() it will take activity context.
Intent i = new Intent(YourActivityName.this, RoomActivity.class);
or
Intent i = new Intent(getBaseContext(), RoomActivity.class);
It`s hard to answer without seeing the stack trace from logcat, but I found that sometimes you need to pass the application context to the a new Intent before starting an Activity.
Try this line:
Intent i = new Intent(getApplicationContext(), RoomActivity.class);

Categories

Resources