0% found this document useful (0 votes)
34 views

Android App Components

The document discusses the key components of Android apps: Activities, Services, Content Providers, and Broadcast Receivers. It describes how Intents are used to communicate between components and how implicit intents allow other apps to handle actions. Content Providers manage shared data through a common interface and ContentResolver. Services run in the background without a UI.

Uploaded by

Edward Mid
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
34 views

Android App Components

The document discusses the key components of Android apps: Activities, Services, Content Providers, and Broadcast Receivers. It describes how Intents are used to communicate between components and how implicit intents allow other apps to handle actions. Content Providers manage shared data through a common interface and ContentResolver. Services run in the background without a UI.

Uploaded by

Edward Mid
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 32

Android App Components

App Components
● App Components
– Activity
– Content Provider
– Service
– Broadcast Receiver

● Messaging Components
– Intent
– Others (based upon Binder IPC)
Intent
● Intent
– An abstract depiction of the operation
– A message for the OS to perform an action

● Applicability
– Start an activity (internal or external)
– Interact with other components like services and broadcast receivers

● Types
– Explicit
– Implicit
Explicit Intent

Class reference

Intent intent = new Intent(this,ListActivity.class);

startActivity(intent);

Intent sent to the OS

● Contains an exact reference to the class


● Typically used to interact with a component
internal to app
Implicit Intent

A string constant representing an action

Intent intent = new Intent(Intent.ACTION_EDIT);

startActivity(intent);

Intent sent to the OS

● Contains an action that any other app (or its component)


can declare to handle
● Facilitates inter-application communication and integration
Implicit Intent
● Workflow
– Applications declare the intents they handle in the
manifest using intent-filter
– Any interested application component can build and send
an implicit intent object
– Android OS:
● Maintains an index of intent-filters and corresponding
components declared by every app at the installation time
● Searches the intent-filter index, on receipt of an intent
● Launch the matching app component (or asks the user in case of
multiple matches)

An app component can specify multiple filters representing different ways it can handle intents
Implicit Intent
● Primary Information
– Action : a string specifying an action
– Data : a URI referencing data for the action
– Category : a string containing additional information about component

● Secondary Information
– Extras
– Flags

Intent-filter need not declare all of the information constituents


Intent resolution requires matching atleast one of each primary information constituent declared in the filter
Sample intent-filter declaration (in Manifest)
<activity android:name="NotesActivity"
android:label="@string/app_name">

<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>

<intent-filter>
<action android:name="android.intent.action.EDIT" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="note" />
</intent-filter>

</activity>

Sample intent sent to OS for matching (in Java)


Intent intent = new Intent(Intent.ACTION_EDIT);
intent.setData(Uri.parse("note://"));
startActivity(intent);
Content Provider
● Manages access to a central repository of data
● Data sharing across multiple applications
– Secure data access
– Inter-process communication
● Data Abstraction
– Tables & Rows (conceptually like a database)
– Independent of underlying data storage medium (e.g. database, files,
shared preferences, etc.)
● API
– ContentProvider
– ContentResolver
– Cursor and ContentValues
– Uri and UriMatcher
Creating a Content Provider
● Design data storage
● Design content URIs
– Authority
– Path
● Implement ContentProvider methods
– onCreate
– getType
– query
– insert
– update
– delete
● Register in manifest and set any permissions required
● Optionally provide a Contract class for specifying provider
details
public class NotesProvider extends ContentProvider{

private static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);

static {
matcher.addURI("com.example.smd.notesprovider","notes",1);
}

private NotesDbHelper dbHelper;


private SQLiteDatabase db;

public boolean onCreate(){


dbHelper = new NotesDbHelper(getContext());
db = dbHelper.getReadableDatabase();
return true;
}

public String getType(Uri uri){ … }


public Uri insert(Uri uri,ContentValues values){ … }
public int update(Uri uri,ContentValues values,String selection,String[] args){ … }
public int delete(Uri uri,String selection,String[] args){ … }

public Cursor query(Uri uri,String [] projection, String selection,String[] selectionArgs,String sortOrder){

if(matcher.match(uri) == 1){
return db.query("Notes",projection,selection,selectionArgs,null,null,sortOrder);
}

String[] cols = {"_ID"};


return new MatrixCursor(cols);
}

}
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.smd"
android:versionCode="1"
android:versionName="1.0">

<application android:label="@string/app_name" android:icon="@drawable/ic_launcher"


android:theme="@style/Notes">

<activity android:name="NotesActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>

</activity>
<activity android:name="com.example.smd.ListActivity"
android:label="ListActivity"
android:parentActivityName="com.example.smd.NotesActivity" >

<meta-data android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.smd.NotesActivity" />
</activity>

<provider android:name="NotesProvider"
android:authorities="com.example.smd.notesprovider"
android:exported="true" />

</application>
</manifest>
Using a Content Provider
● Use ContentResolver
– A remote proxy object for the provider
– Provides same methods as provided by the provider
● onCreate
● getType
● query
● insert
● update
● delete
public class AppTest extends Activity
{
...

public void getNotes(View view)


{
String[] colNames = {"title","content"};

Cursor cursor = getContentResolver().query(


Uri.parse("content://com.example.smd.notesprovider/notes"), // uri
colNames, // projection (columns)
null, // search string (where clause)
null, // search arguments (parameters)
null); // sort order

if (cursor.getCount() > 0){

String result = "";

while (cursor.moveToNext()){
result += cursor.getString(cursor.getColumnIndex("title")) + "\n";
}

Toast.makeText(this,result,Toast.LENGTH_SHORT).show();
}
}

}
Standard Content Providers
● Browser
● Calendar
● Contacts
● CallLog
● MediaStore
● UserDictionary
Services
● Application component without a UI
● A long-running operation in the background
● Continues running even if user switches to
another application
● May be invoked remotely from a different
process through IPC
Example Usage Scenarios
● Download / Upload / Synchronize data on network
● Alarms / notifications / reminders (on some specific event)
● Send emails / messages in a fail-safe manner
● Play audio / music in the background
● Archive data
● Authenticate users
● Other application specific scenarios
Example
public class NotesExportService extends Service {

public void onCreate() {

public int onStartCommand(Intent intent,int flags,int startId){


Toast.makeText(this,"Service starting",Toast.LENGTH_SHORT).show();
return START_NOT_STICKY;
}

public IBinder onBind(Intent intent){


return null;
}

}
Service Types
● Started
– Performs a background operation and does not return
any result to the caller
– Once started, may run indefinitely unless
● explicitly stopped
● killed by the system but may be restarted based upon restart
behavior and any pending requests
– Useful for cases like syncing data, playing audio, etc.
– Invocation
● from other App components (Activities or BroadcastRecievers)
using explicit intents
Intent intent = new Intent(this,NotesExportService.class);
startService(intent);
● calls onStartCommand
Service Types
● Bound
– Bound to the application component starting the service
● client-server communication
● service acts as the server
– Runs only as long as another component is bound to it
● Multiple components may bind to a service at once
● Destroys when all bound components unbind
– Useful for cases like authentication, play audio with
status updates, etc.
– Invocation
● Using Binder, ServiceConnection and bindService
● calls onBind
public class NotesExportService extends Service {

private final IBinder binder = new LocalBinder();

public void onCreate() {

public int onStartCommand(Intent intent,int flags,int startId){


Toast.makeText(this,"Service starting",Toast.LENGTH_SHORT).show();
return START_NOT_STICKY;
}

public IBinder onBind(Intent intent){


return binder;
}

public class LocalBinder extends Binder{


public NotesExportService getService(){
return NotesExportService.this;
}
}

public String getStatus(){


return "exported successfully"; // or other recorded status
}

}
public class SettingsActivity extends BaseActivity
{

NotesExportService dataService;
boolean bound = false;
...
private ServiceConnection connection = new ServiceConnection(){

public void onServiceConnected(ComponentName className, IBinder binder){


dataService = ((NotesExportService.LocalBinder) binder).getService();
bound = true;

// other service related requests and operations go here


}

public void onServiceDisconnected(ComponentName className){


bound = false;
}
};

protected void onStart(){


super.onStart();
Intent intent = new Intent(this,NotesExportService.class);
bindService(intent,connection, Context.BIND_AUTO_CREATE);
}

protected void onStop(){


super.onStop();
if(bound){
unbindService(connection);
}
}
Some Considerations
● Service not a separate process
– Service itself doesn't mean a new process
– Runs in the same process of the application by default
– It may be specified to run in a different process
– Remote services require IPC mechanisms
● Service not a thread
– Service itself doesn't launch a new thread
– Thread management needs to be done explicitly
– Necessary to avoid application not responding errors
Broadcast Receivers
● Broadcasts
– system or custom-generated notifications for events
– broadcasted to interested application components that
may need to take corresponding action
– API
● sendBroadcast: asynchronous operation to notify all receivers in
parallel
● sendOrderedBroadcast: asynchronous operation to notify all
receivers in sequence – may be aborted in between
– Examples
● android.intent.action.BOOT_COMPLETED
● android.intent.action.BATTERY_LOW
Broadcast Receivers
● Broadcast receiver
– An event listener
– Registered to receive broadcasted intents
– Runs in background – may send UI notifications
– Invoke a service
● Only start
● Cannot bind
Example broadcast receiver registered statically in the manifest

public class ConnectivityReceiver extends BroadcastReceiver {

public void onReceive(Context context,Intent intent){


String message = "received";
Toast.makeText(context,message,Toast.LENGTH_SHORT).show();
}

<receiver android:name="ConnectivityReceiver">
<intent-filter>
<action
android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
Example broadcast receiver registered dynamically in an activity

public class NotesActivity extends BaseActivity


{

ConnectivityReceiver receiver;

public void onCreate(Bundle savedInstanceState)


{

IntentFilter intent = new
IntentFilter("android.net.conn.CONNECTIVITY_CHANGE");
receiver = new ConnectivityReceiver();
registerReceiver(receiver,intent);
}

protected void onDestroy(){


unregisterReceiver(receiver);
super.onDestroy();
}
}
Example broadcast receiver invoking a service

public class ConnectivityReceiver extends BroadcastReceiver {

public void onReceive(Context context,Intent intent){


String message = "received";
Toast.makeText(context,message,Toast.LENGTH_SHORT).show();

SharedPreferences preferences =
context.getSharedPreferences("service",Context.MODE_PRIVATE);
boolean started = preferences.getBoolean("started",false);
SharedPreferences.Editor editor = preferences.edit();

if(!started){
Intent serviceIntent = new Intent(context,NotesDataSyncService.class);
context.startService(serviceIntent);
editor.putBoolean("started",true);
}
else{
Intent serviceIntent = new Intent(context,NotesDataSyncService.class);
context.stopService(serviceIntent);
editor.putBoolean("started",false);
}

editor.commit();
}

}
SMS Example
● SMS received broadcast
– android.provider.Telephony.SMS_RECEIVED
– Ordered broadcast – may be aborted by some
application
– Requires permissions
● android.permission.RECEIVE_SMS
● android.permission.READ_SMS
– Intent structure
● Generally carries an array of PDUs, mapped to string pdus
public class SmsReceiver extends BroadcastReceiver {

public void onReceive(Context context,Intent intent){

Bundle bundle = intent.getExtras();

try {
if (bundle != null) {
Object[] pdusObj = (Object[]) bundle.get("pdus");

for (int i = 0; i < pdusObj.length; i++) {


SmsMessage currentMessage = SmsMessage.createFromPdu((byte[]) pdusObj[i]);
String number = currentMessage.getDisplayOriginatingAddress();
String message = currentMessage.getDisplayMessageBody();

String text = "senderNum: "+ number + ", message: " + message;


Toast.makeText(context, text , Toast.LENGTH_LONG).show();

}
}

} catch (Exception e) {

}
}

}
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.smd.AppTest"
android:versionCode="1"
android:versionName="1.0">

<uses-permission android:name="android.permission.RECEIVE_SMS" />


<uses-permission android:name="android.permission.READ_SMS" />

<application android:label="@string/app_name" android:icon="@drawable/ic_launcher">


<activity android:name="AppTest"
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="SmsReceiver">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
</application>

</manifest>

You might also like