1 Islamic University of Gaza Faculty of Engineering Computer Engineering Department Mobile Computing ECOM 5341 By Eng. Wafaa Audah July 2013
1
Islamic University of Gaza
Faculty of Engineering
Computer Engineering Department
Mobile Computing ECOM 5341
By
Eng. Wafaa Audah
July 2013
2
Intent Filters, Broadcast Receivers,
Adapters and ListViews
Using Intent Filters to Service Implicit Intents
To inform the system which implicit intents they can handle, activities, services, and broadcast receivers can have one or more intent filters. Each filter describes a capability of the component, a set of intents that the component is willing to receive.
A filter has fields that parallel the action, data, and category fields of an Intent object. An implicit intent is tested against the filter in all three areas. To be delivered to the component that owns the filter, it must pass all three tests. If it fails even one of them, the Android system won't deliver it to the component.
In order to let an application component to work as an Intent handler, we must use
Intent filters. Intent filters are generally not set up in Java code, but in the application's
manifest file (AndroidManifest.xml) as <intent-filter> tag (and many elements and
attributes within it):
1. action android:name attribute to specify the name of the action being serviced.
- MAIN: the first exec. Activity of Application, start up as the initial activity of a
task, with no data input and no returned output.
- VIEW: activity used to show the content of webpage, people in contacts...etc.
2. category android:name attribute to specify under which category the action
should be serviced. Represents certain special properties of an activity represent
condition that activity will be serviced under it.
- DEFAULT Set this to make a component the default action for the data type
specified.
- LAUNCHER Using this category makes an Activity appear in the application
Launcher. The activity can be the initial activity of a task and is listed in the top-
level application launcher.
- HOME is used for Home Screen activities (Means that the app can be started on the phone's boot up). If you want to create a new home screen use this.
3. data android:Type you specify which data types your component can act on.
- android:scheme Requires a particular scheme (e.g., content or http).
3
Simple Web browser
1. Using known implicit intents only
No need for adding permission or editing the manifest file
“No need to add new intent filters”
2. Using WebView
Need INTERNET permission, no need for editing manifest file
<uses-permission android:name="android.permission.INTERNET"/>
public class First extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.first); Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.google.com")); startActivity(intent); } }
public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); WebView webView = (WebView) findViewById(R.id.webView1); webView.setWebViewClient(new WebViewClient()); webView.loadUrl("http://www.google.com"); }
}
4
3. The presence of more than one activity installed on the device
matching the requirements for an implicit intent
When the implicit intent object is created to display a web browser window in part 1,
the URL of the web page to be displayed will be bundled into the intent object within an
Uri object. The task here is to extract this Uri from the intent object, convert it into a
URL string and assign it to the WebView object which, since we did not provide a
specific name, will have a default ID of webView1.
Need
INTERNET
permission
Editing the manifest file
Default file contains
<intent-filter > <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter>
public class Browser extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_browser); Intent intent = getIntent(); Uri data = intent.getData(); URL url = null; try { url = new URL(data.getScheme(), data.getHost(), data.getPath()); } catch (Exception e) { e.printStackTrace(); } WebView webView = (WebView) findViewById(R.id.webView1); webView.loadUrl(url.toString()); } }
5
Since the activity is not required to be launched as the entry point to an application, cannot be run without data input (in this case a URL) and is not required to appear in the launcher, neither the MAIN nor LAUNCHER directives are required in the manifest file for this activity.
The intent filter for the activity does, however, need to be modified to indicate that it is capable of handling ACTION_VIEW intent actions for http data schemes. Android also requires that any activities capable of handling implicit intents that do not include MAIN and LAUNCHER entries also include the so-called default category in the intent filter. The modified intent filter section should, therefore, read as follows:
<intent-filter > <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="http" /> </intent-filter>
Before this activity can be used as the recipient of an implicit intent, it must first be
installed onto the device. This is achieved by running the application normally.
In order to test this activity, simply re-launch the application created earlier at part 1. This time, however, the intent resolution process will find two activities with intent filters matching the implicit intent. As such, the system will display a dialog (following figure) providing the user with the choice of activity to launch.
<<< Try to do all the above work by yourself at home >>>
6
Broadcast Intents
Broadcast messages between components with the sendBroadcast method.
Makes an application more open, by broadcasting to current and other applications. OR
Broadcast receiver
Definition
A broadcast receiver (receiver) is an Android component which allows you to register for system or application events. All registered receivers for an event will be notified by the Android runtime once this event happens.
Many broadcasts originate from the system—for example, a broadcast announcing that the screen has turned off, the battery is low, or a picture was captured. Applications can also initiate broadcasts—for example, to let other applications know that some data has been downloaded to the device and is available for them to use. Although broadcast receivers don't display a user interface, they may create a status bar notification to alert the user when a broadcast event occurs.
<< Broadcast receiver triggers battery Low notification that you see on your mobile screen >>
<receiver android:name="MyReceiver">
<intent-filter>
<action android:name="com.tutorialspoint.CUSTOM_INTENT">
</action>
</intent-filter>
</receiver>
public class MyReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Intent Detected.",Toast.LENGTH_LONG).show();
}}
public void broadcastIntent(View view){
Intent intent = new Intent();
intent.setAction("com.tutorialspoint.CUSTOM_INTENT"); sendBroadcast(intent);}
7
Implementation
<< Broadcast receivers listen to Broadcast Intents >>
- A receiver can be registered via the AndroidManifest.xml file.
Broadcast Receivers will receive broadcast Intents even when the application has been killed or hasn’t been started. <receiver android:name="MyPhoneReceiver" > <intent-filter> <action android:name="android.intent.action.PHONE_STATE" > </action> </intent-filter> </receiver>
- You can also register a broadcast receiver via the Context.registerReceiver() method at the code, receiver registered programmatically will respond to broadcast Intents only when the application component it is registered within is running. The implementing class for a receiver extends the BroadcastReceiver class, if the event for which the broadcast receiver has registered happens, the onReceive() method of the receiver is called by the Android system.
IntentFilter filter = new IntentFilter();
filter.addAction("android.intent.action.PHONE_STATE");
receiver = new MyReciver();
registerReceiver(receiver, filter);
Broadcast receivers use Intent Filter to specify which Intents it is listening for
The following table lists a few important system events.
Event Usage
Intent.ACTION_BATTERY_LOW The battery level has fallen below a
threshold
Intent.ACTION_BATTERY_OKAY The battery level has risen again
Intent.ACTION_BOOT_COMPLET
ED
Android is up and running android.permission.RECEIVE_BOO
T_COMPLETED permission.
Intent.ACTION_DEVICE_STORA
GE_LOW
Storage space on the device is getting
limited
Intent.ACTION_DEVICE_STORA
GE_OK
The storage situation has improved
again
8
Intent.ACTION_HEADSET_PLUG A headset was plugged in or a
previously plugged headset was
removed
Intent.ACTION_LOCALE_CHANG
ED
The user changed the language of the
device
Intent.ACTION_MY_PACKAGE_R
EPLACED
Your app has been updated
Intent.ACTION_PACKAGE_ADDE
D
A new app has been installed
Intent.ACTION_POWER_CONNE
CTED
The device has been plugged in
Intent.ACTION_POWER_DISCON
NECTED
The device has been disconnected
again
KeyChain.ACTION_STORAGE_C
HANGED
The keystore changed
BluetoothDevice.ACTION_ACL_C
ONNECTED
A Bluetooth ACL connection has
been established
AudioManager.ACTION_AUDIO_B
ECOMING_NOISY
The internal audio speaker is about to
be used instead of other output means
(like a headset)
Difference between Activity Intent and Broadcasting Intent
The intent used to start an Activity makes changes to an operation the user is interacting with, so the user is aware of the process. However, in case of broadcasting intent, the operation runs completely in the background, and is therefore invisible to the user.
Implementing the Broadcast Receiver
You need to follow these steps to implement a broadcast receiver:
1) Create a subclass of Android’s BroadcastReceiver
2) Implement the onReceive() method: In order for the notification to be sent, an onReceive() method has to be implemented. Whenever the event for which the receiver is registered occurs, onReceive() is called. For instance, in case of battery low notification, the receiver is registered to Intent.ACTION_BATTERY_LOW event. As soon as the battery level falls below the defined level, this onReceive() method is called.
9
Following are the two arguments of the onReceive() method:
Context: This is used to access additional information, or to start services or activities.
Intent: The Intent object is used to register the receiver.
We will define a broadcast receiver which listens to telephone state changes. If the
phone receives a phone call then our receiver will be notified and log a message with
state.
New android application project >> new class (superclass: Broadcast Receiver) >> write
the code in it >> update the manifest
<< Class is recorded at Manifest as Receiver not Activity >>
public class MyPhoneReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Bundle extras = intent.getExtras(); if (extras != null) { String state = extras.getString(TelephonyManager.EXTRA_STATE); Log.w("MY_DEBUG_TAG", state); } }
}
10
In order to test the previous work
- Run the application normally >> Go to DMMS (Dalvik Debug Monitor Server)
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.broadcasttest" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" > </uses-permission> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.example.broadcasttest.MyPhoneReceiver" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <receiver android:name="MyPhoneReceiver" > <intent-filter> <action android:name="android.intent.action.PHONE_STATE" > </action> </intent-filter> </receiver> </application> </manifest>
11
- Go to Emulator Control tab >> enter the phone number you want to call >> press Call button …..
Result
12
Lab Work 1
Do the previous work for calling, but with adding incoming phone number in log message and with toast message.
“New Phone Call Event, Incomming Number : "+incomingNumber+”Phone State
Is”+phoneState
if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) { String phoneNumber = extras .getString(TelephonyManager.EXTRA_INCOMING_NUMBER); Log.w("MY_DEBUG_TAG", phoneNumber);
}
13
How to create a ListView using ArrayAdapter
Simply there are three things you have to concentrate;
1. A data set 2. A UI component to view the list 3. A way to join the data set and the UI component
1. Data set is going to be a String ArrayList (which contains mobile OS names in our
example). For a complex scenario a data set can be an output from a database for example.
- If you have a fixed data you can use Array:
final String[] Items = new String[] { "item1", "item2", "item3",
"item4"};
- Generic form: ArrayList ArrayList<String> Items = new ArrayList<String>(); Items.add("item1"); Items.add("item2"); Items.add("item3"); Items.add("item4");
2. Then we need a UI (User Interface) component to view the data set. In this example: ListView.
14
3. There is no way to plug a data set directly to the UI component like ListView. Therefore we need a third party support. That is an Adapter, the ArrayAdapter class is act as the third party to complete our task.
- Create an ArrayAdapter, pass arraylist to it.
int LayoutID = android.R.layout.simple_list_item_1; final ArrayAdapter<String> adapter = new ArrayAdapter<String> (this,LayoutID,Items);
- Create List view, connect it with the adapter.
final ListView listView = (ListView) findViewById(R.id.listView1); listView.setAdapter(adapter);
Lab Work 2
1. Build an application that lists some of mobiles operation
system (Android, IOS, WindowsMobile, Blackberry)
2. Make OnItemClickListener on the list items, show item position and value on click.
15
Adding Listeners
mobileListView.setOnItemClickListener(new OnItemClickListener() { public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // ListView Clicked item index int itemPosition = position; // ListView Clicked item value String itemValue = (String) mobileListView.getItemAtPosition(position); // Show Alert Toast.makeText(getApplicationContext(), "Position :"+itemPosition+" ListItem : " +itemValue , Toast.LENGTH_LONG) .show(); } });
public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final ArrayList<String> MOBILE_OS = new ArrayList<String>(); MOBILE_OS.add("Android"); MOBILE_OS.add("iOS"); MOBILE_OS.add("WindowsMobile"); MOBILE_OS.add("Blackberry"); int LayoutID = android.R.layout.simple_list_item_1; final ArrayAdapter<String> adapter = new ArrayAdapter<String> (this,LayoutID,MOBILE_OS); final ListView mobileListView = (ListView) findViewById(R.id.listView1); mobileListView.setAdapter(adapter); } }
16
SEE YOU AT THE NEXT LAB
Homework
Do all the previous work (Intent Filters, Broadcast Receivers,
Adapters and ListViews) and put them at your report