Pages

Showing posts with label menus. Show all posts
Showing posts with label menus. Show all posts

Friday, May 6, 2016

Android Menus part 4 Alternative menus

Android offers a third type of menus: Alternative menus which allow multiple applications to use each other. An application menu can contain menu items that point to other applications that deal with a certain data type that is passed from the application by an intent.

This functionality is related to the concept of Content Providers which is in brief the ability of an application to expose its data (stored in a database or a file) by defining a MIME type to it and through a content URI to be accessed by any other application through this URI.

For example if an application name Employees has some data of employees stored within this application context, and another application wants to access this data; then Employees application should declare a content provider  to expose its data, with a MIME type:

vnd.android.cursor.item/mina.android.Employees so any other application can access the employees data by calling the Uri content://employees/All to access all employees or the Uri content://employees/1 to access a single employee instance (for example).

Back to our Alternative menus issue, suppose this Scenario: We have two applications:
  1. Application A: deals with the employees data.
  2. Application B: receives the content Uri of the employees and do some calculations on it.
Now we want to add an alternative menu item in an activity in Application A so that when clicked passes a URI of employees and launches an activity in Application B (that manipulates the employees data according to the URI received).

So to add the alternative menu item in the activity of Application A, we write the following in onCreateOptionsMenu method:
public boolean onCreateOptionsMenu(Menu menu) {

//adds a regular menu item
menu.add("Regular item");
//create the intent with the Uri of the employees content provider
Intent targetIntent=
new Intent(Intent.ACTION_VIEW, Uri.parse("content://employees/All"));
targetIntent.addCategory(Intent.CATEGORY_ALTERNATIVE);
menu.addIntentOptions(Menu.CATEGORY_ALTERNATIVE, //item group
Menu.CATEGORY_ALTERNATIVE, //item id
Menu.CATEGORY_ALTERNATIVE, //item order
this.getComponentName(), //our activity class name
null, //no specific menu items required
targetIntent, // the intent to handle
0, //no flags
null); //Optional array in which to place the menu
//items that were generated for each of
//the specifics that were requested

return true;
}
Heres what we did:
  • Create an intent with the desired action (Intent.ACTION_VIEW) on the specified content provider Uri (content://employees/All).
  • Call addIntentOptions method with the specified parameters.
The above code adds a menu item that launches all possible activities in all applications on the device that can deal with the action Intent.ACTION_VIEW on the Uri content://employees/All.

Now in Application B, if we want it to handle such an intent we have to do the following.

Define an activity in the application and specify in the AndroidManifest.xml file that this activity can handle the requests of the employees content provider like this:
<activity android_name=".ContentProvidersDemo" android_label="@string/app_name">

<intent-filter android_label="Access Employees">
<action android_name="android.intent.action.VIEW" />
<category android_name="android.intent.category.DEFAULT" />
<category android_name="android.intent.category.ALTERNATIVE" />
<data android_mimeType="vnd.android.cursor.item/mina.android.Employees" />
</intent-filter>
</activity>
The above IntentFilter means that this activity will respond t0 any implicit intent from any application with the following parameters:
  1. Action: Intent.ACTION_VIEW.
  2. Category: android.intent.category.ALTERNATIVE.
  3. Data of MIME type:vnd.android.cursor.item/mina.android.Employees.
So in Application A when you press on the menu button, youll see a menu like this:



When you press on the Access Employees menu item, the activity in Application B will be launched.


Read More..

Friday, April 29, 2016

Threading in Android part 1 Handlers

Multi-Threading concept is essential in most platforms. it provides maximum

utilization of the processor. threading is used when the program executes

time consuming processes (such as calling a web service) and to give a

good user experience by unblocking the UI.

Android provides threading techniques to perform time consuming tasks in a

background thread with coordination with the UI thread to update the UI.

Android provides the following methods of threading:
  1. Handlers.
  2. Async. Tasks.
Handlers:
When you create an object from the Handler class, it processes

Messages and Runnable objects associated with the

current thread MessageQueue. the message queue holds the

tasks to be executed in FIFO (First In First Out) mannser. you will need

only ine Handler per activity where the background thread will

communicate with to update the UI.

The Handler is associated with the thread from which its been created

We can communicate with the Handler by two methods:
  1. Messages.
  2. Runnable objects.
In this post we will demonstrate how to use both using a simple example which is

updating the text of a TextView using multiple threads.

Using Messages:

the steps of using a Handler are as follows:
  1. You create a Handler object with an asscociated callback

    method to handle the received messages (it is the method where the UI update

    will be done).
  2. From the background thread you will need to send messages to the

    handler.
Heres the code of our activity:
public class MainActivity extends Activity {
TextView txt;
// our handler
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
//display each item in a single line
txt.setText(txt.getText()+"Item "+System.getProperty("line.separator"));
}
};

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
txt=(TextView)findViewById(R.id.txt);
}

@Override
protected void onStart() {
super.onStart();
// create a new thread
Thread background=new Thread(new Runnable() {

@Override
public void run() {
for(int i=0;i<10;i++)
{
try {
Thread.sleep(1000); b.putString("My Key", "My Value:

"+String.valueOf(i));
// send message to the handler with the current message handler

handler.sendMessage(handler.obtainMessage());
} catch (Exception e) {
Log.v("Error", e.toString());
}
}
}
});

background.start();
}
}
after running the following code the TextView will display the following,

each second a new line is written:

This example is pretty basic, it just sends the same message for a number of

times.
what if we want the message sent to hold data thats changed each time the

message is sent, the answer is to use Message.setData(Bundle bundle)

method by creating a Bundle object and adding the data to it like this:
public class MainActivity extends Activity {
TextView txt;
// our handler
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
// get the bundle and extract data by key
Bundle b = msg.getData();
String key = b.getString("My Key");
txt.setText(txt.getText() + "Item " + key
+System.getProperty("line.separator"));
}
};

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
txt = (TextView) findViewById(R.id.txt);
}

@Override
protected void onStart() {
super.onStart();
// create a new thread
Thread background = new Thread(new Runnable() {

@Override
public void run() {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(1000);
Message msg = new Message();
Bundle b = new Bundle();
b.putString("My Key", "My Value: " + String.valueOf(i));
msg.setData(b);
// send message to the handler with the current message handler
handler.sendMessage(msg);
} catch (Exception e) {
Log.v("Error", e.toString());
}
}
}
});

background.start();
}
}
we put a string to the bundle and send a message with that bundle. in the

handler method we receive the bundle and get the value with the predefined key.
after executing that code the text view would look like this:

Using Runnables:
another way to use Handlers is to pass them a Runnable by using the

Handler.post() method like this:
Runnable r=new Runnable() {

@Override
public void run() {
txt.setText("Runnable");

}
};

handler.post(r);

this will add the Runanble object to the message queue to be executed by

the handler.

Sending Messages in a

timely manner:
we can use handlers to send messages or post runnables at time intervals using

the following methods:

  1. handler.sendEmptyMessageAtTime(int what,long uptimeMillis):sends an
     empty message at a specific time in milli-seconds, can be defined by using the
    SystemClock.uptimeMillis() method to get the time since the device boot
     in milli-seconds and concatinating to it.
  2. handler.sendEmptyMessageDelayed(int what,long delayMillis):sends an
     empty message after a certain amount of time in milli-seconds.
  3. handler.sendMessageAtTime(Message msg,long uptimeMillis).
  4. handler.sendMessageDelayed(Message msg,long delayMillis).
  5. handler.postAtTime(Runnable r,long uptimeMillis).
  6. handler.postAtTime(Runnable r,Object token,long uptimeMillis):posts a
     runnable with an object as a distinguishing token.
  7. handler.postDelayed(Runnable r,long delayMillis).
All the above messages return a boolean indicating whether the message or the

runnable has been placed successfully in the message queue.

Removing Call backs:
if you want to remove a runnable or a message from the message queue, you can

use the following methods:

  1. handler.removeCallbacks(Runnable r).
  2. handler.removeCallbacks(Runnable r,Object token).
  3. handler.removeCallbacksAndMessages(Object token).
  4. handler.removeMessages(int what).
  5. handler.removeMessages(int what,Object object)
Read More..

Monday, April 11, 2016

Calling REST Web Services with Android

Requesting REST web service:   you request REST web services by calling a URL with the parameters. like this
http://example.com/resources/getitems

an example of calling a REST web service:
String callWebErvice(String serviceURL){
// http get client
HttpClient client=new DefaultHttpClient();
HttpGet getRequest=new HttpGet();

try {
// construct a URI object
getRequest.setURI(new URI(serviceURL));
} catch (URISyntaxException e) {
Log.e("URISyntaxException", e.toString());
}

// buffer reader to read the response
BufferedReader in=null;
// the service response
HttpResponse response=null;
try {
// execute the request
response = client.execute(getRequest);
} catch (ClientProtocolException e) {
Log.e("ClientProtocolException", e.toString());
} catch (IOException e) {
Log.e("IO exception", e.toString());
}
try {
in=new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
} catch (IllegalStateException e) {
Log.e("IllegalStateException", e.toString());
} catch (IOException e) {
Log.e("IO exception", e.toString());
}
StringBuffer buff=new StringBuffer("");
String line="";
try {
while((line=in.readLine())!=null)
{
buff.append(line);
}
} catch (IOException e) {
Log.e("IO exception", e.toString());
return e.getMessage();
}


try {
in.close();
} catch (IOException e) {
Log.e("IO exception", e.toString());
}
// response, need to be parsed
return buff.toString();
}
Read More..

Saturday, April 9, 2016

Threading in Android part 2 Async Tasks

In the previous post we saw one way to deal with threads in Android, which is by using Handlers. In this post well see how to use another technique which is using AsyncTask class.

AsyncTask is an abstract class that provides several methods managing the interaction between the UI thread and the background thread. its implementation is by creating a sub class that extends AsyncTask and implementing the different protected methods it provides.

Lets demonstrate how to user AsyncTask by creating a simple activity that has two buttons and a progress bar:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout

android_layout_width="match_parent"
android_layout_height="match_parent"
android_orientation="vertical"
>
<Button
android_id="@+id/btn"
android_layout_width="fill_parent"
android_layout_height="wrap_content"
android_text="Show Progress"
></Button>
<ProgressBar
android_layout_width="fill_parent"
android_layout_height="wrap_content"
android_id="@+id/progress"
style="?android:attr/progressBarStyleHorizontal"
></ProgressBar>
<Button
android_id="@+id/btnCancel"
android_layout_width="fill_parent"
android_layout_height="wrap_content"
android_text="Cancel"
></Button>
</LinearLayout>
Here we have two buttons: one to start progress and the other to stop it.

Creating the AsyncTask sub class:
The first step in implementing AsyncTask is to create a sub class like this:
class ProgressTask extends AsyncTask<Params, Progress, Result>{
}
The AsyncTask declaration has three Varargs parameters which are:
  1. Params: parameter info passed to be used by the AsyncTask.
  2. Progress: the type of progress that the task accomplishes.
  3. The result returned after the AsyncTask finishes.
These parameters are of type Varargs which provide the flexibility to pass dynamic sized arrays as parameters.

In our example our class will be like this:
class ProgressTask extends AsyncTask<Integer, Integer, Void>{
}

The parameter and the progress are of type Integer and the result is Void as our tasks does not return anthing (returns null).
The second step is overriding the protected methods defined by the AsyncTask class that handle the execution life cycle of the AsyncTask.

We have five methods to implement which are:
  1. onPreExecute: the first method called in the AsyncTask, called on the UI thread.
  2. doInBackground: the method that executes the time consuming tasks and publish the task progress, executed in background thread.
  3. onProgressUpdate: method that updates the progress of the AsyncTask, run on the UI thread.
  4. onPostExecute: the final method that gets called after doInBackground finishes, here we can update the UI with the results of the AsyncTask.
  5. onCancelled: gets called if the AsyncTask.cancel() methods is called, terminating the execution of the AsyncTask.

Starting the AsyncTask:
To start the AsyncTask we create an instance of it, then call the execute() method passing the initial parameters like this:
ProgressTask task=new ProgressTask();
// start progress bar with initial progress 10
task.execute(10);
Implementing the AsyncTask:
class ProgressTask extends AsyncTask<Integer, Integer, Void>{

@Override
protected void onPreExecute() {
// initialize the progress bar
// set maximum progress to 100.
progress.setMax(100);

}

@Override
protected void onCancelled() {
// stop the progress
progress.setMax(0);

}

@Override
protected Void doInBackground(Integer... params) {
// get the initial starting value
int start=params[0];
// increment the progress
for(int i=start;i<=100;i+=5){
try {
boolean cancelled=isCancelled();
//if async task is not cancelled, update the progress
if(!cancelled){
publishProgress(i);
SystemClock.sleep(1000);

}

} catch (Exception e) {
Log.e("Error", e.toString());
}

}
return null;
}

@Override
protected void onProgressUpdate(Integer... values) {
// increment progress bar by progress value
progress.setProgress(values[0]);

}

@Override
protected void onPostExecute(Void result) {
// async task finished
Log.v("Progress", "Finished");
}

}

Here are the steps:
  1. onPreExecute() method first gets called initializing the maximum value of the progress bar.
  2. doInBackground(Integer... params) methods gets called by obtaining the initial start value of the progress bar then incrementing the value of the progress bar every second and publishing the progress as long as the async task is not cancelled.
  3. onProgressUpdate(Integer... values) method is called each time progress is published from doInBackground, thus incrementing the progress bar.
  4. onPostExecute(Void result) is called after doInBackground finished execution.
  5. void onCancelled() is called if task.cancel(true) is called from the UI thread. it may interrupt the execution preventing onPostExecute from being executed.

The onClick handler of our buttons is like this:
@Override
public void onClick(View v) {
ProgressTask task=new ProgressTask();
switch(v.getId()){
case R.id.btn:
task.execute(10);
break;
case R.id.btnCancel:
task.cancel(true);
break;
}

}

Read More..

Monday, March 28, 2016

Using Android Preferences

We saw before that we can persist an applications data using SQLite database. Android offers another way to store users data through using preferences.

Android preferences is a key/value entries that store data that can be specific to a certain activity or shared among all activities within the application.
the data are stored in a xml file.

Saving Preferences

We can save preferences in three ways:

  1. Preferences can be retrieved only by a single activity.
  2. Preferences can be shared and retrieved among all activities within the application.
  3. Preferences can be shared and retrieved through all applications on the device.
Saving Activity-level preferences:
to save preferences that are accessed only from a single activity, we do it like this:
SharedPreferences prefs=getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor=prefs.edit();
editor.putString("pref 1", "some text");

editor.commit();

we get a SharedPreferences object by calling getPreferences(int mode) method which takes an integer value as a parameter, the mode value can be one of the following:

  1. Context.MODE_PRIVATE (0): a file creating mode that makes the created file only accessible by applications with the same user ID (access the file from the same application context, will desctribe later).
  2. Context.MODE_WORLD_READABLE (1): file mode makes the file readable from other applications.
  3. Context.MODE_WORLD_WRITEABLE (2): file mode allows other applications to write to the file.
then we get an instance of SharedPreferences.Editor and write the preference value with editor.putString(String key, String value) method.
shared preferences allows you to insert preferences using the following methods:
  1. editor.putBoolean(String key, boolean value).
  2. editor.putFloat(String key,float value).
  3. editor.putInt(String key, int value).
  4. editor.putLong(String key, long value)
  5. editor.putString(String key, String value)
then we call edit.commit() to save the preferences to the file. commit returns a boolean indicating the result of saving, true if successful and false if failed.

Reading preferences values:
To read preferences values:
SharedPreferences prefs=getPreferences(Context.MODE_PRIVATE);
String val=prefs.getString("pref 1", "some text");
we use sharedpreferences.getString(String key, String defaultValue) (or get boolean/float/int) to return the value stored with a specific key or defaultValue if not found.

Saving Application-level preferences:
to save preferences that can be retrieved from all activities in the application we do it like this:
SharedPreferences prefs= getSharedPreferences("demopref", Context.MODE_WORLD_READABLE);
SharedPreferences.Editor editor=prefs.edit();
editor.putString("demostring", "hello");
editor.commit();

same as the code above, but the difference is that we give our preferences file a name (demopref in this case) so that other activities can reference that preferences file.
Sharing preferences across applications:


We can store preferences in one application and read them in another application, this is done reading the preferences file by loading them through the first applications context.

lets assume we have two applications:

  1. Application 1 with package name "com.mina.prefdemo".
  2. Application2 with package name "com.mina.demoapp".
If application1 creates a preferences file with the name "demopref" and inserts a String preference with the key/value "demostring/hello".

now we access this file and value from application 2 like this:
Context con;
try {
con = createPackageContext("com.minasamy.prefdemo", 0);
SharedPreferences pref=con.getSharedPreferences("demopref", Context.MODE_PRIVATE);
String x=pref.getString("demostring", "not found");
txt.setText(x);
} catch (NameNotFoundException e) {
Log.e(Tag, e.toString());
}

Creating Preferences Activities:
android provides another nice way of presenting and saving preferences. you can create Activities that extend PreferenceActivity.
PreferenceActivity is an activity that displays a set of built-in preferences related widgets that are defined in xml file.

the preference activity can be divided to several PreferenceCategory each containing a set of related preferences.
The preferences widgets that Android provide are:

  1. CheckBoxPreference: displays a check box widget.
  2. EditTextPreference: displays an EditText widget to save user prefs.
  3. RingtonePreference: displays a list with the  ringtones on the device.
  4. ListPreference: displays a list of key/value items.
each one of these preferences widgets is associated with a preference key. its value is persisted instantly as the widget selection changes.

we can construct our preferences screen xml (saved in res/xml directory) layout like this:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
>
<PreferenceCategory
android_title="Catogory one"
android_summary="sample summary">
<CheckBoxPreference
android_title="Enable"
android_key="pref_enable"
android_summary="enables a preference"/>
<EditTextPreference
android_summary="Edit text prefrence"
android_title="Edit"
android_key="pref_edit"/>


</PreferenceCategory>
<PreferenceCategory
android_title="Category2"
android_summary="sample summary">
<RingtonePreference
android_key="pref_ring"
android_title="Ringtones preference"/>

<ListPreference
android_key="pref_list"
android_title="List Preference"
android_dialogTitle="List Pref Dialog"
android_entries="@array/pref_items"
android_entryValues="@array/pref_items_values"/>
</PreferenceCategory>


then from our activity:
public class PrefActivity extends PreferenceActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.prefs);

}
}

and the activity will look like this:





the ListPreference can be associated with String array resources as its key/value entries
<string-array name="pref_items">
<item>Item1</item>
<item>Item2</item>
<item>Item3</item>
<item>Item4</item>
<item>Item5</item>
</string-array>

<string-array name="pref_items_values">
<item>1</item>
<item>2</item>
<item>3</item>
<item>4</item>
<item>5</item>
</string-array>


to reference the preference widgets programmatically:
EditTextPreference pref_edit=(EditTextPreference)findPreference("pref_edit");
Read More..

Saturday, March 12, 2016

Android Menus part 3 Context Menus

In  previous posts we explored two types of android menus: Options menu and submenus. In this post we’re going to see another menu type: Context menus.

Context Menu:


Context menus are the menus that appear when you right-click in windows.
In android Context menu are attached to widgets and the appear when you click on the widget for a long time (long click).

To add context menus to widgets you have to do two things:
  1. Register the widget for a context menu.
  2. Add menu items to the context menu.
So to register a context menu with a TextView you do it like this:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
txt=(TextView)findViewById(R.id.txt);
registerForContextMenu(txt);
}

We call registerForContextMenu(View V) method to tell the activity that the view is going to have a context menu.

Then we add items to the context menu by overriding the onCreateContext method:
@Override
public void onCreateContextMenu(ContextMenu menu,View v,ContextMenuInfo info)
{
menu.setHeaderTitle("Context Menu");
menu.add("Item");
}

When you make a long click on the text view the context menu will appear like this:


The onCreateContextMenu method has the following parameters:
  1. Context Menu: an instance of the context menu.
  2. View: the view to which the context menu is attached.
  3. ContextMenuInfo: carries additional information regarding the creation of the context menu.
To handle the context menu items click events you can implement the callback method onContextItemSelected.
We do it the same way we handle onOptionsItemSelected.
@Override
public boolean onContextItemSelected(MenuItem item)
{
txt.setText(item.getTitle());
return true;
}

Read More..

Friday, February 19, 2016

Android Menus part 2 Handling Menu Items Events

We can handle menu items events by three ways:
  1. By implementing onOptionsItemSelected method.
  2. By implementing listeners to single menu items.
  3. By using intents.
Using onOptionsItemSelected method:
Implement the onOptionsItemSelected method like this:
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
TextView txt=(TextView)findViewById(R.id.txt);
txt.setText("you clicked on item "+item.getTitle());
return true;
}

Notice that it returns a Boolean which should be true to execute the method, if false it will not execute.

You can switch between the menu items like this:
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
TextView txt=(TextView)findViewById(R.id.txt);
switch(item.getItemId())
{
case 1:
txt.setText("you clicked on item "+item.getTitle());
return true;
case 2:
txt.setText("you clicked on item "+item.getTitle());
return true;
case 3:
txt.setText("you clicked on item "+item.getTitle());
return true;


}
return super.onOptionsItemSelected(item);

}


Notice that we return true for every handled menu item. And for un handled menu items (outside switch block) we call the super class method.

Using listners:

We can handle options menu items click events by making the activity implement onMenuItemClickListner interface provide an implementation of onMenuItemClick method like this:
public class MenusDemo extends Activity implements OnMenuItemClickListener
then implement the method:
public boolean onMenuItemClick(MenuItem item) {
TextView txt=(TextView)findViewById(R.id.txt);
txt.append("listner");
return false;
}


Notice that the method returns a Boolean. If it returns true no other callbacks will be executed. If returns false then onOptionsItemSelected callback will be executed directly after this callback.

Using intents:
You can specify an intent to be launched when an options menu item is clicked like this:
menu.add(1, “dialItem”, 1, "Dial").setIcon(R.drawable.dvd).setIntent(new Intent(Intent.ACTION_DIAL));

note that if you specify an intent for an item and at the same time override the onOptionsItemSelected method and handle the selection for that item, the precedence of execution is to the code in the onOptionsItemSelected.
meaning that the code in onOptionsItemSelected method will be executed first, if it returns true then the intent will not be launched, if returns false then the intent will launch.

So if you want to use intent for menu items don’t handle it in onOptionsItemSelected method but invoke the parent onOptionsItemSelected.

Scenario 1:
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
menu.add(1, “dialItem”, 1, "Dial").setIcon(R.drawable.dvd).setIntent(new Intent(Intent.ACTION_DIAL)); return super.onCreateOptionsMenu(menu);

}

@Override
public boolean onOptionsItemSelected(MenuItem item)
{
TextView txt=(TextView)findViewById(R.id.txt);
switch(item.getItemId())
{
case 1:
txt.append("you clicked on item "+item.getTitle());
return true;
case “dialItem”:
txt.setText("you clicked on item "+item.getTitle());
return true;
case 3:
txt.setText("you clicked on item "+item.getTitle());
return true;


}
return super.onOptionsItemSelected(item);

}


This will execute the code of the onOptionsItemSelected method and the dialer intent will not be launched.

Scenario 2:

@Override
public boolean onCreateOptionsMenu(Menu menu)
{
menu.add(1, “dialItem”, 1, "Dial").setIcon(R.drawable.dvd).setIntent(new Intent(Intent.ACTION_DIAL)); return super.onCreateOptionsMenu(menu);

}

@Override
public boolean onOptionsItemSelected(MenuItem item)
{
TextView txt=(TextView)findViewById(R.id.txt);
switch(item.getItemId())
{
case 1:
txt.append("you clicked on item "+item.getTitle());
return true;
case “dialItem”:
txt.setText("you clicked on item "+item.getTitle());
return false;
case 3:
txt.setText("you clicked on item "+item.getTitle());
return true;


}
return super.onOptionsItemSelected(item);

}
This will execute the code of the onOptionsItemSelected method and then dialer intent will be launched.


Scenario 3:

@Override
public boolean onCreateOptionsMenu(Menu menu)
{
menu.add(1, “dialItem”, 1, "Dial").setIcon(R.drawable.dvd).setIntent(new Intent(Intent.ACTION_DIAL)); return super.onCreateOptionsMenu(menu);

}

@Override
public boolean onOptionsItemSelected(MenuItem item)
{
TextView txt=(TextView)findViewById(R.id.txt);
switch(item.getItemId())
{
case 1:
txt.append("you clicked on item "+item.getTitle());
return true;

case 3:
txt.setText("you clicked on item "+item.getTitle());
return true;


}
return super.onOptionsItemSelected(item);

}



the onOptionsItemSelected does not handle the "dialerItem" selection, so The dialer intent will be launched directly.
Read More..

Tuesday, February 9, 2016

Android Menus Part 1 Options menu and sub menus

Android phones have the menu button which displays a menu with several items that provide navigation or more functionality or settings to your applications

Android has three types of menus
1. Options Menu
2. Context Menu
3. Sub menus

Menu items can be grouped and each menu item can have submenu items.

Options Menu

Each activity has a single menu. It appears when you press the menu button Each activity creates this menu in the callback method onCreateOptionsMenu you can override this method and add items to the menu.
If you press the menu button you will see the menu like this:
public class MenusDemo extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}

@Override
public boolean onCreateOptionsMenu(Menu menu)
{
menu.add("Item1");
menu.add("Item2");
return true;
}
}



Notice that the onCreateOptionsMenu method returns a Boolean. It should return true for the menu to appear, if returns false the menu will be invisible.

If you add many menu items, more than five items they will appear like this:
public boolean onCreateOptionsMenu(Menu menu)
{
menu.add(1, 1, 0, "Item1");
menu.add(1, 2, 1, "Item2");
menu.add(1, 3, 2, "Item3");
menu.add(1, 4, 3, "Item4");
menu.add(1, 5, 4, "Item5");

menu.add(2, 6, 0, "Item6");
menu.add(2, 7, 1, "Item7");
menu.add(2, 8, 2, "Item8");
menu.add(2, 9, 3, "Item9");
menu.add(2, 10, 4, "Item10");



return true;
}



When you press on the “more” link you will see the rest of the menu items



The menu.add(int GroupID,int ItemID,int Order,String Title) method has the following parameters:
  1. GroupID: used to group related menu items to apply some configurations on all items of a certain group once at a time (discussed later) .
  2. ItemID: an integer to identify the menu item.
  3. Order: the sort order or the order ID, controls the order of menu items in a menu. Items with lower order id appear first. There are some constants defined for sort order for different kinds of menu items
    Like Menu.CATEGORY_SECONDRY for secondry menu items, Menu.CATEGORY_SYSTEM for system menu items and Menu.CATEGORY_ALTERNATIVE for altenative menu items..
  4. Title: the text of the menu item


We could have written the previous code using the predefined the sort order constants like this:
menu.add(1, 1, Menu.FIRST, "Item1");
menu.add(1, 2, Menu.FIRST+1, "Item2");
menu.add(1, 3, Menu.FIRST+2, "Item3");
menu.add(1, 4, Menu.FIRST+3, "Item4");
menu.add(1, 5, Menu.FIRST+4, "Item5");

menu.add(2, 6, Menu.CATEGORY_SECONDARY, "Item1");
menu.add(2, 7, Menu.CATEGORY_SECONDARY+1, "Item2");
menu.add(2, 8, Menu.CATEGORY_SECONDARY+2, "Item3");
menu.add(2, 9, Menu.CATEGORY_SECONDARY+3, "Item4");
menu.add(2, 10, Menu.CATEGORY_SECONDARY+4, "Item5");




Adding Icons to menu items:
We saw that only the first five items can appear in the options menu and the other items appear in a dialog when you press “more” item.
For the first five items you can add an icon to appear next to the items title:
menu.add(1, 1, 0, "Blu-Ray").setIcon(R.drawable.bluray);
menu.add(1, 2, 1, "DVD").setIcon(R.drawable.dvd);
menu.add(1, 3, 2, "Hard Disk").setIcon(R.drawable.hd);
menu.add(1, 4, 3, "Sites").setIcon(R.drawable.sites);
menu.add(1, 5, 4, "USB").setIcon(R.drawable.usb);

menu.add(2, 6, 5, "Item1");
menu.add(2, 7, 6, "Item2");
menu.add(2, 8, 7, "Item3");
menu.add(2, 9, 8, "Item4");
menu.add(2, 10, 9, "Item5");



Grouping Menu Items:

We saw that the method we use to add menu items us Menu.Add(GroupID,ItemId,OrderID,Title)
The first parameter is GroupID, what is it ? the answer leads us to grouping Menu Items.

Grouping menu items makes it easy to apply some options on some related menu items by applying these options on all menu items that belong to a group once instead of applying them on each single item at a time.

The actions that can be applied on a group can be:
  • Menu.removeGroup(int GroupID): to remove all menu items belonging to the same group.
  • Menu.setGroupCheckable(int GroupID,Boolean Checakble,Boolean Exclusive): maked a group appear with a check mark beside each item. If the Boolean Exclusive is set to true then the items will appear as if they are in a radiobuttongroup and only one item can be selected at a time. If set to false then they will appear with check boxes beside each item and multiple items can be selected at a time.
  • Menu.setGroupEnabled(int GroupID,Boolean Enabled): sets all items in a group to be enabled/disabled.
  • Menu.setGroupVisible(int GroupID,Boolean Visible): sets all items in a group to be visible/invisible.
Note: the methods mentioned above can be applied only to menu items in the secondary menu (items that appear when you click the more button)


Adding Alpha-Numeric shortcuts to menu Items:
You can add alphabetic or numeric shortcuts to menu items like this:
menu.add(2, 8, 7, "Item3").setNumericShortcut(3);
menu.add(2, 9, 8, "Item4").setAlphabeticShortcut(c);
then setting the querty mode of the menu to true like this:
menu.setQwertyMode(true);

and thats it for Androids options menu.

In a next post well talk about handling options menu events
Read More..