Android Basics
Dr.-Ing. Sven Bugiel
Mobile Security | WS24/25 | 2024-10-18
Should I watch this?
• You can savely skip this lecture on Android basics if you know
− How Android packages (APKs) are composed
− What Intents are and how they are sent between apps
− What Activities, BroadcastReceiver, Service, and ContentProvider
components are
− What the package visibility of Android is
• Video is structured in chapters, just skip to the relevant ones
Android
Applications
Big Picture
4 https://developer.android.com/guide/platform
Big Picture
5 https://developer.android.com/guide/platform
Applications
• Third party applications
− Installed by the user
− e.g., from Google Play, Amazon Store, etc.
• A few core (“system”) applications (cannot be uninstalled)
− Special flag in the package manager to mark them as system application
− Complement the implementation of the application framework API
− Contacts management, initiating phone calls, SMS/MMS management,…
6
Application packages (APK)
• APK is simply a packaging format like JAR, ZIP, or TAR
7
Application packages (APK): Basic structure
• APK is simply a packaging format like JAR, ZIP, or TAR
• Components of applications
− Activity: User interface
− Service: Background service
− Content Provider: SQL-like database
Classes.dex Native libs Resources META-INF/ Application
− Broadcast receiver: Mailbox for broadcasted messages Manifest
• Applications can contain native code (C/C++ shared libraries) and resources APK
(e.g., images)
− Native code provided as shared library files that can be dynamically linked into
the process
− Resources and assets: String values, layout definitions, drawables (pictures),
raw data
• META-INF/ contains the application certificate and package manifest
− Package manifest not to be mistaken with the application manifest !
8
Application packages (APK)
• APK is simply a packaging format like JAR, ZIP, or TAR
9
Application Manifest.xml
• Declares application meta-data and all components
− Names, filters, permissions, …
• Very basic example:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name” App info (Launcher icon, name, etc.)
...
android:roundIcon="@mipmap/ic_launcher_round"
tools:targetApi="31">
<activity android:name=".MainActivity”
android:exported="true">
Activity component
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=”.MyReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
BroadcastReceiver component
</intent-filter>
</receiver>
...
</application>
</manifest> https://developer.android.com/guide/topics/manifest/manifest-intro
10
Gradle build configuration
• Additional properties set in the gradle build configuration
− For example, package name, version, etc.
android {
namespace = ”com.example.app"
compileSdk = 33
defaultConfig {
applicationId = ”com.example.app"
minSdk = 33
targetSdk = 33
versionCode = 1
versionName = "1.0"
...
}
...
11
Components and
Intents
Activity component
• Represents a single screen in your application
− Composed of different Views (Buttons,
lists, text,…)
− Can be split into different Fragments
(reusable UI modules with own lifecycle,
hosted by an Activity/Fragment in a
hierarchy)
• Usually, one main activity per app
• Activity lifecycle:
https://developer.android.com/guide/components/activities/activity-lifecycle
13
Intent messages
• Data object that represents the intent to do something
− Launching an Activity, starting a Service, broadcast a message,…
− Payload and attributes describe the intended action
− Can be sent and received by an application
− Transmitted between processes via Binder-based IPC
− Can be sent to components of the same app or of another app
https://developer.android.com/guide/components/intents-filters
14
Application Manifest.xml: Exported attribute
• Only exported=“true” components can be called by another app
− Exported=“false”: can be launched only by components of the same app or
privileged system components
• Default value is “false”, unless intent filters are declared (implicitly exported)
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name” App info (Launcher icon, name, etc.)
...
android:roundIcon="@mipmap/ic_launcher_round"
tools:targetApi="31">
<activity android:name=".MainActivity”
android:exported="true">
Activity component
<intent-filter>
<action android:name="android.intent.action.MAIN" />
Activity (explicitly) <category android:name="android.intent.category.LAUNCHER" />
and receiver </intent-filter>
</activity>
(implicitly) are <receiver android:name=”.MyReceiver" >
<intent-filter>
exported! <action android:name="android.intent.action.BOOT_COMPLETED" />
BroadcastReceiver component
</intent-filter>
</receiver>
...
</application>
</manifest> https://developer.android.com/guide/topics/manifest/manifest-intro
15
Intent messages
• A receiver component can be described explicit or implicit
− Explicit: Set target component name
− “com.example.app.MainActivity”
Intent(Context packageContext, Class<?> cls)
Create an intent for a specific component.
Intent(String action, Uri uri, Context packageContext, Class<?> cls)
Create an intent for a specific component with a specified action and data.
− Implicit: Set an Action string, Category, and Data; the Android framework will
find a suitable receiver for this Intent
− Action = Intent.ACTION_VIEW ; Data=“http://www.google.com”
will open an app that can show the website, e.g., the default browser app
Intent(String action)
Create an intent with a given action.
Intent(String action, Uri uri)
Create an intent with a given action and for a given data url.
16
Example Intents
Intent intent = new Intent(Intent.ACTION_VIEW); Will implicitly start an application that can handle
intent.setData(Uri.parse("http://www.google.com")); http URIs, e.g., a browser, which then will react to
activity.startActivity(intent); this data, here, e.g., showing the Google website
Intent newAct = new Intent(this, MainActivity.class); Explicitly start the component
startActivity(newAct); MainActivity within the same package
as the caller (no payload provided here)
https://developer.android.com/guide/components/intents-filters
17
Intent Filters
• Declared in the manifest for Intent-receiving components to specify which
kinds of Intents (e.g., action string, class name, data payload) these
components want to receive
<activity android:name="MainActivity">
<!-- This activity is the main entry, should appear in app launcher -->
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="ShareActivity">
<!-- This activity handles "SEND" actions with text data -->
<intent-filter>
<action android:name="android.intent.action.SEND"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="text/plain"/>
</intent-filter>
</activity>
18
User-choice of applications
• What if multiple applications’ intent-filters match an Intent?
− The user has set a default application for this action
-or-
The system asks the user to select a target application
• Apps can also force the app chooser for an Intent (Intent.createChooser())
19
Service components
• Background processes without user interaction
− Potentially long-running
− E.g., polling emails from a web server
• Can be local to the app or in a remote process (provided by another app)
− Remote: Interface can be defined in domain-specific language Android
Interface Definition Language (AIDL)
− AIDL compiler creates a skeleton for the implementation of the service
(stub) and a proxy object abstracting the service and encapsulating
− A common approach to implement the Android application
framework API (Location manager, Wi-Fi manager, etc.)
• Can be started by a client or be bound by one or more clients
20
Service lifecycle
https://developer.android.com/guide/components/services
21
Service lifecycle
https://developer.android.com/guide/components/services
22
Starting an Unbounded Service
• Start service through startService() • Example Service:
command with an Intent:
public class HelloService extends
startService(new Intent(this, Service {
HelloService.class)); ...
@Override
• Can only be started with a fully public int onStartCommand(Intent
intent, int flags, int startId)
explicit Intent (i.e., contains the
{
component name)!
// Handle the call
− Ensure that only the intended
service responds and receives ...
return START_NOT_STICKY;
the Intent
}
23
Service lifecycle
https://developer.android.com/guide/components/services
24
Stubs and Proxies: Abstract view
App A App B
Component
(e.g. Activity)
B Service Stub
Call foo(“bar”)
Stub implementation
int foo(String) { return 42; }
B Service Proxy
int foo(String);
Binder-based Inter-Process Communication (IPC)
Kernel
25
Example Service Interface Definition in AIDL
MyService.aidl:
package com.example.android;
interface MyService {
int foo(in String bar);
}
26
Example Auto-generated Proxy and Stub from AIDL
IMyService.java:
/*
* This file is auto-generated. DO NOT MODIFY.
* Original file: /Users/sven/android_coding_share/apps/TestApp/src/com/example/android/MyService.aidl
*/
package com.example.android;
public interface MyService extends android.os.IInterface
{
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements com.example.android.MyService
{
private static final java.lang.String DESCRIPTOR = "com.example.android.MyService";
...
@Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
{
switch (code)
{
...
case TRANSACTION_bar:
{
data.enforceInterface(DESCRIPTOR); Stub: Receiving side, i.e., has to be
String _arg0;
_arg0 = data.readString();
int _result = this.foo(_arg0); implemented by the Service-side (e.g., takes
reply.writeNoException();
reply.writeInt(_result);
return true;
care of reading the Parcel and calling
}
...
private static class Proxy implements com.example.roundtrip2.IRR2Service
method implementation)
{
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote)
{
...
@Override public int foo(String bar) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
int _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeString(bar);
mRemote.transact(Stub.TRANSACTION_foo, _data, _reply, 0);
_reply.readException();
_result = _reply.readInt();
}
...
return _result; Proxy: Used by sender to call the service
}
... (takes care of writing a Parcel and sending
(“transact”) it to remote process)
27
Example Stub implementation
MyService.java:
public class MyService extends Service {
...
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
private final MyService.Stub mBinder = new MyService.Stub() {
public int foo(String bar) {
return 42;
};
}
...
}
28
Stubs and Proxies: Concrete example
• Manager classes
encapsulate the
proxy classes and 1
provide easy-to-
use APIs to invoke 2
the services 5
Source: https://thenewcircle.com/s/post/1340/Deep_Dive_Into_Binder_Presentation.htm#slide-11
29
Local Bound Service
• If the Service is only used locally within the app:
− Easier to extend the Binder class instead of using AIDL
public class LocalService extends Service {
// Binder given to clients.
private final IBinder binder = new LocalBinder();
// Random number generator.
private final Random mGenerator = new Random();
/**
* Class used for the client Binder. Because we know this service always
* runs in the same process as its clients, we don't need to deal with IPC.
*/
public class LocalBinder extends Binder {
LocalService getService() {
// Return this instance of LocalService so clients can call public methods.
return LocalService.this;
}
}
@Override
public IBinder onBind(Intent intent) {
return binder;
}
/** Method for clients. */
public int getRandomNumber() {
return mGenerator.nextInt(100);
}
}
30
ContentProvider components
• Standardized mechanism to share (structured) data among applications
− Contacts data, SMS data, media metadata,…
• SQLite-like data management
− Insert, Delete, Update, Query
• URIs to address ContentProviders and their data:
content://com.example.android.BookProvider/book/23
Scheme Authority name Path Segments
com.example.android.BookProvider
Table: book Table: author
id Title Author ID id Name
1 Embedded Android 1 1 K. Yaghmour
23 Pro Android 4 42 42 S. Komatinie & D. MacLean
31
Example Querying a Provider
String URL = "content://com.example.android.BookProvider/book/";
mCursor = getContentResolver().query(
URL, // The content URI of the books table
mProjection, // String[] of table columns to return for each row
mSelectionClause // Selection criteria (“where” clause)
mSelectionArgs, // Selection criteria (arguments for “where” clause)
mSortOrder); // The sort order for the returned rows
int numcols = mCursor.getColumnCount();
String[] colnames = mCursor.getColumnNames();
mCursor.moveToFirst();
while (cursor.moveToNext()) {
// Do something with the row
int id = mCursor.getInt(0); // id is first column
String title = mCursor.getString(1); // Title is in 2nd column
int author_id = mCursor.getInt(2); // Author ID is in 3rd column (x-ref to author
table)
}
mCursor.close();
32
BroadcastReceiver components
• Mailbox for broadcast Intent messages
− Define filters which kind of messages to receive (publish-subscribe pattern)
− Action string, category,…
• Registered in the application manifest or dynamically at runtime
− Since Android 8.0 (API level 26): cannot use the manifest to declare a receiver for most
implicit broadcasts; use a context-registered receiver while app is running in foreground
− registerReceiver(BroadcastReceiver receiver, IntentFilter filter)
− Exceptions: https://developer.android.com/guide/components/broadcast-exceptions
• Very short-lived, bound to processing the Intent
• Common operations to listen to with a BroadcastReceiver
− Location changes, SMS/MMS received, etc.
• Apps can send custom Broadcasts with the sendBroadcast(Intent) method
33
Android 11: New restrictions on package visibility
• Pre-Android 11: Apps could discover other apps and components
− queryIntentActivities(), getPackageInfo(), or getInstalledApplications()
− Could send explicit Intents to other apps
• Since Android 11:
− List of installed applications considered personal and sensitive user data
− Android restricts which packages an app can see and explicitly contact
− Automatically visible: own app, certain system packages, any app that starts or
binds to a service in your app or accesses a content provider in your app, …
− Everything else:
− App needs to declare <query> element in Manifest based on package
name, by intent signature, or by provider authority they want to access
− Request QUERY_ALL_PACKAGES privilege (not recommended by Google, extra
app vetting)
https://developer.android.com/training/package-visibility
34
Android 11: New restrictions on package visibility
• <query> to specify package name:
<manifest package="com.example.game">
<queries>
<package android:name="com.example.store" />
<package android:name="com.example.services" />
</queries>
...
</manifest>
• <query> to specify IntentFilter signature (with some restrictions on the filter attributes)
<manifest package="com.example.game">
<queries>
<intent>
<action android:name="android.intent.action.SEND" />
<data android:mimeType="image/jpeg" />
</intent>
</queries>
...
</manifest>
https://developer.android.com/training/package-visibility/declaring
35
Recap
• Android apps consist of several components (Activities, Services, etc.)
• Components are registered in the system through the application
Manifest.xml
− BroadcastReceivers need to be registered at runtime with a few
exceptions for explicit Broadcasts targeting the application
• Primary channel for Inter-Component-Communication are Intents
− Intents are an indirect communication that is relayed via the
ActivityManagerService
− Explicit target component or implicit via attributes (Action string,
category, mime type, etc)
− Bound services and ContentProviders can also be contacted directly after
receiving a reference from the Android system
• Since Android 11: Restrictions on package visibility
36