I want to create a function that calls the notification channel settings for another app. I don't know the channel IDs for the other app. Is there a way to do that?
You cannot access the notification channels of another app, neither what channels there are nor what their settings are.
The only thing you can do is to open the notification settings overview of another app, given its package name (Facebook for example):
Intent intent = new Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS)
.putExtra(Settings.EXTRA_APP_PACKAGE, "com.facebook.katana");
startActivity(intent);
This can be done through reflection. Note that more hidden APIs are blocked with every Android release, so this is not a long-term solution.
First, add the android.permission.STATUS_BAR_SERVICE permission to AndroidManifest.xml. My IDE warns that this is a system app permission, but my device (running Xiaomi's MIUI 12.5, Android 11) allows it.
<manifest ...>
<uses-permission android:name="android.permission.STATUS_BAR_SERVICE"
tools:ignore="ProtectedPermissions"/>
...
</manifest>
Now, any app's channels can be accessed:
// Retreive an instance of the INotificationManager service using the
// hidden NotificationManager.getService static method.
val sINM = NotificationManager::class.java.getMethod("getService").invoke(null)
// Find the INotificationManager.getNotificationChannelsForPackage method.
val getNotificationChannelsForPackageMethod =
sINM::class.java.getMethod(
"getNotificationChannelsForPackage",
java.lang.String::class.java,
Integer.TYPE,
java.lang.Boolean.TYPE,
)
// Retreive information about an app.
val applicationInfo = packageManager.getApplicationInfo("com.example", 0)
// Retreive a ParceledListSlice of the app's NotificationChannel objects.
// The boolean is the "includeDeleted" parameter.
val channelsSlice = getNotificationChannelsForPackageMethod.invoke(
sINM,
applicationInfo.packageName,
applicationInfo.uid,
false,
)
// Retreive the channels in the form of an ArrayList<NotificationChannel>.
val channels = channelsSlice::class.java.getMethod("getList")
.invoke(channelsSlice) as ArrayList<NotificationChannel>
AOSP references:
NotificationManager.java
INotificationManager.aidl
BaseParceledListSlice.java
No, You can not handle other app Notification Channel because every change has id and without id System can not get that channel.
According to my knowledge we can not get notification channel ids of other app.
You can access notification channels of other apps using NotificationListenerService, which is in-built in SDK. After registering the service and giving notification access permission (using Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS")), it is possible to just call something like the following method:
private List<NotificationChannel> getChannels() {
final var ranking = getCurrentRanking();
final var channelsList = new ArrayList<NotificationChannel>();
for (var notification : getActiveNotifications()) {
final var currentRanking = new Ranking();
ranking.getRanking(notification.getKey(), currentRanking);
channelsList.add(currentRanking.getChannel());
}
return channelsList;
}
Related
6
I'm currently developing an app for Android that uses the NotificationListenerService, which requires that the user will enable notification access for my app under Setting -> Security -> Notification Access.
My question is that can I redirect the user to this place so they will enable it? So far I only managed to direct them to Setting -> Security window.
Also, is it possible to first check if the user enabled notification access for my app already and only then redirect them?
For Flutter
After a long search, I found the solution that will show the intended notification settings.
This is only for Flutter.
I found an app_settings plugin. Just add it in pubspec.yaml and install it.
After that just one line of code.
RaisedButton(
onPressed: () {
// AppSettings.openLocationSettings();
AppSettings.openNotificationSettings();
// openWIFISettings();
},
)
For Java
To open the settings for a specific channel, you can use ACTION_CHANNEL_NOTIFICATION_SETTINGS:
Intent intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS)
.putExtra(Settings.EXTRA_APP_PACKAGE, context.getPackageName())
.putExtra(Settings.EXTRA_CHANNEL_ID, yourChannelId);
startActivity(intent);
Using ACTION_APP_NOTIFICATION_SETTINGS will open settings of list all channels of the app:
Intent intent = new Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS)
.putExtra(Settings.EXTRA_APP_PACKAGE, context.getPackageName());
startActivity(intent);
For Notification check, you can use "areNotificationEnabled" method.
You can read at below doc/
https://developer.android.com/reference/android/support/v4/app/NotificationManagerCompat.html#areNotificationsEnabled()
when the app is totally closed, I don't receive calls, I don't know why
can any one help me ??
I'm using this code to setup mesibo :
Mesibo.getInstance().init(this)
Mesibo.addListener(this)
Mesibo.setRestartListener(this)
Mesibo.setSecureConnection(true)
Mesibo.setAccessToken(user?.mesiboToken)
val myProfile = UserProfile()
myProfile.name = user?.name
myProfile.address = user?.mesiboAddress
Mesibo.setDatabase("mydb", 0)
MesiboCall.getInstance().init(applicationContext)
Mesibo.setAppInForeground(this, 0, true)
Mesibo.start()
val profiles = Mesibo.getUserProfiles()
profiles.forEach { (key, profile) ->
val split = key.split("-")
if (!split.isNullOrEmpty()) {
val userProfile = UserProfile()
userProfile.name = split[0]
userProfile.address = key
Mesibo.setUserProfile(userProfile, false)
}
}
Mesibo.setPushToken(TokenManager.getInstance().getFCMToken())
also I have implement all Mesibo Call Listeners
Once the operating system suspends your app, it will not be able to
run and hence receive new messages or calls until it is activated
again. Hence, when your app has a new message or a new incoming call,
you need to wake up your app from the sleep state to deliver messages
and calls in real-time. This is where you need to send push
notifications. Push notification wakes up your app and moves it from
the sleep state to the active state. Once the app moves to the active
state, Mesibo will automatically connect and start receiving messages
and calls.
From https://mesibo.com/documentation/api/push-notifications/
I am trying to create an application that allows sending any website as data, but when I write the address it does not load in the second activity.
Note: in the manifest I already put this code <uses-permission android: name = "android.permission.INTERNET" />
This is my code
MainActivity
bt_ir.setOnClickListener {
val sitio = pt_sitio.text.toString()
val inten = Intent (this, MainActivity2_Webview::class.java)
inten.putExtra("Clave", sitio)
startActivity(inten)
}
Second Activity
val intent = intent
val name = intent.getStringExtra("Clave")
wv_sitio.loadUrl("http//:${name}")
bt_atras.setOnClickListener {
finish()
}
You have a typo in your URL string after http, it should be :// instead of //:
As well as that, if you're using http instead of https, you might need to set usesCleartextTraffic in the manifest to true - this was the default before API 28, if you target 28+ it defaults to false and you have to explicitly enable it.
There's also a more complex system with a Network security configuration if you want more fine control over which sites are allowed through.
Depending on what's going on in your WebView, you might need use setMixedContentMode to ALWAYS_ALLOW or something - this is a security problem, so using https would be better, but that's up to you!
I know that on Android you can retrieve a list of current active notifications with NotificationListenerService. However is it possible to retrieve a list of old notifications (meaning not active anymore).
I know that there is a feature in the Android OS called Notification Log. Is it possible to get kind of the same content just for my application only? Or does this have to be handled on the application level to keep that kind of history?
Unfortunately Notification Log uses the method getHistoricalNotifications of NotificationManagerService that requires ACCESS_NOTIFICATIONS permission. For this reason it is reserved to system apps:
/**
* System-only API for getting a list of recent (cleared, no longer shown) notifications.
*
* Requires ACCESS_NOTIFICATIONS which is signature|system.
*/
#Override
public StatusBarNotification[] getHistoricalNotifications(String callingPkg, int count) {
// enforce() will ensure the calling uid has the correct permission
getContext().enforceCallingOrSelfPermission(
android.Manifest.permission.ACCESS_NOTIFICATIONS,
"NotificationManagerService.getHistoricalNotifications");
StatusBarNotification[] tmp = null;
int uid = Binder.getCallingUid();
// noteOp will check to make sure the callingPkg matches the uid
if (mAppOps.noteOpNoThrow(AppOpsManager.OP_ACCESS_NOTIFICATIONS, uid, callingPkg)
== AppOpsManager.MODE_ALLOWED) {
synchronized (mArchive) {
tmp = mArchive.getArray(count);
}
}
return tmp;
}
The only viable option is to create a NotificationListenerService, implement the method onNotificationPosted and keep track locally about new notifications posted by apps.
I'm currently developing an app for Android that uses the NotificationListenerService, which requires that the user will enable notification access for my app under Setting -> Security -> Notification Access.
My question is that can I redirect the user to this place so they will enable it? So far I only managed to direct them to Setting -> Security window.
Also, is it possible to first check if the user enabled notification access for my app already and only then redirect them?
You can open the NotificationAccessSettingsActivity by using the following Intent, but I'm not sure about checking to see if they've already enabled your app.
startActivity(new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS"));
Alternatively, for API 22+:
startActivity(new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS));
Many Thanks to #adneal and #Waboodoo. I am posting this for an complete answer
Check permission granted or not using this method
private boolean isNotificationServiceRunning() {
ContentResolver contentResolver = getContentResolver();
String enabledNotificationListeners =
Settings.Secure.getString(contentResolver, "enabled_notification_listeners");
String packageName = getPackageName();
return enabledNotificationListeners != null && enabledNotificationListeners.contains(packageName);
}
Then show settings activity, if necessary
boolean isNotificationServiceRunning = isNotificationServiceRunning();
if(!isNotificationServiceRunning){
startActivity(new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS));
}
You can always use the notification manager to check if notifications are enabled at the OS level:
NotificationManagerCompat.from(context).areNotificationsEnabled()