I have voice commands in my Google Glass app working, with a R.id.add_item and R.id.remove_item for a list-type app. However, I would like to be able to let the user say, "Add Item, Apple". I cannot find any information on how to do this.
My main.xml file looks like this:
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/add_item"
android:title="Add Item" />
<item android:id="#+id/remove_item"
android:title="Remove Item" />
</menu>
And my onMenuItemSelected is
#Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
if (featureId == WindowUtils.FEATURE_VOICE_COMMANDS || featureId == Window.FEATURE_OPTIONS_PANEL) {
switch (item.getItemId()) {
case R.id.add_item:
break;
case R.id.remove_item:
break;
}
return true;
}
return super.onMenuItemSelected(featureId, item);
}
I don't know where I would add this code, or how I would do so. Thanks for your help.
You add onMenuItem to your activity....
I think reading the code again you could see where it fits in the bigger scope.
https://developers.google.com/glass/develop/gdk/voice
You can try here to see a sample app with voice recognition:
https://github.com/RIVeR-Lab/google_glass_driver/tree/master/android/RobotManager/src/com/riverlab/robotmanager
Related
Hi, there
Currently, I'm develop an immersion app to provide a text on screen and user can swipe_right to go another one.
Actually, It adapt from sample immersion pattern called charades(google development site).
My objective is, I want to using voice commands, instead of SWIPE gesture.
for example;
User open the immersion demo, the screen will show first TEXT.
User want to go next TEXT by using voice "GO NEXT".
The screen will show another Text.
Considering this post!
Is there any way to do this?
or any suggestion?
Here, It is my solution. Hope this might helped someone who looking for.
I used Contextual voice commands to provide 'Next', 'Save' and 'Exit' commands for an user. you can go to this document from google dev site to see the ideas of doing this.
I have my layout activity to show some TEXT, so I put this code structure. in my layout activity
//contextual voice command
import com.google.android.glass.view.WindowUtils;
import android.view.Menu;
import android.view.MenuItem;
#Override
public boolean onCreatePanelMenu(int featureId, Menu menu) {
if (featureId == WindowUtils.FEATURE_VOICE_COMMANDS) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
// Pass through to super to setup touch menu.
return super.onCreatePanelMenu(featureId, menu);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
if (featureId == WindowUtils.FEATURE_VOICE_COMMANDS) {
switch (item.getItemId()) {
case R.id.save_menu_item:
Log.d("Contextual", "go save checks");
break;
case R.id.next_menu_item:
Log.d("Contextual", "go next checks");
break;
case R.id.exit_menu_item:
Log.d("Contextual", "go exit checks");
break;
default:
return true;
}
return true;
}
return super.onMenuItemSelected(featureId, item);
}
Don't forget to declare this line getWindow().requestFeature(WindowUtils.FEATURE_VOICE_COMMANDS); to your onCreate(); before your setContentView().
Next thing, I created 'menu folder' and main.xml inside its to provide my item selection. Like this
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/next_menu_item"
android:title="#string/next">
</item>
<item
android:id="#+id/save_menu_item"
android:title="#string/save_this">
</item>
<item
android:id="#+id/exit_menu_item"
android:title="#string/exit">
</item>
and my strings.xml file.
<resources>
<string name="next">next</string>
<string name="save_this">save</string>
<string name="exit">exit</string>
</resources>
put this line
<uses-permission android:name="com.google.android.glass.permission.DEVELOPMENT" />
to your AndroidMenifest.xml.
and it works fine for me !
I've got an options menu that allows the user to change map type on google maps. That works fine, but I'd like to offer the functionality to change the markers presently showing which I control with a boolean value. Here is my current code.
#Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.map_styles_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
super.onOptionsItemSelected(item);
switch(item.getItemId()) {
case R.id.normal_map:
mapType=GoogleMap.MAP_TYPE_NORMAL;
break;
case R.id.satellite_map:
mapType=GoogleMap.MAP_TYPE_SATELLITE;
break;
case R.id.terrain_map:
mapType=GoogleMap.MAP_TYPE_TERRAIN;
break;
case R.id.hybrid_map:
mapType=GoogleMap.MAP_TYPE_HYBRID;
break;
}
googleMap.setMapType(mapType);
return true;
}
I guess what I'd like to do is create another case statement like so
case R.id.present:
mapChange=true;
break;
case R.id.past:
mapChange=false;
break;
I use items in the menu XML file to represent the maps, could I use items for changing a boolean too?
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/map_types"
android:title="Menu"
android:showAsAction="always">
<menu>
<item android:id="#+id/normal_map"
android:title="Mormal map"/>
<item android:id="#+id/satellite_map"
android:title="Satellite map"/>
<item android:id="#+id/terrain_map"
android:title="Terrain map"/>
<item android:id="#+id/hybrid_map"
android:title="Hybrid map"/>
</menu>
</item>
So I would add an item below the above like
<item android:id="#+id/past"
android:title="Change to past markers"/>
First of all I would suggest to try everything that you think can work. And if still not finding an answer then post on SO.
With the explanation that you have mentioned and with my limited knowledge I conclude that you need one option in your option menu which will toggle between your markers screen and other markers screen.
So add the option in your xml:
<item android:id="#+id/past"
android:title="Change to past markers"/>
then in your java file add this code:
case R.id.past:
if(mapChange){
mapChange=false;
//your code to show other markers
}else{
mapChange=true;
//your code to show same markers etc
}
break;
Well if you want you can just create another method named "changeState()" and put your suggested switch case in that method
Private void changeState() {
Switch(VARIABLE-HERE)
{
case R.id.present:
mapChange=true;
break;
case R.id.past:
mapChange=false;
break;
}
}
And call it after.
googleMap.setMapType(mapType);
When I'm on Android App and i click on menu button at mobile device, settings menu appear. How i can add new item Facebook like at this setting menu ?
Maybe this is what you are looking for?
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/like"
android:title="#string/menu_facebook_like"
android:icon="#drawable/ic_menu_like"
android:showAsAction="ifRoom" />
</menu>
Then on your code:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle menu item selection
switch (item.getItemId()) {
case android.R.id.like:
// Do what you want when "like" is pressed
return true;
default:
return super.onOptionsItemSelected(item);
}
}
Of course you have to find a "like" icon (ask to Google) and resize it for the ActionBar/Menu.
I am looking for a way to have the options menu persist on screen as soon as the activity is opened without pressing the menu button of the simulator and it should be there until one of the options in the menu is pressed
Currently I have made an option menu like this:
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/icon"
android:icon="#drawable/icon" />
<item android:id="#+id/text"
android:title="Text" />
<item android:id="#+id/icontext"
android:title="Icon and text"
android:icon="#drawable/icon" />
</menu>
And my code is:
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId())
{
case R.id.icon:
break;
case R.id.text:
break;
case R.id.icontext:
break;
}
return true;
}
Please suggest changes in my code.
Activity‘s option menu can be programatically opened and closed with the openOptionsMenu and closeOptionsMenu respectively
#Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
openOptionsMenu();
}
and to close:
closeOptionsMenu();
for lvls that do not support onAttachedToWindow could be used delayed execution(Not the best way):
new Handler().postDelayed(new Runnable() {
public void run() {
openOptionsMenu();
}
}, 1000);
I haven't tried this one, but you could look at openOptionsMenu.
Then after it's open you should try to intercept the menu button press and the back button press (as you would close the menu otherwise) and only disable this once one of the option items has been selected.
With this said, this all looks like a hack, so maybe you should consider a different solution for what you want to achieve.
I have the following menu layout in my Android app:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/item1"
android:titleCondensed="Options"
android:title="Highlight Options"
android:icon="#android:drawable/ic_menu_preferences" />
<item android:id="#+id/item2"
android:titleCondensed="Persist"
android:title="Persist"
android:icon="#android:drawable/ic_menu_preferences"
android:checkable="true" />
</menu>
My problem is that the second menu item doesn't appear to be "checkable" when I run my app in the Android emulator. There should be a green tick about the item, right? To indicate that its checkable.
Am I doing something wrong?
Layout looks right. But you must check and uncheck menu item in code.
From the documentation:
When a checkable item is selected, the system calls your respective item-selected callback method (such as onOptionsItemSelected()). It is here that you must set the state of the checkbox, because a checkbox or radio button does not change its state automatically. You can query the current state of the item (as it was before the user selected it) with isChecked() and then set the checked state with setChecked().
Wrap the items in a group element, like this:
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="all">
<item android:id="#+id/item1"
android:titleCondensed="Options"
android:title="Highlight Options"
android:icon="#android:drawable/ic_menu_preferences">
</item>
<item android:id="#+id/item2"
android:titleCondensed="Persist"
android:title="Persist"
android:icon="#android:drawable/ic_menu_preferences"
android:checkable="true">
</item>
</group>
</menu>
From the Android docs:
The android:checkableBehavior attribute accepts either:
single - Only one item from the group can be checked (radio buttons)
all - All items can be checked (checkboxes)
none - No items are checkable
You can create a checkable menu item by setting the actionViewClass to a checkable widget like android.widget.CheckBox
res/menu/menu_with_checkable_menu_item.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/action_favorite"
android:checkable="true"
android:title="#string/action_favorite"
app:actionViewClass="android.widget.CheckBox"
app:showAsAction="ifRoom|withText" />
</menu>
And you can can even style it to be a checkable star if you set actionLayout to a layout with a styled android.widget.CheckBox
res/layout
/action_layout_styled_checkbox.xml
<CheckBox xmlns:android="http://schemas.android.com/apk/res/android"
style="?android:attr/starStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
res/menu/menu_with_checkable_star_menu_item.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/action_favorites"
android:checkable="true"
android:title="#string/action_favorites"
app:actionLayout="#layout/action_layout_styled_checkbox"
app:showAsAction="ifRoom|withText" />
</menu>
To set the value
menuItem.setChecked(true/false);
To get the value
menuItem.isChecked()
Cast MenuItem to CheckBox
CheckBox checkBox= (CheckBox) menuItem.getActionView();
I've found that the best solution was to just use the onOptionsItemSelected() method as of my current API (27-28).
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
//Copy from here...
int itemId = item.getItemId();
if(item.isChecked())
{
if(R.id.edit_tile_checkbox == itemId) //Individual checkbox logic
{ /*TODO unchecked Action*/}
item.setChecked(false); //Toggles checkbox state.
}
else
{
if(R.id.edit_tile_checkbox == itemId) //Individual checkbox logic
{/*TODO checked Action*/}
item.setChecked(true); //Toggles checkbox state.
}
//...To here in to your onOptionsItemSelected() method, then make sure your variables are all sweet.
return super.onOptionsItemSelected(item);
}
I spent way to long on here for this answer. and for whatever reason, the answers above didn't help (I'm a returning newbie I probably mucked something up I'm sure).
There could be a better way of doing this so helpful criticism is welcomed.
READ THIS
As has been said the "manual checking" is only the tip of the iceberg. It flashes the menu away so fast the users don't see anything happen and it is very counter intuitive, frustrating, and effectively utter crap. The REAL TASK (therefore) is allowing the check box event to be digested by the users mind.
Good news: this can be done and it does work and this is how you do it. #TouchBoarder had it best so I will copy his code. then develop it.
the idea is to detect if the checkbox is clicked, then (and only if that one is picked) slightly suppress the menu removal, add a timer for 500ms then close the menu, this give the "tick" animation of the checkbox time to run and creates the right "feel"
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/action_favorite"
android:checkable="true"
android:title="#string/action_favorite"
app:actionViewClass="android.widget.CheckBox"
app:showAsAction="ifRoom|withText" />
</menu>
then you make this method as usual, but you make sure you add all this extra bumpf
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the bottom bar and the top bar (weird)
BottomAppBar bottomBar = findViewById(R.id.bottom_app_bar_help);
Menu bottomMenu = bottomBar.getMenu();
getMenuInflater().inflate(R.menu.bottom_nav_menu, bottomMenu);
for (int i = 0; i < bottomMenu.size(); i++) {
bottomMenu.getItem(i).setOnMenuItemClickListener(item -> {
if (item.getItemId()==R.id.action_favorite){
item.setChecked(!item.isChecked());
// Keep the popup menu open
item.setShowAsAction(MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);
item.setActionView(new View(frmMain.this));
item.setOnActionExpandListener(new MenuItem.OnActionExpandListener() {
#Override
public boolean onMenuItemActionExpand(MenuItem item) {
final Handler handler = new Handler();
handler.postDelayed(() -> bottomMenu.close(), 500);
return false;
}
#Override
public boolean onMenuItemActionCollapse(MenuItem item) {
final Handler handler = new Handler();
handler.postDelayed(() -> bottomMenu.close(), 500);
return false;
}
});
return false;
}
else {
return onOptionsItemSelected(item);
}
});
}
return true;
}
the other menu events are here
public boolean onOptionsItemSelected(MenuItem item) {
// Bottom Bar item click
try {
switch (item.getItemId()) {
case R.id.mnuExit:
MenuClick(ClickType.LOGOUT);
return true;
case R.id.mnuList:
MenuClick(ClickType.LIST);
return true;
default:
return super.onOptionsItemSelected(item);
}
} catch (Exception e) {
e.printStackTrace();
}
return super.onOptionsItemSelected(item);
}
Answering because the answers here seem long and convoluted.. I have some exact Kotlin code here
Override your activity at the top and override the function onMenuItemClick, Have a function to handle the button click to open the menu.
Have an array or list which holds the checked value and sets the check when the menu is re-created
Note: This code does not keep the menu open, It only ensures that checked items remain checked.
I noted there are lots of solutions to that on stack overflow, so have a look at them if that's what you desire
class exampleActivity : AppCompatActivity(), PopupMenu.OnMenuItemClickListener {
private var checkChecked = arrayListOf(false,false)
//some code
fun clickBTN(v: View){
val popup = PopupMenu(this,v)
popup.setOnMenuItemClickListener(this)
popup.inflate(R.menu.yourmenufilename)
//assuming you have 2 or more menu items
popup.menu[0].isChecked = checkChecked[0]
popup.menu[1].isChecked = checkChecked[1]
popup.show()
}
override fun onMenuItemClick(item: MenuItem?): Boolean {
when(item?.itemID){
R.id.item0 -> {
item.isChecked = !item.isChecked
checkChecked[0] = item.isChecked
return true
}
R.id.item1 -> {
item.isChecked = !item.isChecked
checkChecked[1] = item.isChecked
return true
}
}
}
of course in XML you should have your Button and Menu setup. An example menu is here
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/item0"
android:title="#string/hi"
android:checkable="true"/>
<item android:id="#+id/item1"
android:title="#string/yo"
android:checkable="true"/>
</menu>
This may be theme dependant but my menu didn't show a checkbox. I found this :
Note: Menu items in the Icon Menu cannot display a checkbox or radio
button. If you choose to make items in the Icon Menu checkable, then
you must personally indicate the state by swapping the icon and/or
text each time the state changes between on and off.
For Adding Menu items Programmatically,
#Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add("Item1").setActionView(R.layout.action_layout_checkbox).setCheckable(true);
return super.onCreateOptionsMenu(menu);
}
res/layout /action_layout_checkbox.xml
<CheckBox xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
I have two items in the menu and set to checkable in menu.xml file like below
<item
android:id="#+id/A"
android:title="A"
app:showAsAction="never"
android:checkable="true"/>
<item
android:id="#+id/B"
android:title="B"
app:showAsAction="never"
android:checkable="true"/>
and logic for the menu checkboxes is below.
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.A:
//logic goes here
if(item.isChecked())
{
//logic is it is checked
item.setChecked(false);
}
else
{
//logic is it is not checked
item.setChecked(true);
}
return true;
case R.id.B:
//logic for second checkbox goes here
if(item.isChecked())
{
//logic is it is checked
item.setChecked(false);
}
else
{
//logic is it is not checked
item.setChecked(true);
}
return true;
default:
return super.onOptionsItemSelected(item);
}