react-native-notify-kit 9.1.22 → 9.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -2
- package/android/build.gradle +67 -35
- package/android/proguard-rules.pro +14 -1
- package/android/schemas/app.notifee.core.database.NotifeeCoreDatabase/1.json +44 -0
- package/android/schemas/app.notifee.core.database.NotifeeCoreDatabase/2.json +51 -0
- package/android/src/androidTest/java/app/notifee/core/ExampleInstrumentedTest.java +25 -0
- package/android/src/androidTest/java/app/notifee/core/database/NotifeeCoreDatabaseTest.java +55 -0
- package/android/src/main/AndroidManifest.xml +71 -4
- package/android/src/main/java/app/notifee/core/AlarmPermissionBroadcastReceiver.java +25 -0
- package/android/src/main/java/app/notifee/core/BlockStateBroadcastReceiver.java +164 -0
- package/android/src/main/java/app/notifee/core/ChannelManager.java +350 -0
- package/android/src/main/java/app/notifee/core/ContextHolder.java +33 -0
- package/android/src/main/java/app/notifee/core/EventBus.java +63 -0
- package/android/src/main/java/app/notifee/core/EventSubscriber.java +82 -0
- package/android/src/main/java/app/notifee/core/ForegroundService.java +347 -0
- package/android/src/main/java/app/notifee/core/InitProvider.java +93 -0
- package/android/src/main/java/app/notifee/core/KeepForSdk.java +26 -0
- package/android/src/main/java/app/notifee/core/Logger.java +68 -0
- package/android/src/main/java/app/notifee/core/Notifee.java +570 -0
- package/android/src/main/java/app/notifee/core/NotifeeAlarmManager.java +352 -0
- package/android/src/main/java/app/notifee/core/NotificationAlarmReceiver.java +42 -0
- package/android/src/main/java/app/notifee/core/NotificationManager.java +939 -0
- package/android/src/main/java/app/notifee/core/NotificationPendingIntent.java +191 -0
- package/android/src/main/java/app/notifee/core/NotificationReceiverActivity.java +39 -0
- package/android/src/main/java/app/notifee/core/NotificationReceiverHandler.java +144 -0
- package/android/src/main/java/app/notifee/core/Preferences.java +79 -0
- package/android/src/main/java/app/notifee/core/RebootBroadcastReceiver.java +39 -0
- package/android/src/main/java/app/notifee/core/ReceiverService.java +281 -0
- package/android/src/main/java/app/notifee/core/Worker.java +87 -0
- package/android/src/main/java/app/notifee/core/database/NotifeeCoreDatabase.java +77 -0
- package/android/src/main/java/app/notifee/core/database/WorkDataDao.java +52 -0
- package/android/src/main/java/app/notifee/core/database/WorkDataEntity.java +68 -0
- package/android/src/main/java/app/notifee/core/database/WorkDataRepository.java +107 -0
- package/android/src/main/java/app/notifee/core/event/BlockStateEvent.java +102 -0
- package/android/src/main/java/app/notifee/core/event/ForegroundServiceEvent.java +48 -0
- package/android/src/main/java/app/notifee/core/event/InitialNotificationEvent.java +50 -0
- package/android/src/main/java/app/notifee/core/event/LogEvent.java +74 -0
- package/android/src/main/java/app/notifee/core/event/MainComponentEvent.java +33 -0
- package/android/src/main/java/app/notifee/core/event/NotificationEvent.java +107 -0
- package/android/src/main/java/app/notifee/core/interfaces/EventListener.java +39 -0
- package/android/src/main/java/app/notifee/core/interfaces/MethodCallResult.java +27 -0
- package/android/src/main/java/app/notifee/core/model/ChannelGroupModel.java +48 -0
- package/android/src/main/java/app/notifee/core/model/ChannelModel.java +126 -0
- package/android/src/main/java/app/notifee/core/model/IntervalTriggerModel.java +63 -0
- package/android/src/main/java/app/notifee/core/model/NotificationAndroidActionModel.java +125 -0
- package/android/src/main/java/app/notifee/core/model/NotificationAndroidModel.java +688 -0
- package/android/src/main/java/app/notifee/core/model/NotificationAndroidPressActionModel.java +150 -0
- package/android/src/main/java/app/notifee/core/model/NotificationAndroidStyleModel.java +336 -0
- package/android/src/main/java/app/notifee/core/model/NotificationModel.java +72 -0
- package/android/src/main/java/app/notifee/core/model/TimestampTriggerModel.java +206 -0
- package/android/src/main/java/app/notifee/core/model/package-info.java +4 -0
- package/android/src/main/java/app/notifee/core/utility/AlarmUtils.java +52 -0
- package/android/src/main/java/app/notifee/core/utility/Callbackable.java +12 -0
- package/android/src/main/java/app/notifee/core/utility/ColorUtils.java +62 -0
- package/android/src/main/java/app/notifee/core/utility/ExtendedListenableFuture.java +84 -0
- package/android/src/main/java/app/notifee/core/utility/IntentUtils.java +146 -0
- package/android/src/main/java/app/notifee/core/utility/ObjectUtils.java +191 -0
- package/android/src/main/java/app/notifee/core/utility/PowerManagerUtils.java +338 -0
- package/android/src/main/java/app/notifee/core/utility/ResourceUtils.java +308 -0
- package/android/src/main/java/app/notifee/core/utility/TextUtils.java +28 -0
- package/android/src/main/java/app/notifee/core/utility/package-info.java +4 -0
- package/android/src/test/java/app/notifee/core/model/NotificationAndroidPressActionModelTest.java +56 -0
- package/android/src/test/java/app/notifee/core/model/TimestampTriggerModelTest.java +44 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +2 -2
- package/src/version.ts +1 -1
- package/android/libs/app/notifee/core/202108261754/core-202108261754.aar +0 -0
- package/android/libs/app/notifee/core/202108261754/core-202108261754.aar.md5 +0 -1
- package/android/libs/app/notifee/core/202108261754/core-202108261754.aar.sha1 +0 -1
- package/android/libs/app/notifee/core/202108261754/core-202108261754.aar.sha256 +0 -1
- package/android/libs/app/notifee/core/202108261754/core-202108261754.aar.sha512 +0 -1
- package/android/libs/app/notifee/core/202108261754/core-202108261754.module +0 -146
- package/android/libs/app/notifee/core/202108261754/core-202108261754.module.md5 +0 -1
- package/android/libs/app/notifee/core/202108261754/core-202108261754.module.sha1 +0 -1
- package/android/libs/app/notifee/core/202108261754/core-202108261754.module.sha256 +0 -1
- package/android/libs/app/notifee/core/202108261754/core-202108261754.module.sha512 +0 -1
- package/android/libs/app/notifee/core/202108261754/core-202108261754.pom +0 -64
- package/android/libs/app/notifee/core/202108261754/core-202108261754.pom.md5 +0 -1
- package/android/libs/app/notifee/core/202108261754/core-202108261754.pom.sha1 +0 -1
- package/android/libs/app/notifee/core/202108261754/core-202108261754.pom.sha256 +0 -1
- package/android/libs/app/notifee/core/202108261754/core-202108261754.pom.sha512 +0 -1
- package/android/libs/app/notifee/core/maven-metadata.xml +0 -13
- package/android/libs/app/notifee/core/maven-metadata.xml.md5 +0 -1
- package/android/libs/app/notifee/core/maven-metadata.xml.sha1 +0 -1
- package/android/libs/app/notifee/core/maven-metadata.xml.sha256 +0 -1
- package/android/libs/app/notifee/core/maven-metadata.xml.sha512 +0 -1
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
package app.notifee.core;
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* Copyright (c) 2016-present Invertase Limited & Contributors
|
|
5
|
+
*
|
|
6
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
* you may not use this library except in compliance with the License.
|
|
8
|
+
* You may obtain a copy of the License at
|
|
9
|
+
*
|
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
*
|
|
12
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
* See the License for the specific language governing permissions and
|
|
16
|
+
* limitations under the License.
|
|
17
|
+
*
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import android.annotation.SuppressLint;
|
|
21
|
+
import android.app.Notification;
|
|
22
|
+
import android.app.Service;
|
|
23
|
+
import android.content.ComponentName;
|
|
24
|
+
import android.content.Context;
|
|
25
|
+
import android.content.Intent;
|
|
26
|
+
import android.content.pm.PackageManager;
|
|
27
|
+
import android.content.pm.ServiceInfo;
|
|
28
|
+
import android.os.Build;
|
|
29
|
+
import android.os.Bundle;
|
|
30
|
+
import android.os.IBinder;
|
|
31
|
+
import androidx.annotation.Nullable;
|
|
32
|
+
import androidx.annotation.RequiresApi;
|
|
33
|
+
import androidx.core.app.NotificationManagerCompat;
|
|
34
|
+
import app.notifee.core.event.ForegroundServiceEvent;
|
|
35
|
+
import app.notifee.core.event.NotificationEvent;
|
|
36
|
+
import app.notifee.core.interfaces.MethodCallResult;
|
|
37
|
+
import app.notifee.core.model.NotificationModel;
|
|
38
|
+
|
|
39
|
+
public class ForegroundService extends Service {
|
|
40
|
+
private static final String TAG = "ForegroundService";
|
|
41
|
+
public static final String START_FOREGROUND_SERVICE_ACTION =
|
|
42
|
+
"app.notifee.core.ForegroundService.START";
|
|
43
|
+
public static final String STOP_FOREGROUND_SERVICE_ACTION =
|
|
44
|
+
"app.notifee.core.ForegroundService.STOP";
|
|
45
|
+
|
|
46
|
+
private static final Object sLock = new Object();
|
|
47
|
+
|
|
48
|
+
public static String mCurrentNotificationId = null;
|
|
49
|
+
|
|
50
|
+
public static int mCurrentForegroundServiceType = -1;
|
|
51
|
+
|
|
52
|
+
private static Bundle mCurrentNotificationBundle = null;
|
|
53
|
+
private static Notification mCurrentNotification = null;
|
|
54
|
+
private static int mCurrentHashCode = 0;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Re-posts the foreground service notification if the given notification ID matches the active
|
|
58
|
+
* foreground service. On Android 14+, users can dismiss ongoing foreground service notifications
|
|
59
|
+
* for most service types; this method restores the notification so the user remains aware of the
|
|
60
|
+
* running service.
|
|
61
|
+
*
|
|
62
|
+
* @return true if the notification was re-posted, false otherwise
|
|
63
|
+
*/
|
|
64
|
+
@SuppressLint("MissingPermission")
|
|
65
|
+
static boolean repostIfActive(String notificationId) {
|
|
66
|
+
synchronized (sLock) {
|
|
67
|
+
if (mCurrentNotificationId == null
|
|
68
|
+
|| !mCurrentNotificationId.equals(notificationId)
|
|
69
|
+
|| mCurrentNotification == null) {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
Logger.w(TAG, "Re-posting foreground service notification dismissed by user");
|
|
73
|
+
NotificationManagerCompat.from(ContextHolder.getApplicationContext())
|
|
74
|
+
.notify(mCurrentHashCode, mCurrentNotification);
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
static void start(int hashCode, Notification notification, Bundle notificationBundle) {
|
|
80
|
+
Context context = ContextHolder.getApplicationContext();
|
|
81
|
+
if (context == null) {
|
|
82
|
+
Logger.e(TAG, "Application context is null; cannot start ForegroundService.");
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
|
|
87
|
+
try {
|
|
88
|
+
ComponentName component = new ComponentName(context, ForegroundService.class);
|
|
89
|
+
ServiceInfo info =
|
|
90
|
+
context.getPackageManager().getServiceInfo(component, PackageManager.GET_META_DATA);
|
|
91
|
+
if (info.getForegroundServiceType() == ServiceInfo.FOREGROUND_SERVICE_TYPE_NONE) {
|
|
92
|
+
Logger.e(
|
|
93
|
+
TAG,
|
|
94
|
+
"No foregroundServiceType declared for app.notifee.core.ForegroundService in"
|
|
95
|
+
+ " your AndroidManifest.xml. Android 14+ requires an explicit"
|
|
96
|
+
+ " foregroundServiceType. Add <service"
|
|
97
|
+
+ " android:name=\"app.notifee.core.ForegroundService\""
|
|
98
|
+
+ " android:foregroundServiceType=\"yourType\" /> to your app manifest."
|
|
99
|
+
+ " Aborting foreground service start.");
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
} catch (PackageManager.NameNotFoundException e) {
|
|
103
|
+
Logger.e(TAG, "ForegroundService not found in manifest", e);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
Intent intent = new Intent(context, ForegroundService.class);
|
|
109
|
+
intent.setAction(START_FOREGROUND_SERVICE_ACTION);
|
|
110
|
+
intent.putExtra("hashCode", hashCode);
|
|
111
|
+
intent.putExtra("notification", notification);
|
|
112
|
+
intent.putExtra("notificationBundle", notificationBundle);
|
|
113
|
+
|
|
114
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
115
|
+
context.startForegroundService(intent);
|
|
116
|
+
} else {
|
|
117
|
+
// TODO test this on older device
|
|
118
|
+
context.startService(intent);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
static void stop() {
|
|
123
|
+
Context context = ContextHolder.getApplicationContext();
|
|
124
|
+
if (context == null) {
|
|
125
|
+
Logger.e(TAG, "Application context is null; cannot stop ForegroundService.");
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
Intent intent = new Intent(context, ForegroundService.class);
|
|
130
|
+
intent.setAction(STOP_FOREGROUND_SERVICE_ACTION);
|
|
131
|
+
|
|
132
|
+
try {
|
|
133
|
+
// Call start service first with stop action
|
|
134
|
+
context.startService(intent);
|
|
135
|
+
} catch (IllegalStateException illegalStateException) {
|
|
136
|
+
// try to stop with stopService command
|
|
137
|
+
context.stopService(intent);
|
|
138
|
+
} catch (Exception exception) {
|
|
139
|
+
Logger.e(TAG, "Unable to stop foreground service", exception);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
@SuppressLint({"ForegroundServiceType", "MissingPermission"})
|
|
144
|
+
@Override
|
|
145
|
+
public int onStartCommand(Intent intent, int flags, int startId) {
|
|
146
|
+
// Check if action is to stop the foreground service
|
|
147
|
+
if (intent == null || STOP_FOREGROUND_SERVICE_ACTION.equals(intent.getAction())) {
|
|
148
|
+
stopSelf();
|
|
149
|
+
synchronized (sLock) {
|
|
150
|
+
mCurrentNotificationId = null;
|
|
151
|
+
mCurrentForegroundServiceType = -1;
|
|
152
|
+
mCurrentNotificationBundle = null;
|
|
153
|
+
mCurrentNotification = null;
|
|
154
|
+
mCurrentHashCode = 0;
|
|
155
|
+
}
|
|
156
|
+
return Service.START_STICKY_COMPATIBILITY;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
Bundle extras = intent.getExtras();
|
|
160
|
+
|
|
161
|
+
if (extras != null) {
|
|
162
|
+
// Hash code is sent to service to ensure it is kept the same
|
|
163
|
+
int hashCode = extras.getInt("hashCode");
|
|
164
|
+
Notification notification = extras.getParcelable("notification");
|
|
165
|
+
Bundle bundle = extras.getBundle("notificationBundle");
|
|
166
|
+
|
|
167
|
+
if (notification != null && bundle != null) {
|
|
168
|
+
NotificationModel notificationModel = NotificationModel.fromBundle(bundle);
|
|
169
|
+
|
|
170
|
+
Object pendingEvent = null;
|
|
171
|
+
|
|
172
|
+
synchronized (sLock) {
|
|
173
|
+
if (mCurrentNotificationId == null) {
|
|
174
|
+
mCurrentNotificationId = notificationModel.getId();
|
|
175
|
+
mCurrentNotificationBundle = bundle;
|
|
176
|
+
mCurrentNotification = notification;
|
|
177
|
+
mCurrentHashCode = hashCode;
|
|
178
|
+
|
|
179
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
|
180
|
+
int foregroundServiceType = notificationModel.getAndroid().getForegroundServiceType();
|
|
181
|
+
if (foregroundServiceType == ServiceInfo.FOREGROUND_SERVICE_TYPE_MANIFEST) {
|
|
182
|
+
foregroundServiceType = resolveManifestServiceType();
|
|
183
|
+
}
|
|
184
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE
|
|
185
|
+
&& foregroundServiceType == ServiceInfo.FOREGROUND_SERVICE_TYPE_NONE) {
|
|
186
|
+
Logger.e(
|
|
187
|
+
TAG,
|
|
188
|
+
"Resolved foreground service type is NONE on API 34+; aborting"
|
|
189
|
+
+ " startForeground to avoid InvalidForegroundServiceTypeException.");
|
|
190
|
+
mCurrentNotificationId = null;
|
|
191
|
+
mCurrentNotificationBundle = null;
|
|
192
|
+
return START_NOT_STICKY;
|
|
193
|
+
}
|
|
194
|
+
startForeground(hashCode, notification, foregroundServiceType);
|
|
195
|
+
mCurrentForegroundServiceType = foregroundServiceType;
|
|
196
|
+
} else {
|
|
197
|
+
startForeground(hashCode, notification);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// On headless task complete
|
|
201
|
+
final MethodCallResult<Void> methodCallResult =
|
|
202
|
+
(e, aVoid) -> {
|
|
203
|
+
stopForegroundCompat();
|
|
204
|
+
synchronized (sLock) {
|
|
205
|
+
mCurrentNotificationId = null;
|
|
206
|
+
mCurrentForegroundServiceType = -1;
|
|
207
|
+
mCurrentNotificationBundle = null;
|
|
208
|
+
mCurrentNotification = null;
|
|
209
|
+
mCurrentHashCode = 0;
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
pendingEvent = new ForegroundServiceEvent(notificationModel, methodCallResult);
|
|
214
|
+
} else {
|
|
215
|
+
if (mCurrentNotificationId.equals(notificationModel.getId())) {
|
|
216
|
+
boolean shouldPostNotificationAgain = true;
|
|
217
|
+
// find if we need to start the service again if the type was changed
|
|
218
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
|
219
|
+
int foregroundServiceType =
|
|
220
|
+
notificationModel.getAndroid().getForegroundServiceType();
|
|
221
|
+
if (foregroundServiceType == ServiceInfo.FOREGROUND_SERVICE_TYPE_MANIFEST) {
|
|
222
|
+
foregroundServiceType = resolveManifestServiceType();
|
|
223
|
+
}
|
|
224
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE
|
|
225
|
+
&& foregroundServiceType == ServiceInfo.FOREGROUND_SERVICE_TYPE_NONE) {
|
|
226
|
+
Logger.e(
|
|
227
|
+
TAG,
|
|
228
|
+
"Resolved foreground service type is NONE on API 34+; skipping type"
|
|
229
|
+
+ " change.");
|
|
230
|
+
} else if (foregroundServiceType != mCurrentForegroundServiceType) {
|
|
231
|
+
startForeground(hashCode, notification, foregroundServiceType);
|
|
232
|
+
mCurrentForegroundServiceType = foregroundServiceType;
|
|
233
|
+
shouldPostNotificationAgain = false;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
if (shouldPostNotificationAgain) {
|
|
237
|
+
NotificationManagerCompat.from(ContextHolder.getApplicationContext())
|
|
238
|
+
.notify(hashCode, notification);
|
|
239
|
+
}
|
|
240
|
+
} else {
|
|
241
|
+
pendingEvent =
|
|
242
|
+
new NotificationEvent(NotificationEvent.TYPE_FG_ALREADY_EXIST, notificationModel);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
if (pendingEvent != null) {
|
|
248
|
+
EventBus.post(pendingEvent);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
return START_NOT_STICKY;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
@Nullable
|
|
257
|
+
@Override
|
|
258
|
+
public IBinder onBind(Intent intent) {
|
|
259
|
+
return null;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Called by the system on API 34 (Android 14) when a foreground service of type {@code
|
|
264
|
+
* shortService} exceeds its timeout. Stops the service gracefully to prevent ANR.
|
|
265
|
+
*/
|
|
266
|
+
@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
|
|
267
|
+
@Override
|
|
268
|
+
public void onTimeout(int startId) {
|
|
269
|
+
handleTimeout(startId, -1);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Called by the system on API 35+ (Android 15+) when a foreground service exceeds its
|
|
274
|
+
* type-specific timeout. Supersedes the single-parameter variant on these API levels.
|
|
275
|
+
*/
|
|
276
|
+
@RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
|
|
277
|
+
@Override
|
|
278
|
+
public void onTimeout(int startId, int fgsType) {
|
|
279
|
+
handleTimeout(startId, fgsType);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
@RequiresApi(Build.VERSION_CODES.Q)
|
|
283
|
+
private static int resolveManifestServiceType() {
|
|
284
|
+
try {
|
|
285
|
+
Context context = ContextHolder.getApplicationContext();
|
|
286
|
+
if (context == null) {
|
|
287
|
+
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE
|
|
288
|
+
? ServiceInfo.FOREGROUND_SERVICE_TYPE_NONE
|
|
289
|
+
: ServiceInfo.FOREGROUND_SERVICE_TYPE_MANIFEST;
|
|
290
|
+
}
|
|
291
|
+
ComponentName component = new ComponentName(context, ForegroundService.class);
|
|
292
|
+
ServiceInfo info =
|
|
293
|
+
context.getPackageManager().getServiceInfo(component, PackageManager.GET_META_DATA);
|
|
294
|
+
int type = info.getForegroundServiceType();
|
|
295
|
+
if (type != ServiceInfo.FOREGROUND_SERVICE_TYPE_NONE) {
|
|
296
|
+
return type;
|
|
297
|
+
}
|
|
298
|
+
} catch (PackageManager.NameNotFoundException e) {
|
|
299
|
+
Logger.e(TAG, "ForegroundService not found in manifest", e);
|
|
300
|
+
}
|
|
301
|
+
// On API 34+ returning MANIFEST (-1) would crash in startForeground(), so return NONE.
|
|
302
|
+
// On API 29-33 MANIFEST is accepted by the framework and resolves at runtime.
|
|
303
|
+
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE
|
|
304
|
+
? ServiceInfo.FOREGROUND_SERVICE_TYPE_NONE
|
|
305
|
+
: ServiceInfo.FOREGROUND_SERVICE_TYPE_MANIFEST;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
@SuppressWarnings("deprecation")
|
|
309
|
+
private void stopForegroundCompat() {
|
|
310
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
|
311
|
+
stopForeground(STOP_FOREGROUND_REMOVE);
|
|
312
|
+
} else {
|
|
313
|
+
stopForeground(true);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
private void handleTimeout(int startId, int fgsType) {
|
|
318
|
+
Logger.e(
|
|
319
|
+
TAG,
|
|
320
|
+
"Foreground service timed out (startId="
|
|
321
|
+
+ startId
|
|
322
|
+
+ ", type="
|
|
323
|
+
+ fgsType
|
|
324
|
+
+ "). Stopping service.");
|
|
325
|
+
|
|
326
|
+
Bundle notifBundle;
|
|
327
|
+
synchronized (sLock) {
|
|
328
|
+
notifBundle = mCurrentNotificationBundle;
|
|
329
|
+
mCurrentNotificationId = null;
|
|
330
|
+
mCurrentForegroundServiceType = -1;
|
|
331
|
+
mCurrentNotificationBundle = null;
|
|
332
|
+
mCurrentNotification = null;
|
|
333
|
+
mCurrentHashCode = 0;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
stopForegroundCompat();
|
|
337
|
+
stopSelf(startId);
|
|
338
|
+
|
|
339
|
+
if (notifBundle != null) {
|
|
340
|
+
NotificationModel model = NotificationModel.fromBundle(notifBundle);
|
|
341
|
+
Bundle extras = new Bundle();
|
|
342
|
+
extras.putInt("startId", startId);
|
|
343
|
+
extras.putInt("fgsType", fgsType);
|
|
344
|
+
EventBus.post(new NotificationEvent(NotificationEvent.TYPE_FG_TIMEOUT, model, extras));
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
package app.notifee.core;
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* Copyright (c) 2016-present Invertase Limited & Contributors
|
|
5
|
+
*
|
|
6
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
* you may not use this library except in compliance with the License.
|
|
8
|
+
* You may obtain a copy of the License at
|
|
9
|
+
*
|
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
*
|
|
12
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
* See the License for the specific language governing permissions and
|
|
16
|
+
* limitations under the License.
|
|
17
|
+
*
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import android.content.ContentProvider;
|
|
21
|
+
import android.content.ContentValues;
|
|
22
|
+
import android.content.Context;
|
|
23
|
+
import android.content.pm.ProviderInfo;
|
|
24
|
+
import android.database.Cursor;
|
|
25
|
+
import android.net.Uri;
|
|
26
|
+
import androidx.annotation.CallSuper;
|
|
27
|
+
import androidx.annotation.NonNull;
|
|
28
|
+
import androidx.annotation.Nullable;
|
|
29
|
+
|
|
30
|
+
@KeepForSdk
|
|
31
|
+
public class InitProvider extends ContentProvider {
|
|
32
|
+
private static final String PROVIDER_AUTHORITY = "notifee-init-provider";
|
|
33
|
+
|
|
34
|
+
@Override
|
|
35
|
+
public void attachInfo(Context context, ProviderInfo info) {
|
|
36
|
+
if (info != null && !info.authority.endsWith(InitProvider.PROVIDER_AUTHORITY)) {
|
|
37
|
+
throw new IllegalStateException(
|
|
38
|
+
"Incorrect provider authority in manifest. This is most likely due to a missing "
|
|
39
|
+
+ "applicationId variable in application's build.gradle.");
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
super.attachInfo(context, info);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
@KeepForSdk
|
|
46
|
+
@CallSuper
|
|
47
|
+
@Override
|
|
48
|
+
public boolean onCreate() {
|
|
49
|
+
if (ContextHolder.getApplicationContext() == null) {
|
|
50
|
+
Context context = getContext();
|
|
51
|
+
if (context != null && context.getApplicationContext() != null) {
|
|
52
|
+
context = context.getApplicationContext();
|
|
53
|
+
}
|
|
54
|
+
ContextHolder.setApplicationContext(context);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
@Nullable
|
|
61
|
+
@Override
|
|
62
|
+
public Cursor query(
|
|
63
|
+
@NonNull Uri uri,
|
|
64
|
+
String[] projection,
|
|
65
|
+
String selection,
|
|
66
|
+
String[] selectionArgs,
|
|
67
|
+
String sortOrder) {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
@Nullable
|
|
72
|
+
@Override
|
|
73
|
+
public String getType(@NonNull Uri uri) {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
@Nullable
|
|
78
|
+
@Override
|
|
79
|
+
public Uri insert(@NonNull Uri uri, ContentValues values) {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
@Override
|
|
84
|
+
public int delete(@NonNull Uri uri, String selection, String[] selectionArgs) {
|
|
85
|
+
return 0;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
@Override
|
|
89
|
+
public int update(
|
|
90
|
+
@NonNull Uri uri, ContentValues values, String selection, String[] selectionArgs) {
|
|
91
|
+
return 0;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
package app.notifee.core;
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* Copyright (c) 2016-present Invertase Limited & Contributors
|
|
5
|
+
*
|
|
6
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
* you may not use this library except in compliance with the License.
|
|
8
|
+
* You may obtain a copy of the License at
|
|
9
|
+
*
|
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
*
|
|
12
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
* See the License for the specific language governing permissions and
|
|
16
|
+
* limitations under the License.
|
|
17
|
+
*
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import java.lang.annotation.Documented;
|
|
21
|
+
import java.lang.annotation.ElementType;
|
|
22
|
+
import java.lang.annotation.Target;
|
|
23
|
+
|
|
24
|
+
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.CONSTRUCTOR})
|
|
25
|
+
@Documented
|
|
26
|
+
public @interface KeepForSdk {}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
package app.notifee.core;
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* Copyright (c) 2016-present Invertase Limited & Contributors
|
|
5
|
+
*
|
|
6
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
* you may not use this library except in compliance with the License.
|
|
8
|
+
* You may obtain a copy of the License at
|
|
9
|
+
*
|
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
*
|
|
12
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
* See the License for the specific language governing permissions and
|
|
16
|
+
* limitations under the License.
|
|
17
|
+
*
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import android.util.Log;
|
|
21
|
+
import androidx.annotation.NonNull;
|
|
22
|
+
import app.notifee.core.event.LogEvent;
|
|
23
|
+
|
|
24
|
+
public class Logger {
|
|
25
|
+
private static final String TAG = "NOTIFEE";
|
|
26
|
+
|
|
27
|
+
private static String tagAndMessage(String tag, String message) {
|
|
28
|
+
return "(" + tag + "): " + message;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@KeepForSdk
|
|
32
|
+
public static void v(@NonNull String tag, String message) {
|
|
33
|
+
Log.v(TAG, tagAndMessage(tag, message));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
@KeepForSdk
|
|
37
|
+
public static void d(@NonNull String tag, String message) {
|
|
38
|
+
Log.d(TAG, tagAndMessage(tag, message));
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
@KeepForSdk
|
|
42
|
+
public static void i(@NonNull String tag, String message) {
|
|
43
|
+
Log.i(TAG, tagAndMessage(tag, message));
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
@KeepForSdk
|
|
47
|
+
public static void w(@NonNull String tag, String message) {
|
|
48
|
+
Log.w(TAG, tagAndMessage(tag, message));
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
@KeepForSdk
|
|
52
|
+
public static void e(@NonNull String tag, String message, Exception e) {
|
|
53
|
+
Log.e(TAG, tagAndMessage(tag, message), e);
|
|
54
|
+
EventBus.post(new LogEvent(LogEvent.LEVEL_ERROR, tag, message, e));
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
@KeepForSdk
|
|
58
|
+
public static void e(@NonNull String tag, String message) {
|
|
59
|
+
Log.e(TAG, tagAndMessage(tag, message));
|
|
60
|
+
EventBus.post(new LogEvent(LogEvent.LEVEL_ERROR, tag, message));
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
@KeepForSdk
|
|
64
|
+
public static void e(@NonNull String tag, String message, Throwable throwable) {
|
|
65
|
+
Log.e(TAG, tagAndMessage(tag, message), throwable);
|
|
66
|
+
EventBus.post(new LogEvent(LogEvent.LEVEL_ERROR, tag, message, throwable));
|
|
67
|
+
}
|
|
68
|
+
}
|