Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,11 @@ If the `PermissionStatus` is `denied` or `unknown`, we can ask the user for the
Future<PermissionStatus> permissionStatus = NotificationPermissions.requestNotificationPermissions({NotificationSettingsIos iosSettings, bool openSettings});
```

On Android, if the permission is `denied`, this method will open the app settings.
On Android 12 and lower, if the permission is `denied`, this method will open the app settings.
On Android 13 and higher system dialog asking for permission will be displayed. To be able to request permission on Android 13+ add the following permission to `AndroidManifest.xml`:
```xml
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
```

In iOS, if the permission is `unknown` or `provisional`, it will show an alert window asking the user for the permission. On the other hand, if the permission is `denied` it has the same behaviour as Android, opening the app settings.
Also in iOS if you set `openSettings` to false settings window won't be opened. You will get `denied` status.
Expand Down
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ rootProject.allprojects {
apply plugin: 'com.android.library'

android {
compileSdkVersion 29
compileSdkVersion 33

defaultConfig {
minSdkVersion 16
Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,44 @@
package com.vanethos.notification_permissions;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.provider.Settings;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.NotificationManagerCompat;

import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.PluginRegistry;

public class MethodCallHandlerImpl implements MethodCallHandler {
public class MethodCallHandlerImpl implements MethodCallHandler, PluginRegistry.RequestPermissionsResultListener {
private static final String PERMISSION_GRANTED = "granted";
private static final String PERMISSION_DENIED = "denied";

private static final int REQUEST_CODE = MethodCallHandlerImpl.class.hashCode();

private final Context applicationContext;
@Nullable private Activity activity;

@Nullable
private Activity activity;

@Nullable
private MethodChannel.Result permissionRequestResult;

public MethodCallHandlerImpl(Context applicationContext) {
this.applicationContext = applicationContext;
}

public void setActivity(@Nullable Activity activity) {
this.activity = activity;
this.permissionRequestResult = null;
}

@Override
Expand All @@ -41,6 +54,13 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result
return;
}

// Since TIRAMISU (API level 33) POST_NOTIFICATIONS permission can be requested
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
permissionRequestResult = result;
activity.requestPermissions(new String[]{Manifest.permission.POST_NOTIFICATIONS}, REQUEST_CODE);
return;
}

// https://stackoverflow.com/a/45192258
final Intent intent = new Intent();

Expand Down Expand Up @@ -69,9 +89,26 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result
}
}

@Override
public boolean onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode != REQUEST_CODE || permissions.length == 0) {
return false;
}

if (permissionRequestResult != null) {
permissionRequestResult.success(
grantResults[0] == PackageManager.PERMISSION_GRANTED
? PERMISSION_GRANTED
: PERMISSION_DENIED
);
}

return true;
}

private String getNotificationPermissionStatus() {
return (NotificationManagerCompat.from(applicationContext).areNotificationsEnabled())
? PERMISSION_GRANTED
: PERMISSION_DENIED;
? PERMISSION_GRANTED
: PERMISSION_DENIED;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

import android.app.Activity;
import android.content.Context;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.embedding.engine.plugins.activity.ActivityAware;
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
Expand All @@ -27,6 +29,9 @@ public static void registerWith(io.flutter.plugin.common.PluginRegistry.Registra
@Nullable
private MethodCallHandlerImpl methodCallHandler;

@Nullable
ActivityPluginBinding activityPluginBinding;

@Override
public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {
onAttachedToEngine(binding.getApplicationContext(), binding.getBinaryMessenger());
Expand All @@ -48,7 +53,9 @@ private void onAttachedToEngine(Context applicationContext, BinaryMessenger mess

@Override
public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) {
activityPluginBinding = binding;
onActivityChanged(binding.getActivity());
startListeningForPermissionResult();
}

@Override
Expand All @@ -64,11 +71,24 @@ public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBindin
@Override
public void onDetachedFromActivity() {
onActivityChanged(null);
stopListeningForPermissionResult();
}

private void onActivityChanged(@Nullable Activity activity) {
if (methodCallHandler != null) {
methodCallHandler.setActivity(activity);
}
}

private void startListeningForPermissionResult() {
if (this.activityPluginBinding != null && methodCallHandler != null) {
activityPluginBinding.addRequestPermissionsResultListener(methodCallHandler);
}
}

private void stopListeningForPermissionResult() {
if (this.activityPluginBinding != null && methodCallHandler != null) {
activityPluginBinding.removeRequestPermissionsResultListener(methodCallHandler);
}
}
}
4 changes: 2 additions & 2 deletions example/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"

android {
compileSdkVersion 30
compileSdkVersion 33

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
Expand All @@ -45,7 +45,7 @@ android {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.example.example"
minSdkVersion 16
targetSdkVersion 30
targetSdkVersion 33
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
Expand Down
4 changes: 4 additions & 0 deletions example/android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.example">

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

<application
android:label="example"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
Expand Down
2 changes: 1 addition & 1 deletion example/android/build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
buildscript {
ext.kotlin_version = '1.3.50'
ext.kotlin_version = '1.7.10'
repositories {
google()
jcenter()
Expand Down
2 changes: 1 addition & 1 deletion example/android/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-all.zip