0

I am trying to test my activity which has a button to go to a People application with ActivityInstrumentationTestCase2. But the problem is People application starts edit activity in another task, and clearly I don't have access there. So, what to do? How to send signals to People application?

My intent is:

Intent intent = new Intent(Intent.ACTION_INSERT);
intent.setType(ContactsContract.Contacts.CONTENT_TYPE);

intent.putExtra(ContactsContract.Intents.Insert.NAME, "");
intent.putExtra(ContactsContract.Intents.Insert.PHONE, "");
Vladimir Ivanov
  • 42,730
  • 18
  • 77
  • 103
  • Can you show some code for your Intents? I think that you may have a relative class issue (as opposed to verbose package naming of your activities...) – jesses.co.tt Sep 07 '15 at 07:27
  • I have updated the question. I don't use explicit intent for obvious reasons. – Vladimir Ivanov Sep 07 '15 at 07:33
  • http://stackoverflow.com/questions/14278587/insert-a-new-contact-intent – cyanide Sep 07 '15 at 07:48
  • cyanide, do you mean I should insert a contact programatically? Or should I prefill the intent and then go back to save the contact? – Vladimir Ivanov Sep 07 '15 at 07:50
  • I guess, you prefill the Intent, then call the system activity which saves this contact and returns its URI through onActivityResult. – cyanide Sep 07 '15 at 07:57
  • cyanide The problem is I can not return from this system activity. mSolo.goBack() doesn't work and sending key events requires permission. – Vladimir Ivanov Sep 07 '15 at 10:12

1 Answers1

0

Well, I figured it out, pretty sure other developers will find it useful. First of all, to enable testing interaction with People application you can prefill the contact data with related Intent fields:

public static void addAsContactConfirmed(final Context context, final Person person) {

Intent intent = new Intent(Intent.ACTION_INSERT);
intent.setType(ContactsContract.Contacts.CONTENT_TYPE);

intent.putExtra(ContactsContract.Intents.Insert.NAME, person.name);
intent.putExtra(ContactsContract.Intents.Insert.PHONE, person.mobile);
intent.putExtra(ContactsContract.Intents.Insert.EMAIL, person.email);

intent.putExtra("finishActivityOnSaveCompleted", true); // this line enables instant return People to our app
context.startActivity(intent);

}

Then you need to press back button, and this is the tricky part:

  1. You can't just finish(), because it is not your activity, and even not the same task
  2. You can't access any views of People app by the same reason
  3. You cry a lot, because you don't know, what to do

But here I am with the solution. You need to use UiAutomation which can be obtained from instrumentation by calling final UiAutomation uiAutomation = getInstrumentation().getUiAutomation();.

Then you can't send any key events to another application, because it requires INJECT_EVENTS permission, which needs system signature, which your application apparently lacks :)

So, call this one:

uiAutomation.performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK);

It does not require any permissions and just work across application. Be sure you run your test above Android 4.3.

Additional link.

Vladimir Ivanov
  • 42,730
  • 18
  • 77
  • 103