313313MANIFEST_FILE=" $APP_MODULE_DIR /src/main/AndroidManifest.xml"
314314if [ ! -f " $MANIFEST_FILE " ]; then
315315 mkdir -p " $( dirname " $MANIFEST_FILE " ) "
316- cat > " $MANIFEST_FILE " << ' EOF '
317- <manifest xmlns:android="http://schemas.android.com/apk/res/android">
316+ cat > " $MANIFEST_FILE " << EOF
317+ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package=" $PACKAGE_NAME " >
318318 <application/>
319319</manifest>
320320EOF
321321 ba_log " Created minimal Android manifest at $MANIFEST_FILE "
322322fi
323323
324324ensure_manifest_stub () {
325- python3 - " $MANIFEST_FILE " " $MAIN_NAME " << 'PY '
325+ python3 - " $MANIFEST_FILE " " $MAIN_NAME " " $PACKAGE_NAME " << 'PY '
326326import sys
327327from pathlib import Path
328328import xml.etree.ElementTree as ET
329329
330330manifest_path = Path(sys.argv[1])
331331main_name = sys.argv[2]
332+ package_name = sys.argv[3]
332333ns_android = "http://schemas.android.com/apk/res/android"
333334
334335ET.register_namespace('android', ns_android)
335336tree = ET.parse(manifest_path)
336337root = tree.getroot()
337338changed = False
338339
340+ # Ensure manifest declares the package attribute for clarity
341+ if 'package' not in root.attrib:
342+ root.set('package', package_name)
343+ changed = True
344+
339345app = root.find('application')
340346if app is None:
341347 app = ET.SubElement(root, 'application')
342348 changed = True
343349
344- target = f".{main_name}Stub"
350+ target_fqcn = f"{package_name}.{main_name}Stub"
351+ target_relative = f".{main_name}Stub"
345352android_name = f"{{{ns_android}}}name"
346353android_exported = f"{{{ns_android}}}exported"
347354
348355for activity in app.findall('activity'):
349356 name = activity.get(android_name)
350- if name in (target, target.lstrip('.')):
357+ if name == target_relative:
358+ activity.set(android_name, target_fqcn)
359+ changed = True
360+ break
361+ if name == target_fqcn:
351362 break
352363else:
353364 activity = ET.Element('activity')
354- activity.set(android_name, target )
365+ activity.set(android_name, target_fqcn )
355366 activity.set(android_exported, 'false')
356367 app.append(activity)
357368 changed = True
@@ -366,7 +377,7 @@ if ! ensure_manifest_stub; then
366377 exit 1
367378fi
368379
369- if ! grep -Eq " android:name=\" (\. ${MAIN_NAME} Stub| ${ PACKAGE_NAME// ./ \\ .} .${MAIN_NAME} Stub) \" " " $MANIFEST_FILE " ; then
380+ if ! grep -Eq " android:name=\" ${ PACKAGE_NAME// ./ \\ .} .${MAIN_NAME} Stub\" " " $MANIFEST_FILE " ; then
370381 ba_log " Manifest does not declare ${MAIN_NAME} Stub activity" >&2
371382 exit 1
372383fi
@@ -387,6 +398,87 @@ if ! grep -q "android[[:space:]]*{" "$APP_BUILD_GRADLE"; then
387398 exit 1
388399fi
389400
401+ ensure_gradle_package_config () {
402+ python3 - " $APP_BUILD_GRADLE " " $PACKAGE_NAME " << 'PY '
403+ import sys
404+ from pathlib import Path
405+ import re
406+
407+ path = Path(sys.argv[1])
408+ package_name = sys.argv[2]
409+ text = path.read_text()
410+ original = text
411+ messages = []
412+
413+ def ensure_namespace(source: str) -> str:
414+ pattern = re.compile(r'\bnamespace\s+["\']([^"\']+)["\']')
415+ match = pattern.search(source)
416+ if match:
417+ if match.group(1) != package_name:
418+ start, end = match.span()
419+ replacement = f'namespace "{package_name}"'
420+ source = source[:start] + replacement + source[end:]
421+ messages.append(f"Updated namespace to {package_name}")
422+ else:
423+ android_match = re.search(r'android\s*\{', source)
424+ if not android_match:
425+ sys.exit("Unable to locate android block when inserting namespace")
426+ insert = android_match.end()
427+ insertion = f"\n namespace \"{package_name}\""
428+ source = source[:insert] + insertion + source[insert:]
429+ messages.append(f"Inserted namespace {package_name}")
430+ return source
431+
432+ def ensure_application_id(source: str) -> str:
433+ pattern = re.compile(r'\bapplicationId\s+["\']([^"\']+)["\']')
434+ match = pattern.search(source)
435+ if match:
436+ if match.group(1) != package_name:
437+ start, end = match.span()
438+ indent = source[:start].split('\n')[-1].split('applicationId')[0]
439+ replacement = f"{indent}applicationId \"{package_name}\""
440+ source = source[:start] + replacement + source[end:]
441+ messages.append(f"Updated applicationId to {package_name}")
442+ return source
443+
444+ default_match = re.search(r'defaultConfig\s*\{', source)
445+ if default_match:
446+ insert = default_match.end()
447+ insertion = f"\n applicationId \"{package_name}\""
448+ source = source[:insert] + insertion + source[insert:]
449+ messages.append(f"Inserted applicationId {package_name}")
450+ return source
451+
452+ android_match = re.search(r'android\s*\{', source)
453+ if not android_match:
454+ sys.exit("Unable to locate android block when creating defaultConfig")
455+ insert = android_match.end()
456+ insertion = ("\n defaultConfig {\n applicationId \"{0}\"\n }\n".format(package_name))
457+ source = source[:insert] + insertion + source[insert:]
458+ messages.append(f"Created defaultConfig with applicationId {package_name}")
459+ return source
460+
461+ text = ensure_namespace(text)
462+ text = ensure_application_id(text)
463+
464+ if text != original:
465+ path.write_text(text)
466+
467+ for message in messages:
468+ print(message)
469+ PY
470+ }
471+
472+ if ! GRADLE_PACKAGE_LOG=$( ensure_gradle_package_config) ; then
473+ ba_log " Failed to align namespace/applicationId with Codename One package" >&2
474+ exit 1
475+ fi
476+ if [ -n " $GRADLE_PACKAGE_LOG " ]; then
477+ while IFS= read -r line; do
478+ [ -n " $line " ] && ba_log " $line "
479+ done <<< " $GRADLE_PACKAGE_LOG"
480+ fi
481+
390482chmod +x " $GRADLE_PROJECT_DIR /gradlew"
391483
392484ba_log " Inspecting Gradle application identifiers"
9531045
9541046MERGED_MANIFEST=" $APP_MODULE_DIR /build/intermediates/packaged_manifests/debug/AndroidManifest.xml"
9551047if [ -f " $MERGED_MANIFEST " ]; then
956- if grep -q " ${ MAIN_NAME} Stub" " $MERGED_MANIFEST " ; then
957- grep -n " ${MAIN_NAME} Stub" " $MERGED_MANIFEST " | sed ' s/^/[build-android-app] merged-manifest: /' || true
1048+ if grep -q " android:name= \" ${PACKAGE_NAME // . / \\ .} . ${ MAIN_NAME} Stub\" " " $MERGED_MANIFEST " ; then
1049+ grep -n " ${PACKAGE_NAME // . / \\ .} . ${ MAIN_NAME} Stub" " $MERGED_MANIFEST " | sed ' s/^/[build-android-app] merged-manifest: /' || true
9581050 else
9591051 ba_log " ERROR: merged manifest missing ${MAIN_NAME} Stub declaration"
9601052 sed -n ' 1,200p' " $MERGED_MANIFEST " | sed ' s/^/[build-android-app] merged-manifest: /'
@@ -1034,7 +1126,7 @@ LAUNCH_RESOLVE_OUTPUT="$("$ADB_BIN" -s "$EMULATOR_SERIAL" shell cmd package reso
10341126if [ -n " $LAUNCH_RESOLVE_OUTPUT " ]; then
10351127 printf ' %s\n' " $LAUNCH_RESOLVE_OUTPUT " | sed ' s/^/[build-android-app] resolve-launch: /'
10361128fi
1037- STUB_ACTIVITY_FQCN=" $PACKAGE_NAME /.${MAIN_NAME} Stub"
1129+ STUB_ACTIVITY_FQCN=" $PACKAGE_NAME /$PACKAGE_NAME .${MAIN_NAME} Stub"
10381130STUB_RESOLVE_OUTPUT=" $(
10391131 " $ADB_BIN " -s " $EMULATOR_SERIAL " shell cmd package resolve-activity --brief " $STUB_ACTIVITY_FQCN " 2>&1 || true
10401132 ) "
0 commit comments