Background
I work on an app that can answer to certain queries (phone number queries, and maybe others).
Google introduced a new feature on Android 6 , called "Google Now On Tap" (AKA "Assist API") , which allows the user to query about things that are shown on the screen (triggered by long-click on home button or by saying something) without the need to type anything.
Google provided a developers tutorial for it, here
The problem
I can't find any code snippet to show how to prepare the app for it.
Only thing that I've noticed is that I can extend from Application class, and add OnProvideAssistDataListener inside , and register to it.
But, it opens a lot of questions about how to do it.
Sadly, because this topic is so new, I can't find almost anything about it, so I'd like to ask the questions here.
The questions
1) Is there any sample or at least a more explained tutorial for this new feature?
2) It is said in the docs:
In most cases, implementing accessibility support will enable the
assistant to obtain the information it needs. This includes providing
android:contentDescription attributes, populating
AccessibilityNodeInfo for custom views, making sure custom ViewGroups
correctly expose their children, and following the best practices
described in “Making Applications Accessible”.
Why and how does it work with the accessibility features of the app? What does it have anything to do with exposing child views (or views at all)? How could it even be about views, if the app doesn't run yet (because the feature is activated on any app, anywhere).
What I think is that this is called only if the foreground app is my app, but if it is this way, how can I actually offer queries that appear for all apps, depending on what the input is?
3) Does the class that extends from Application supposed to implement OnProvideAssistDataListener ? If so, why does it need to register to it? If not, how could it be that Google-Now-On-Tap works with it? It can't just open all apps that have such a classs, and see if they register...
4) The docs have a sample snippet which I didn't understand:
#Override
public void onProvideAssistContent(AssistContent assistContent) {
super.onProvideAssistContent(assistContent);
String structuredJson = new JSONObject()
.put("#type", "MusicRecording")
.put("#id", "example.comhttps://example.com/music/recording")
.put("name", "Album Title")
.toString();
assistContent.setStructuredData(structuredJson);
}
What does the new feature do with each key? Is it used by the app, or Google-Now-On-Tap ? What are my options about it?
Is this where I define if my app can handle the content that the feature suggests me? Is AssistContent supposed to be the input that I look at, and decide if my app can handle it or ignore it?
Related
One can visualize Encapsulation as the method of putting everything
that is required to do the job, inside a capsule and presenting that
capsule to the user. What it means is that by Encapsulation, all the
necessary data and methods are bind together and all the unnecessary
details are hidden to the normal user
Encapsulation may also refer to a mechanism of restricting the direct access to some components of an object, such that users cannot access state values for all of the variables of a particular object.
Above two extracts i have taken from two different places.
Why they mention word user here?
I believe a user is someone who is using the product.Example. For an android app user is someone who is downloading and using the app..He/she only has access the the product functionality and not the code running behind it.So how is encapsulation hiding unnecessary details from user.Instead it's hiding implementation details inside one class from another using private?
"Users" here means other programmers who are going to use your code/API/library.
This is not an uncommon or unusual choice of words. If you want to refer to the users who are downloading and using the app, people usually use the term "end user".
The Situation
I'm writing a timetable-viewing application and the first feature to be implemented is choosing the course for which to view the timetable.
The user chooses the name of their course from a list and is taken to another screen to further specify which year, group etc. of the course they're currently in. The screens to choose your course and edit your course details are as follows:
The Goal
Inspired by the Google I/O 17 talk on Test-Driven Development on Android, what I wish to write is a UI test case to test this feature. Specifically, I want my test to confirm that if the user clicks on one of the course names they will be taken to the 'edit course details' screen and that the course title at the top e.g. 'Accounting and Finance' matches the one that was clicked in the list.
The Problem
The test, using Espresso, for the specific case of choosing the course titled 'Accounting and Finance' and seeing if the correct title shows up on the next screen, would look (roughly) like this:
#Test
public void chooseCourse() {
onView(withId(R.id.rv_course_list))
.perform(RecyclerViewActions.actionOnItemAtPosition(
/*Somehow find position of Accounting and Finance*/,
click())
);
onView(withId(R.id.course_title))
.check(matches(withText("Accounting and Finance")))
.check(matches(isDisplayed()));
}
My problem is that the RecyclerView course list will be populated using results from a HTTP request or a SQLite database at runtime and there is no way of knowing beforehand whether the list will contain 'Accounting and Finance' or something else (I don't want the test to fail just because a specific course isn't in the list when the application runs).
Taking this into consideration I cannot hard-code the course name into the test. Please note that I'm not trying to write a unit test where I would just mock the dependency of obtaining the course list to ensure that 'Accounting and Finance' is in the list (and would probably just isolate the ChooseCourseActivity class, capturing its Intents).
In the video I linked to above, the presenter talks us through a UI test of the add-note feature of a notes application where the test is as follows:
Click on the 'add note' button
Enter title and description of the note
Click on the 'save note' button
Verify that a new note with the details from step 2 is contained in the list
In that scenario hard-coding the text (title and description) used to find the views works great because the code in the test determines the contents of the view i.e. the note in the notes list. In my case, the contents of the view will be determined by a HTTP response or db query
The Question
How do I write an adequate UI test for the choose-course feature before implementing it?
Is the method used in the video to test the notes app simply not applicable to my feature (because I cannot hard-code the course title that is to be chosen from the list)?
Am I just misunderstanding UI testing and should be mocking dependencies (even though the speaker in the video did not)?
Edit: The best solution to this problem seems to be what is called 'hermetic testing' and this blog describes how to apply it to android UI.
You can test this in a few different ways and I've used a combination of all of them within my apps.
1) You can mock your network/database layer as you suggested.
2) You can make a call to your API in your test to get your 'expected' data set and then verify that it appears correctly in your UI.
3) You can Stub your networking layer to allow you to inject known data and not rely on your networking endpoint. Retrofit in particular makes it very easy to do this.
4) You can test against live endpoints using a known test dataset that won't change frequently.
I tend to use Espresso both for UI level tests and full blown regression tests. In the UI level tests, I stub out the networking/on device persistence layer and just test the client side with datasets that I inject during the test. For regression tests, I care about testing the integration with my API and for those I use a testing account that has known unchanging data.
I have an Android app which is represented by the following picture:
The main activity is a sort of "main menu" composed of buttons. Each button starts a sub-activity. All is working fine so far, this is not the purpose of this question.
What I would like to do is adding some features in time. For example, I add a new feature/activity to my project and I would like my main activity to become like so:
So my main activity would have more buttons now. Each new button should act as described below:
If the feature is free, simply act as a normal button (like the ones that were provided with the published activity)
If the feature must be bought to be used, the button (once clicked) would show a "temporary" activity which will provide a video presentation of the new feature and the option to buy it or not.
If the user does not buy the new feature, it should remain the same as long as the new feature is not bought (so the button will always show the "temporary" activity).
If the user buys the new feature, the button should now launch the new feature instead of the "temporary" activity.
So my questions are:
Is it possible? (I guess yes but it doesn't hurt to ask...)
How can I implement this as easilly as possible (I took a look at the in-app billing feature and example, but it's a little bit confusing as my app does not work exactly the same, due to the "temporary" activity thing...)
If you have any idea/suggestion that could help, I would be glad to hear it!
There is no need to use any in-app libraries. Just use some flags to indicate what feature is free and what is payable. To check what feature was bought, just use standard Google in-app methods from example app and here is in-app implementation guide with implementation details.
Applications of these two ideas could include enabling the player to see his or her progress in earlier games within the latest sequel, being able to keep the same character/progress across games, etc. etc.
While the best solution is likely having the player create an account they use across games, I'd like to avoid that if I can (both because players are already logging into Google Play Games, and because I currently do not have access to server infrastructure to handle doing that). Is there any other official/popular mechanism for passing data between games, or is the account route the best bet?
I believe that this is what you are looking for, Interacting with Other Apps especially the Sharing Simple Data and Sharing File section. You may also refer to this documentation for Receiving Simple Data from Other Apps which suggests that you will need an ACTION_SEND intent filter.
Update Your Manifest
Intent filters inform the system what intents an application component is willing to accept. Similar to how you constructed an intent with action ACTION_SEND in the Sending Simple Data to Other Apps lesson, you create intent filters in order to be able to receive intents with this action. You define an intent filter in your manifest, using the <intent-filter> element.
Handle the Incoming Content
To handle the content delivered by an Intent, start by calling getIntent() to get Intent object. Once you have the object, you can examine its contents to determine what to do next. Keep in mind that if this activity can be started from other parts of the system, such as the launcher, then you will need to take this into consideration when examining the intent.
I think this would be a good place to start on how to pass data from one app to another. You will also need to make changes in your current implementation both in your existingt and new app for this to be possible.
The other solution to this is to have all the games share a common Play Game Console configuration. You can have multiple packageIds point to the same appId, so they see the same list of achievements, leaderboards, etc.
Depending on your specific requirements, you could simply change the descriptions of the items to describe which game they are for, or implement custom UIs to display the lists.
I wish to show my other apps under "More Apps" section of while exiting.
What is the the best way to do it ?
Is there is any common library to add my app icon and link of my app. so that It can be shown at the time of interest. It would be great if it is scrollable
Thanks is Advance !
Well since these are your apps you can simply hard-code the icons into a RecyclerView or ListView along with a link leading to Google Play. This really doesn't require a third-party liubrary as it can easily be done by yourself.
If you really want to allow for future expansiveness, you could use a cloud platform like parse where you store the names of different apps as parse objects along with a link and an image (logo). Then you could write a custom adapter for your list which takes the parse objects from your cloud, and populates itself with the logo,link,title,etc.
This is really a matter of comfort and preference rather than finding a library to do this for you. If you need help, feel free to ask, and good luck!
You can show a 'Dialog' asking if the user cares to check some of your other apps with two available options: 'yes' and 'no'. If the user chooses
'no', close the dialog, if he chooses 'yes' - redirect him/her to the following url:
https://play.google.com/store/apps/developer?id={Your-Google-Account-Name}
This link will be opened either in the browser or in the Google Play app, whichever your user prefers, and it'll show him/her the list of all your apps.
You can try overriding finish() (Documentation) method inside your Activity. If you're using multiple Activities, consider creating a base Activity so that you don't have to implement this in each Activity.
That said, please consider not doing this. As a user, I'd be super annoyed if I'm trying to close your app and you're not letting me do it. That'd be instant uninstallation from my side. Never annoy your users. Respect their experience.