v0.9.3: notification_send posts on the phone, and Java helpers have a home
The tool was the last Android one that never worked on the NX789J: it would fail with "Notification.Builder.build() failed: no exception detail" and the shade stayed empty. The detail was the whole story -- Qt clears a Java exception before C++ gets to look at it, so a build() that throws and a build() that returns null look exactly the same from here, and the only way to catch the difference is to let Java catch it. - app/android/src/xyz/whcself/cstagent/Notifier.java: the builder, the PendingIntent, build() and notify() in one try/catch that returns "" or the throwable's class and message. androiddeployqt copies app/android/ with the rest of the package source and Qt's Gradle template puts its src/ on java.srcDirs, so a class dropped there needs no build-script change (the first one is this; the foreground service of the next step goes there too). - AndroidTools.cpp keeps what it can see from C++ (the context, the channel on API 26+, the small icon looked up by name, the launch intent) and calls Notifier.post(); the result line now carries the Java failure when there is one. The javaErrorText() helper of the previous attempt is gone: reading a pending exception from C++ is exactly what does not work here. - On the device: the tool answers "notification sent", the system holds the record (channel cst-agent, importance 3, the framework small icon, the tap intent back into the app). Earlier attempts in the same session are in the transcript next to it: four failures from the old path, then this one. Docs: docs/android.md gets the Java-helper mechanism (and why the tool has to be wrapped in Java at all) and no longer lists notification_send as missing; app/README.md's platform table and the Android note say where a Java class goes. Version 0.9.3.
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
package xyz.whcself.cstagent;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
/**
|
||||
* The notification behind the engine's notification_send tool.
|
||||
*
|
||||
* It lives in Java because a Java exception is invisible to C++ by the time
|
||||
* Qt's JNI wrapper is done with the call: Notification.Builder.build() can
|
||||
* throw (a small icon Android refuses, a channel it does not know) and the
|
||||
* JNI call then simply returns null -- the tool could only say "failed, no
|
||||
* exception detail" on a device where the phone's own shade never saw
|
||||
* anything. Catching it here turns the failure into the line the tool shows.
|
||||
*
|
||||
* Called from app/src/platform/android/AndroidTools.cpp through QJniObject.
|
||||
* androiddeployqt copies this file with the rest of the package source
|
||||
* (QT_ANDROID_PACKAGE_SOURCE_DIR, app/android/) and Qt's Gradle template adds
|
||||
* "src" to java.srcDirs, so no build script change is needed for a file
|
||||
* added here.
|
||||
*/
|
||||
public final class Notifier {
|
||||
private Notifier() {}
|
||||
|
||||
/**
|
||||
* Post one notification. An empty channelId means an API below 26, which
|
||||
* has no channels. Returns "" when it went out, the Java failure
|
||||
* otherwise (class name and message), so the tool result can name it.
|
||||
*/
|
||||
public static String post(Context ctx, String channelId, String title,
|
||||
String text, int iconId, Intent tap, int id) {
|
||||
try {
|
||||
Notification.Builder builder = channelId == null || channelId.isEmpty()
|
||||
? new Notification.Builder(ctx)
|
||||
: new Notification.Builder(ctx, channelId);
|
||||
builder.setContentTitle(title).setContentText(text).setSmallIcon(iconId);
|
||||
if (tap != null) {
|
||||
tap.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
| Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||
PendingIntent pending = PendingIntent.getActivity(
|
||||
ctx, 0, tap,
|
||||
PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
builder.setContentIntent(pending);
|
||||
}
|
||||
NotificationManager manager = (NotificationManager)
|
||||
ctx.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
if (manager == null)
|
||||
return "no NotificationManager";
|
||||
manager.notify(id, builder.build());
|
||||
return "";
|
||||
} catch (Throwable t) {
|
||||
String message = t.getMessage();
|
||||
return t.getClass().getSimpleName()
|
||||
+ (message == null || message.isEmpty() ? "" : ": " + message);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user