fix: open the app from a widget tap without asking which build to use

This commit is contained in:
Linus Rath
2026-10-31 13:37:10 +01:00
parent bd5c54d654
commit fe6781745f
2 changed files with 68 additions and 0 deletions
@@ -24,6 +24,20 @@ index ed1af56..12c3630 100644
intent,
PendingIntent.FLAG_CANCEL_CURRENT
| PendingIntent.FLAG_MUTABLE
diff --git a/node_modules/react-native-android-widget/android/src/main/java/com/reactnativeandroidwidget/RNWidgetProvider.java b/node_modules/react-native-android-widget/android/src/main/java/com/reactnativeandroidwidget/RNWidgetProvider.java
index c138d81..bcd490d 100644
--- a/node_modules/react-native-android-widget/android/src/main/java/com/reactnativeandroidwidget/RNWidgetProvider.java
+++ b/node_modules/react-native-android-widget/android/src/main/java/com/reactnativeandroidwidget/RNWidgetProvider.java
@@ -133,6 +133,9 @@ public class RNWidgetProvider extends AppWidgetProvider {
try {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ // This app's own activity, never a chooser: another build of the app
+ // (another flavor) handles the same scheme and would be offered too.
+ intent.setPackage(context.getPackageName());
context.startActivity(intent);
} catch (Exception e) {
e.printStackTrace();
diff --git a/node_modules/react-native-android-widget/android/src/main/java/com/reactnativeandroidwidget/RNWidgetUtil.java b/node_modules/react-native-android-widget/android/src/main/java/com/reactnativeandroidwidget/RNWidgetUtil.java
index 2a34305..711503b 100644
--- a/node_modules/react-native-android-widget/android/src/main/java/com/reactnativeandroidwidget/RNWidgetUtil.java
@@ -0,0 +1,54 @@
import { describe, expect, it } from 'vitest';
import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';
import { open, links } from '../clicks';
const root = path.resolve(__dirname, '../../..');
const patchFile = path.join(root, 'patches/react-native-android-widget+0.22.1.patch');
const provider = 'node_modules/react-native-android-widget/android/src/main/java/com/reactnativeandroidwidget/RNWidgetProvider.java';
// The library's own openUri, as published: what the patch is applied to.
const UPSTREAM_OPEN_URI = [
' private void openUri(Context context, String uri) {',
' try {',
' Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));',
' intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);',
' context.startActivity(intent);',
' } catch (Exception e) {',
' e.printStackTrace();',
' }',
' }',
];
describe('a tap that opens the app from a widget', () => {
it('goes through the library’s OPEN_URI, which the patch makes explicit', () => {
expect(open(links.inbox())).toEqual({ clickAction: 'OPEN_URI', clickActionData: { uri: 'bulwarkmobile://mail/folder/inbox' } });
});
it('is sent to this app’s own package, so no chooser offers another build', async () => {
const { parsePatchFile } = await import(path.join(root, 'node_modules/patch-package/dist/patch/parse.js'));
const { executeEffects } = await import(path.join(root, 'node_modules/patch-package/dist/patch/apply.js'));
const effects = parsePatchFile(fs.readFileSync(patchFile, 'utf8'))
.filter((e: { path?: string }) => e.path?.endsWith('RNWidgetProvider.java'));
expect(effects).toHaveLength(1);
// The published file around openUri, padded to its line numbers.
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'widget-patch-'));
const target = path.join(dir, provider);
fs.mkdirSync(path.dirname(target), { recursive: true });
const lines = Array.from({ length: 131 }, () => '').concat(UPSTREAM_OPEN_URI, ['', '}']);
fs.writeFileSync(target, lines.join('\n'));
const cwd = process.cwd();
try {
process.chdir(dir);
executeEffects(effects, { dryRun: false });
} finally {
process.chdir(cwd);
}
const patched = fs.readFileSync(target, 'utf8');
const openUri = patched.slice(patched.indexOf('private void openUri'), patched.indexOf('startActivity'));
expect(openUri).toMatch(/intent\.setPackage\(context\.getPackageName\(\)\);/);
fs.rmSync(dir, { recursive: true, force: true });
});
});