mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
PushNotifications: Assert instead of crashing if Android notification icon cannot be located
This commit is contained in:
parent
98031a814c
commit
ed0092a8bc
1 changed files with 64 additions and 28 deletions
|
|
@ -276,7 +276,7 @@ bool PushNotifications::Notification::isValid() const noexcept
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
struct PushNotifications::Pimpl
|
struct PushNotifications::Pimpl
|
||||||
{
|
{
|
||||||
Pimpl (PushNotifications& p)
|
explicit Pimpl (PushNotifications& p)
|
||||||
: owner (p)
|
: owner (p)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
@ -303,16 +303,18 @@ struct PushNotifications::Pimpl
|
||||||
|
|
||||||
auto* env = getEnv();
|
auto* env = getEnv();
|
||||||
|
|
||||||
auto notificationManager = getNotificationManager();
|
if (auto notificationManager = getNotificationManager())
|
||||||
|
|
||||||
if (notificationManager.get() != nullptr)
|
|
||||||
{
|
{
|
||||||
auto notification = juceNotificationToJavaNotification (n);
|
if (auto notification = juceNotificationToJavaNotification (n))
|
||||||
|
{
|
||||||
|
auto tag = javaString (n.identifier);
|
||||||
|
const int id = 0;
|
||||||
|
|
||||||
auto tag = javaString (n.identifier);
|
env->CallVoidMethod (notificationManager.get(),
|
||||||
const int id = 0;
|
NotificationManagerBase.notify,
|
||||||
|
tag.get(),
|
||||||
env->CallVoidMethod (notificationManager.get(), NotificationManagerBase.notify, tag.get(), id, notification.get());
|
id, notification.get());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -607,11 +609,12 @@ struct PushNotifications::Pimpl
|
||||||
|
|
||||||
auto notificationBuilder = createNotificationBuilder (n);
|
auto notificationBuilder = createNotificationBuilder (n);
|
||||||
|
|
||||||
setupRequiredFields (n, notificationBuilder);
|
notificationBuilder = setupRequiredFields (n, notificationBuilder);
|
||||||
setupOptionalFields (n, notificationBuilder);
|
notificationBuilder = setupOptionalFields (n, notificationBuilder);
|
||||||
|
notificationBuilder = setupActions (n, notificationBuilder);
|
||||||
|
|
||||||
if (n.actions.size() > 0)
|
if (notificationBuilder == nullptr)
|
||||||
setupActions (n, notificationBuilder);
|
return notificationBuilder;
|
||||||
|
|
||||||
return LocalRef<jobject> (env->CallObjectMethod (notificationBuilder, NotificationBuilderApi16.build));
|
return LocalRef<jobject> (env->CallObjectMethod (notificationBuilder, NotificationBuilderApi16.build));
|
||||||
}
|
}
|
||||||
|
|
@ -648,8 +651,11 @@ struct PushNotifications::Pimpl
|
||||||
return LocalRef<jobject> (env->NewObject (builderClass, builderConstructor, context.get()));
|
return LocalRef<jobject> (env->NewObject (builderClass, builderConstructor, context.get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setupRequiredFields (const Notification& n, LocalRef<jobject>& notificationBuilder)
|
static LocalRef<jobject> setupRequiredFields (const Notification& n, LocalRef<jobject> notificationBuilder)
|
||||||
{
|
{
|
||||||
|
if (notificationBuilder == nullptr)
|
||||||
|
return notificationBuilder;
|
||||||
|
|
||||||
auto* env = getEnv();
|
auto* env = getEnv();
|
||||||
LocalRef<jobject> context (getMainActivity());
|
LocalRef<jobject> context (getMainActivity());
|
||||||
|
|
||||||
|
|
@ -676,8 +682,16 @@ struct PushNotifications::Pimpl
|
||||||
env->CallObjectMethod (notificationBuilder, NotificationBuilderBase.setContentIntent, notifyPendingIntent.get());
|
env->CallObjectMethod (notificationBuilder, NotificationBuilderBase.setContentIntent, notifyPendingIntent.get());
|
||||||
|
|
||||||
auto resources = LocalRef<jobject> (env->CallObjectMethod (context.get(), AndroidContext.getResources));
|
auto resources = LocalRef<jobject> (env->CallObjectMethod (context.get(), AndroidContext.getResources));
|
||||||
const int iconId = env->CallIntMethod (resources, AndroidResources.getIdentifier, javaString (n.icon).get(),
|
const auto iconId = env->CallIntMethod (resources, AndroidResources.getIdentifier, javaString (n.icon).get(),
|
||||||
javaString ("raw").get(), packageNameString.get());
|
javaString ("raw").get(), packageNameString.get());
|
||||||
|
|
||||||
|
if (iconId == 0)
|
||||||
|
{
|
||||||
|
// If you hit this, the notification icon could not be located, and the notification
|
||||||
|
// will not be sent.
|
||||||
|
jassertfalse;
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
env->CallObjectMethod (notificationBuilder, NotificationBuilderBase.setSmallIcon, iconId);
|
env->CallObjectMethod (notificationBuilder, NotificationBuilderBase.setSmallIcon, iconId);
|
||||||
|
|
||||||
|
|
@ -688,12 +702,17 @@ struct PushNotifications::Pimpl
|
||||||
|
|
||||||
auto publicNotificationBuilder = createNotificationBuilder (n);
|
auto publicNotificationBuilder = createNotificationBuilder (n);
|
||||||
|
|
||||||
setupRequiredFields (*n.publicVersion, publicNotificationBuilder);
|
publicNotificationBuilder = setupRequiredFields (*n.publicVersion, publicNotificationBuilder);
|
||||||
setupOptionalFields (*n.publicVersion, publicNotificationBuilder);
|
publicNotificationBuilder = setupOptionalFields (*n.publicVersion, publicNotificationBuilder);
|
||||||
|
|
||||||
|
if (publicNotificationBuilder == nullptr)
|
||||||
|
return {};
|
||||||
|
|
||||||
auto publicVersion = LocalRef<jobject> (env->CallObjectMethod (publicNotificationBuilder, NotificationBuilderApi16.build));
|
auto publicVersion = LocalRef<jobject> (env->CallObjectMethod (publicNotificationBuilder, NotificationBuilderApi16.build));
|
||||||
env->CallObjectMethod (notificationBuilder, NotificationBuilderApi21.setPublicVersion, publicVersion.get());
|
env->CallObjectMethod (notificationBuilder, NotificationBuilderApi21.setPublicVersion, publicVersion.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return notificationBuilder;
|
||||||
}
|
}
|
||||||
|
|
||||||
static LocalRef<jobject> juceNotificationToBundle (const Notification& n)
|
static LocalRef<jobject> juceNotificationToBundle (const Notification& n)
|
||||||
|
|
@ -753,8 +772,11 @@ struct PushNotifications::Pimpl
|
||||||
return bundle;
|
return bundle;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setupOptionalFields (const Notification& n, LocalRef<jobject>& notificationBuilder)
|
static LocalRef<jobject> setupOptionalFields (const Notification n, LocalRef<jobject>& notificationBuilder)
|
||||||
{
|
{
|
||||||
|
if (notificationBuilder == nullptr)
|
||||||
|
return notificationBuilder;
|
||||||
|
|
||||||
auto* env = getEnv();
|
auto* env = getEnv();
|
||||||
|
|
||||||
if (n.subtitle.isNotEmpty())
|
if (n.subtitle.isNotEmpty())
|
||||||
|
|
@ -871,12 +893,15 @@ struct PushNotifications::Pimpl
|
||||||
env->CallObjectMethod (notificationBuilder, NotificationBuilderApi26.setTimeoutAfter, (jlong) n.timeoutAfterMs);
|
env->CallObjectMethod (notificationBuilder, NotificationBuilderApi26.setTimeoutAfter, (jlong) n.timeoutAfterMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
setupNotificationDeletedCallback (n, notificationBuilder);
|
return setupNotificationDeletedCallback (n, notificationBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setupNotificationDeletedCallback (const Notification& n,
|
static LocalRef<jobject> setupNotificationDeletedCallback (const Notification& n,
|
||||||
LocalRef<jobject>& notificationBuilder)
|
LocalRef<jobject> notificationBuilder)
|
||||||
{
|
{
|
||||||
|
if (notificationBuilder == nullptr)
|
||||||
|
return notificationBuilder;
|
||||||
|
|
||||||
auto* env = getEnv();
|
auto* env = getEnv();
|
||||||
LocalRef<jobject> context (getMainActivity());
|
LocalRef<jobject> context (getMainActivity());
|
||||||
|
|
||||||
|
|
@ -898,16 +923,19 @@ struct PushNotifications::Pimpl
|
||||||
0));
|
0));
|
||||||
|
|
||||||
env->CallObjectMethod (notificationBuilder, NotificationBuilderBase.setDeleteIntent, deletePendingIntent.get());
|
env->CallObjectMethod (notificationBuilder, NotificationBuilderBase.setDeleteIntent, deletePendingIntent.get());
|
||||||
|
|
||||||
|
return notificationBuilder;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setupActions (const Notification& n, LocalRef<jobject>& notificationBuilder)
|
static LocalRef<jobject> setupActions (const Notification& n, LocalRef<jobject> notificationBuilder)
|
||||||
{
|
{
|
||||||
|
if (notificationBuilder == nullptr || n.actions.isEmpty())
|
||||||
|
return notificationBuilder;
|
||||||
|
|
||||||
auto* env = getEnv();
|
auto* env = getEnv();
|
||||||
LocalRef<jobject> context (getMainActivity());
|
LocalRef<jobject> context (getMainActivity());
|
||||||
|
|
||||||
int actionIndex = 0;
|
for (const auto [actionIndex, action] : enumerate (n.actions))
|
||||||
|
|
||||||
for (const auto& action : n.actions)
|
|
||||||
{
|
{
|
||||||
auto activityClass = LocalRef<jobject> (env->CallObjectMethod (context.get(), JavaObject.getClass));
|
auto activityClass = LocalRef<jobject> (env->CallObjectMethod (context.get(), JavaObject.getClass));
|
||||||
auto notifyIntent = LocalRef<jobject> (env->NewObject (AndroidIntent, AndroidIntent.constructorWithContextAndClass, context.get(), activityClass.get()));
|
auto notifyIntent = LocalRef<jobject> (env->NewObject (AndroidIntent, AndroidIntent.constructorWithContextAndClass, context.get(), activityClass.get()));
|
||||||
|
|
@ -938,6 +966,14 @@ struct PushNotifications::Pimpl
|
||||||
iconId = env->CallIntMethod (resources, AndroidResources.getIdentifier, javaString (n.icon).get(),
|
iconId = env->CallIntMethod (resources, AndroidResources.getIdentifier, javaString (n.icon).get(),
|
||||||
javaString ("raw").get(), packageNameString.get());
|
javaString ("raw").get(), packageNameString.get());
|
||||||
|
|
||||||
|
if (iconId == 0)
|
||||||
|
{
|
||||||
|
// If this is hit, the notification icon could not be located, so the notification
|
||||||
|
// cannot be displayed.
|
||||||
|
jassertfalse;
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
auto actionBuilder = LocalRef<jobject> (env->NewObject (NotificationActionBuilder,
|
auto actionBuilder = LocalRef<jobject> (env->NewObject (NotificationActionBuilder,
|
||||||
NotificationActionBuilder.constructor,
|
NotificationActionBuilder.constructor,
|
||||||
iconId,
|
iconId,
|
||||||
|
|
@ -982,9 +1018,9 @@ struct PushNotifications::Pimpl
|
||||||
|
|
||||||
env->CallObjectMethod (notificationBuilder, NotificationBuilderApi20.addAction,
|
env->CallObjectMethod (notificationBuilder, NotificationBuilderApi20.addAction,
|
||||||
env->CallObjectMethod (actionBuilder, NotificationActionBuilder.build));
|
env->CallObjectMethod (actionBuilder, NotificationActionBuilder.build));
|
||||||
|
|
||||||
++actionIndex;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return notificationBuilder;
|
||||||
}
|
}
|
||||||
|
|
||||||
static LocalRef<jobject> juceUrlToAndroidUri (const URL& url)
|
static LocalRef<jobject> juceUrlToAndroidUri (const URL& url)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue