This post will cover what the Uri, Scheme and SSP(Scheme Specific PART) are.
Intent has information called data. Data is expressed as Uri(Uniform Resource Identifier), which has Scheme, Host and SSP. You might be familiar with Scheme and Host, but SSP is not.
First, I will briefly explain Intent, and then introduce Uri, Scheme, and SSP.
Intent
Intent is used when sending and receiving events in Android. In Intent, there is an item called Data. Data represents what information the Intent has.
For instance, when executing an activity, the intent is used to decide which activity to execute.
Intent can be created and data variable can be set as follows.
val intent = Intent(Intent.ACTION_VIEW)
intent.addCategory(Intent.CATEGORY_DEFAULT)
intent.addCategory(Intent.CATEGORY_BROWSABLE)
val uri: Uri = Uri.parse("http://google.com")
intent.data = uri
So, we can say that the data of Intent is Uri and it represents what data intent has.
Uri
Uri stands for Uniform Resource Identifier and is an identifier that represents a resource. Url used on the Internet is a sub-concept of Uri.
The syntax of Uri is like this:
<scheme>://<host>:<port>[<path>|<pathPrefix>|<pathPattern>]
I took the above http://google.com
as an example. Here, http
is the scheme and google.com
is the host. There was no port and path.
You can make a string into a Uri object using Uri.parse()
as follows.
val uri: Uri = Uri.parse("http://google.com")
Log.d(TAG, "scheme: ${uri.scheme}, host: ${uri.host}, " +
"port: ${uri.port}, path: ${uri.path}")
Output:
MainActivity: scheme: http, host: google.com, port: -1, path:
Why use Uri
Uri is an identifier representing a resource.
For example, when the user clicks on a link called http://google.com
, the app makes this an intent and calls startActivity()
.
And the system looks for an app that can process the data from the Intent. At this time, it searches for apps related to Uri's scheme and host. (Under the hood, ActivityManager asks PackageManager for the intent and then start an activity)
When you run the following code, the system will find and run an app associated with this Intent. Generally, browsers can handle these intents, so when you run the code, the browser is launched.
val intent = Intent(Intent.ACTION_VIEW)
intent.addCategory(Intent.CATEGORY_DEFAULT)
intent.addCategory(Intent.CATEGORY_BROWSABLE)
val uri: Uri = Uri.parse("http://google.com")
intent.data = uri
startActivity(intent)
One way to express what kind of intent your app can handle is AndroidManifest's IntentFilter. The system reads AndroidManifest.xml to categorize which intents this app can handle, and when sending an intent, it refers to this information to determine who to send.
Looking at the Manifest of the Chrome app, the IntentFilter of the Activity is set as follows.
If you look a little closer, you can see that the action and category of the above Intent are the same.
Also, the scheme is defined as http
in the data item. This data means Uri, and it means that Uri with the scheme http and https can all be processed. In other words, it doesn't matter what host comes in.
<activity android:name="com.google.android.apps.chrome.IntentDispatcher">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="http"/>
<data android:scheme="https"/>
</intent-filter>
</activity>
In this way, the App declares a Uri it can process in the Manifest, so the system can compare the Uri information to determine who to deliver the Intent to.
If some activity can only handle google.com
as host, you can set IntentFilter like this: If you look at the data item, the host has been set.
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="http" android:host="google.com"/>
<data android:scheme="https" android:host="google.com"/>
</intent-filter>
SSP(Scheme Specific Part)
Above, we said that the syntax of Uri is like this.
<scheme>://<host>:<port>[<path>|<pathPrefix>|<pathPattern>]
However, we can use this syntax when we define SSP.
<scheme>:<scheme-specific-part>#fragment
Compared to the first syntax, there is no //
. The right part of :
is called SSP (Scheme Specific Part). And the right side of #
is called fragment.
Sometimes Android uses SSP format Uri.
For example, the ACTION_PACKAGE_ADDED
intent is delivered when the app is installed.
Intent { act=android.intent.action.PACKAGE_ADDED dat=package:com.codechacha.myapplication flg=0x4000010 (has extras) }
The Uri of this intent is package:com.codechacha.myapplication
. The scheme is package
and the SSP is com.codechacha.myapplication
. There is no fragment.
As another example, the Uri of the Intent sent when making a call is in the form of tel:010-1111-1111
. There is a scheme called tel
, and detailed information about the scheme is stored in the SSP.
Both sms
and mms
are expressed in SSP the same way.
Define SSP in IntentFilter
When the app is deleted from the device, it broadcasts an intent of PACKAGE_FULLY_REMOVED
. This intent uses SSP to represent Uri, and passes the app's package name in the SSP, like package:com.example.myapplication
.
If you want to receive PACKAGE_FULLY_REMOVED
from the receiver, you need to set the scheme to package
as follows.
With this setting, you will receive that event when an app is deleted.
<receiver android:name=".MyReceiver">
<intent-filter>
<action android:name="android.intent.action.PACKAGE_FULLY_REMOVED" />
<data android:scheme="package"/>
</intent-filter>
</receiver>
But what if you want to receive intents only when the app com.example.myapplication
is deleted?
You can set the IntentFilter to ssp as com.example.myapplication
. With this setting, it is delivered only when it matches the SSP of the intent and the SSP of the intent filter.
<receiver android:name=".MyReceiver">
<intent-filter>
<action android:name="android.intent.action.PACKAGE_FULLY_REMOVED" />
<data android:scheme="package" android:ssp="com.example.myapplication"/>
</intent-filter>
</receiver>
If you register a receiver with Context.registerReceiver()
instead of Manifest, you can create an IntentFilter object as follows. You can use addDataSchemeSpecificPart()
when setting up the SSP.
val intentFilter = IntentFilter()
intentFilter.addAction(Intent.ACTION_PACKAGE_FULLY_REMOVED)
intentFilter.addDataScheme("package")
intentFilter.addDataSchemeSpecificPart("com.example.myapplication",
PatternMatcher.PATTERN_LITERAL)
val receiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
Log.d("MyReceiver", "onReceive: $intent")
}
}
context.registerReceiver(receiver, intentFilter)
Deliver Uri with SSP
We have seen ways to define IntentFilter which can receive Intents with SSP.
Here, i will show you how to send Intents with SSP from my application.
You can create a Uri object with SSP.
val intent = Intent("com.custom.intent.action")
intent.data = Uri.fromParts("package" /* scheme */,
"com.example.myapplication" /* ssp */,
null /* fragment */)
When you start or broadcast an intent with SSP, it can be delivered to apps with an intent filter set up like this:
<intent-filter>
<action android:name="com.custom.intent.action" />
<data android:scheme="package" android:ssp="com.example.myapplication"/>
</intent-filter>
Of course, it is also delivered to apps where only the scheme is set.
<intent-filter>
<action android:name="com.custom.intent.action" />
<data android:scheme="package"/>
</intent-filter>
Example where Fragment is used
While developing Android, I haven't seen fragments used. Please let me know if anyone has seen it.
clean up
We have looked closely at Intent and SSP. There are 2 syntax. One is for defining data without SSP, the other is for defining with SSP. Each has a slightly different way of creating IntentFilter and Intent objects.
I hope reading this article helps you understand Intent a bit.
Related Posts
- How to download and build Android 13, AOSP
- Notification permission request, pop up notification in Android 13
- Resolve `Access blocked: ComponentInfo` error on Android 13
- Fix error "android gradle plugin requires java 11 to run. you are currently using java 1.8."
- Android - Vibration, Vibrator, VibrationEffect example
- How to get phone number in Android
- How to create Bugreports and Logcat with ADB in Android
- Clear application user data with ADB in Android
- How to disable/enable apps with ADB in Android
- How to find PID of a package with adb in Android
- How to grant/revoke permissions with adb in Android
- How to install an apk(app) with adb in Android
- How to kill a process/package from ADB in Android
- How to transfer files using adb push/pull command in Android
- How to capture the screen from adb in Android
- How to uninstall/install system apps from adb in Android
- How to change Settings values from adb in Android
- How to Factory reset with ADB in Android
- How to get logcat from ADB command in Android
- How to capture Heap Dump from app with ADB in Android
- How to force stop an app with adb in Android
- How to start/stop a service from adb in Android
- How to send/broadcast an intent from adb command in Android
- How to start an activity from adb in Android
- How to generate input from adb in Android
- How to check SQLite DB table in Android Studio
- How to get memory info and thread list from adb in Android
- Android - Uri, Scheme and SSP(Scheme Specific Part)
- How to parse a xml file with XmlResourceParser in Android
- Android - Signing an apk with Platfom key
- How to fix "Cleartext HTTP ... not permitted" for Android development
- How to fix "kvm permission denied" for Android Emulator
- Using ADB over Wifi for Android development