- Android Apps can send and receive the messages and events from the android systen and other apps. Like Publis-subscribe patterns.
- Therefore, delivery times of broadcasts are not guaranteed
- Apps need to register the receiver to receive the events.
- Whenever possible, keep broadcasts private to your app.
- The system automatically sends broadcasts when various system events occur, such as when the system switches in and out of airplane mode. System broadcasts are sent to all apps that are subscribed to receive the event.
- When app is in cached state the less important brodcast are deferred suct as
ACTION_SCREEN_ON
. once the app comes is in active state the all deferred broadcast ready to delivered.
- The
NETWORK_STATE_CHANGED_ACTION
broadcast doesn't receive information about the user's location or personally identifiable data.
- Custom broadcast need to be regostered dynamically. in code.
Android 7.0 (API level 24) and higher don't send the following system broadcasts
ACTION_NEW_PICTURE ACTION_NEW_VIDEO
Also, apps targeting Android 7.0 and higher must register the CONNECTIVITY_ACTION broadcast using registerReceiver(BroadcastReceiver, IntentFilter). Declaring a receiver in the manifest doesn't work.
Apps can receive broadcasts in two ways: through manifest-declared receivers and context-registered receivers.
- Context-registered they receive the broadcast as long as their registering content is valid. like if they registered using Activity context they will receive the broadcast untill the activity not destroyed. if they registerd using applicationContext than will receive broadcast throughout the application.
exported
it is define that other apps can access your broadcast or not so set it to false if you want only your app receive the broadcast.
val listenToBroadcastsFromOtherApps = false
val receiverFlags = if (listenToBroadcastsFromOtherApps) {
ContextCompat.RECEIVER_EXPORTED
} else { ContextCompat.RECEIVER_NOT_EXPORTED }
Implementing Broadcast
class MyBroadcastReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
intent?.apply { }
} }
// declare in manifest
receiver android:name=".MyBroadcastReceiver" android:exported="false"> <intent-filter> <action android:name="APP_SPECIFIC_BROADCAST" /> </intent-filter>
</receiver>
// register in Activity
val br: BroadcastReceiver = MyBroadcastReceiver()
onStart(){
val filter = IntentFilter(APP_SPECIFIC_BROADCAST)val listenToBroadcastsFromOtherApps = false
val receiverFlags = if (listenToBroadcastsFromOtherApps) { ContextCompat.RECEIVER_EXPORTED
} else {
ContextCompat.RECEIVER_NOT_EXPORTED
}
ContextCompat.registerReceiver(context, br, filter, receiverFlags)
}
onStop(){
unregisterReceiver(android.content.BroadcastReceiver)
}
- The BroadcastReceiver is deactivated after
onReceive()
- Thus, broadcast receivers should not initiate long-running background threads.
- The system can stop the process at any moment after
onReceive()
to reclaim memory, terminating the created thread. - schedule a JobService from the receiver using the JobScheduler so the system knows the process is still working.
-
sendOrderedBroadcast(Intent, String)
- method sends broadcasts to one receiver at a time.
- As each receiver executes in turn, it can propagate a result to the next receiver
- it can completely abort the broadcast so that it won't be passed to other receivers.
- the order of execution is define by
priority
, if thepriority
is same than it execute in arbitrary order.
-
sendBroadcst(intent)
- sends broadcasts to all receivers in an undefined order
- This is more efficient, but means that receivers cannot read results from other receivers
Intent().also { intent ->
intent.setAction("com.example.broadcast.MY_NOTIFICATION")
intent.putExtra("data", "Nothing to see here, move along.")
sendBroadcast(intent)
}
- you can specify a permission parameter. Only receivers who have requested that permission with the tag in their manifest (and subsequently been granted the permission if it is dangerous) can receive the broadcast
sendBroadcast(Intent(BluetoothDevice.ACTION_FOUND), Manifest.permission.BLUETOOTH_CONNECT)
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>
// Receiving With permission
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>
<receiver android:name=".MyBroadcastReceiver"
android:permission="android.permission.BLUETOOTH_CONNECT">
<intent-filter>
<action android:name="android.intent.action.ACTION_FOUND"/>
</intent-filter>
</receiver>
var filter = IntentFilter(Intent.ACTION_FOUND)
registerReceiver(receiver, filter, Manifest.permission.BLUETOOTH_CONNECT, null )
- use the LocalBroadcastManager to sendBroadcast(). in locally inside the app only.
- If many apps have registered to receive the same broadcast in their manifest, it can cause the system to launch a lot of apps, causing a substantial impact on both device performance and user experience. To avoid this, prefer using context registration over manifest declaration
- Do not broadcast sensitive information using an implicit intent
- There are three ways to control who can receive your broadcasts:
- You can specify a permission when sending a broadcast
- setPackage(), so that only list of package will receive the broadcast.
- eported = false.
- Do not start activities from broadcast receivers because the user experience is jarring; especially if there is more than one receiver
- receiver's onReceive(Context, Intent) method runs on the main thread,
As part of the Android 8.0 (API level 26) background execution limits, apps that target the API level 26 or higher can't register broadcast receivers for implicit broadcasts in their manifest
- ACTION_LOCKED_BOOT_COMPLETED, ACTION_BOOT_COMPLETED
- ACTION_USER_INITIALIZE, android.intent.action.USER_ADDED, android.intent.action.USER_REMOVED
- android.intent.action.TIME_SET, ACTION_TIMEZONE_CHANGED, ACTION_NEXT_ALARM_CLOCK_CHANGED
and so on.
Q if we not defined receiver in amnifest and write to register the code using context register in Activity then what happen?
- If the receiver is successfully registered then it will receive the events or broadcast.
- Manage access to data stored by itself or stored by other apps and provide a way to share data with other apps.
- you can configure a content provider to let other applications securely access and modify your app data
- The Android framework includes content providers that manage data such as
audio, video, images, and personal contact information
. CursorLoader
to load data in the background
- To access an existing content provider in another application
- Creating a new content provider in your application to share data with other applications
- Returning custom search suggestions for your application through the search framework using
SearchRecentSuggestionsProvider
- Synchronizing application data with your server using an implementation of
AbstractThreadedSyncAdapter
- Loading data in your UI using a
CursorLoader
- access data in a content provider
- UI<->ContentLoader<->ContentResolver<->ContentProvider<->DataStore.
- Youe Application has to request specific permission to use the content provider in manifext.
// Queries the UserDictionary and returns resultscursor = contentResolver.query(
UserDictionary.Words.CONTENT_URI, // The content URI of the words table
projection, // The columns to return for each row
selectionClause, // Selection criteria
selectionArgs.toTypedArray(), // Selection criteria
sortOrder // The sort order for the returned rows
)
- It return the
cursor
as we iterate the data on the main thread or UI thread. We need to process the cursor or data on the background thread. for that we can use threading or HereLoaders
comes , that by default load the content on the backgroud UI. - Advantages of using loader is , its provide the latest/update data always as anychages happen in the third party app it will update automatically.
-
URI that identifies data in a provider
-
content://user_dictionary/words
- The
content://
string is the scheme, which is always present and identifies this as a content URI. - The
user_dictionary
string is the provider's authority. - The
words
string is the table's path.
- The
- Request read access permission for the provider.
- sends a query to the provider.
-
Example of permissions
-
The User Dictionary Provider requires the
android.permission.READ_USER_DICTIONARY
permission to retrieve data from it. The provider has a separateandroid.permission.WRITE_USER_DICTIONARY
permission for inserting, updating, or deleting data. -
By default, all applications can read from or write to your provider, even if the underlying data is private, because by default your provider doesn't have permissions set.
-
Insert, update, and delete data
Authority (android:authorities)
- Provider class name
(android:name)
- Permissions
android:grantUriPermissions:
temporary permission flagandroid:permission:
single provider-wide read/write permissionandroid:readPermission
: provider-wide read permissionandroid:writePermission:
provider-wide write permission
- Storage Provider : - just like file system apps in android.