Skip to content

Commit c79f9fb

Browse files
committed
Working on NFC + tag emulation
1 parent 2eacf87 commit c79f9fb

40 files changed

+818
-383
lines changed

.cursor/plans/hce_nfc_integration_plan.plan.md

Lines changed: 252 additions & 0 deletions
Large diffs are not rendered by default.

android/app/build.gradle

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ react {
1414
hermesCommand = new File(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim()).getParentFile().getAbsolutePath() + "/sdks/hermesc/%OS-BIN%/hermesc"
1515
codegenDir = new File(["node", "--print", "require.resolve('@react-native/codegen/package.json', { paths: [require.resolve('react-native/package.json')] })"].execute(null, rootDir).text.trim()).getParentFile().getAbsoluteFile()
1616

17+
enableBundleCompression = (findProperty('android.enableBundleCompression') ?: false).toBoolean()
1718
// Use Expo CLI to bundle the app, this ensures the Metro config
1819
// works correctly with Expo projects.
1920
cliFile = new File(["node", "--print", "require.resolve('@expo/cli', { paths: [require.resolve('expo/package.json')] })"].execute(null, rootDir).text.trim())
@@ -63,9 +64,9 @@ react {
6364
}
6465

6566
/**
66-
* Set this to true to Run Proguard on Release builds to minify the Java bytecode.
67+
* Set this to true in release builds to optimize the app using [R8](https://developer.android.com/topic/performance/app-optimization/enable-app-optimization).
6768
*/
68-
def enableProguardInReleaseBuilds = (findProperty('android.enableProguardInReleaseBuilds') ?: false).toBoolean()
69+
def enableMinifyInReleaseBuilds = (findProperty('android.enableMinifyInReleaseBuilds') ?: false).toBoolean()
6970

7071
/**
7172
* The preferred build flavor of JavaScriptCore (JSC)
@@ -78,21 +79,23 @@ def enableProguardInReleaseBuilds = (findProperty('android.enableProguardInRelea
7879
* give correct results when using with locales other than en-US. Note that
7980
* this variant is about 6MiB larger per architecture than default.
8081
*/
81-
def jscFlavor = 'org.webkit:android-jsc:+'
82+
def jscFlavor = 'io.github.react-native-community:jsc-android:2026004.+'
8283

8384
android {
8485
ndkVersion rootProject.ext.ndkVersion
8586

8687
buildToolsVersion rootProject.ext.buildToolsVersion
8788
compileSdk rootProject.ext.compileSdkVersion
8889

89-
namespace 'com.anonymous.app'
90+
namespace 'com.brewskey.app'
9091
defaultConfig {
91-
applicationId 'com.anonymous.app'
92+
applicationId 'com.brewskey.app'
9293
minSdkVersion rootProject.ext.minSdkVersion
9394
targetSdkVersion rootProject.ext.targetSdkVersion
9495
versionCode 1
9596
versionName "3.0.0"
97+
98+
buildConfigField "String", "REACT_NATIVE_RELEASE_LEVEL", "\"${findProperty('reactNativeReleaseLevel') ?: 'stable'}\""
9699
}
97100
signingConfigs {
98101
debug {
@@ -110,15 +113,18 @@ android {
110113
// Caution! In production, you need to generate your own keystore file.
111114
// see https://reactnative.dev/docs/signed-apk-android.
112115
signingConfig signingConfigs.debug
113-
shrinkResources (findProperty('android.enableShrinkResourcesInReleaseBuilds')?.toBoolean() ?: false)
114-
minifyEnabled enableProguardInReleaseBuilds
116+
def enableShrinkResources = findProperty('android.enableShrinkResourcesInReleaseBuilds') ?: 'false'
117+
shrinkResources enableShrinkResources.toBoolean()
118+
minifyEnabled enableMinifyInReleaseBuilds
115119
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
116-
crunchPngs (findProperty('android.enablePngCrunchInReleaseBuilds')?.toBoolean() ?: true)
120+
def enablePngCrunchInRelease = findProperty('android.enablePngCrunchInReleaseBuilds') ?: 'true'
121+
crunchPngs enablePngCrunchInRelease.toBoolean()
117122
}
118123
}
119124
packagingOptions {
120125
jniLibs {
121-
useLegacyPackaging (findProperty('expo.useLegacyPackaging')?.toBoolean() ?: false)
126+
def enableLegacyPackaging = findProperty('expo.useLegacyPackaging') ?: 'false'
127+
useLegacyPackaging enableLegacyPackaging.toBoolean()
122128
}
123129
}
124130
androidResources {
@@ -156,15 +162,15 @@ dependencies {
156162

157163
if (isGifEnabled) {
158164
// For animated gif support
159-
implementation("com.facebook.fresco:animated-gif:${reactAndroidLibs.versions.fresco.get()}")
165+
implementation("com.facebook.fresco:animated-gif:${expoLibs.versions.fresco.get()}")
160166
}
161167

162168
if (isWebpEnabled) {
163169
// For webp support
164-
implementation("com.facebook.fresco:webpsupport:${reactAndroidLibs.versions.fresco.get()}")
170+
implementation("com.facebook.fresco:webpsupport:${expoLibs.versions.fresco.get()}")
165171
if (isWebpAnimatedEnabled) {
166172
// Animated webp support
167-
implementation("com.facebook.fresco:animated-webp:${reactAndroidLibs.versions.fresco.get()}")
173+
implementation("com.facebook.fresco:animated-webp:${expoLibs.versions.fresco.get()}")
168174
}
169175
}
170176

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
2+
xmlns:tools="http://schemas.android.com/tools">
3+
4+
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
5+
6+
<application android:usesCleartextTraffic="true" tools:targetApi="28" tools:ignore="GoogleAppIndexingWarning" tools:replace="android:usesCleartextTraffic" />
7+
</manifest>

android/app/src/main/AndroidManifest.xml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
1+
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">
22
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
33
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
44
<uses-permission android:name="android.permission.INTERNET"/>
55
<uses-permission android:name="android.permission.NFC"/>
66
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
7+
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
78
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
89
<uses-permission android:name="android.permission.VIBRATE"/>
910
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
@@ -14,7 +15,7 @@
1415
<data android:scheme="https"/>
1516
</intent>
1617
</queries>
17-
<application android:name=".MainApplication" android:label="@string/app_name" android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round" android:allowBackup="true" android:theme="@style/AppTheme" android:supportsRtl="true" android:fullBackupContent="@xml/secure_store_backup_rules" android:dataExtractionRules="@xml/secure_store_data_extraction_rules">
18+
<application android:name=".MainApplication" android:label="@string/app_name" android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round" android:allowBackup="true" android:theme="@style/AppTheme" android:supportsRtl="true" android:enableOnBackInvokedCallback="false" android:fullBackupContent="@xml/secure_store_backup_rules" android:dataExtractionRules="@xml/secure_store_data_extraction_rules">
1819
<meta-data android:name="expo.modules.updates.ENABLED" android:value="false"/>
1920
<meta-data android:name="expo.modules.updates.EXPO_UPDATES_CHECK_ON_LAUNCH" android:value="ALWAYS"/>
2021
<meta-data android:name="expo.modules.updates.EXPO_UPDATES_LAUNCH_WAIT_MS" android:value="0"/>
@@ -27,7 +28,7 @@
2728
<action android:name="android.intent.action.VIEW"/>
2829
<category android:name="android.intent.category.DEFAULT"/>
2930
<category android:name="android.intent.category.BROWSABLE"/>
30-
<data android:scheme="com.anonymous.app"/>
31+
<data android:scheme="brewskey"/>
3132
<data android:scheme="exp+brewskey"/>
3233
</intent-filter>
3334
</activity>

android/app/src/main/java/com/anonymous/app/MainActivity.kt renamed to android/app/src/main/java/com/brewskey/app/MainActivity.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.anonymous.app
1+
package com.brewskey.app
22
import expo.modules.splashscreen.SplashScreenManager
33

44
import android.os.Build

android/app/src/main/java/com/anonymous/app/MainApplication.kt renamed to android/app/src/main/java/com/brewskey/app/MainApplication.kt

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,37 @@
1-
package com.anonymous.app
1+
package com.brewskey.app
22

33
import android.app.Application
44
import android.content.res.Configuration
55

66
import com.facebook.react.PackageList
77
import com.facebook.react.ReactApplication
8+
import com.facebook.react.ReactNativeApplicationEntryPoint.loadReactNative
89
import com.facebook.react.ReactNativeHost
910
import com.facebook.react.ReactPackage
1011
import com.facebook.react.ReactHost
11-
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load
12+
import com.facebook.react.common.ReleaseLevel
13+
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint
1214
import com.facebook.react.defaults.DefaultReactNativeHost
13-
import com.facebook.react.soloader.OpenSourceMergedSoMapping
14-
import com.facebook.soloader.SoLoader
1515

1616
import expo.modules.ApplicationLifecycleDispatcher
1717
import expo.modules.ReactNativeHostWrapper
1818

1919
class MainApplication : Application(), ReactApplication {
2020

2121
override val reactNativeHost: ReactNativeHost = ReactNativeHostWrapper(
22-
this,
23-
object : DefaultReactNativeHost(this) {
24-
override fun getPackages(): List<ReactPackage> {
25-
val packages = PackageList(this).packages
26-
// Packages that cannot be autolinked yet can be added manually here, for example:
27-
// packages.add(new MyReactNativePackage());
28-
return packages
29-
}
22+
this,
23+
object : DefaultReactNativeHost(this) {
24+
override fun getPackages(): List<ReactPackage> =
25+
PackageList(this).packages.apply {
26+
// Packages that cannot be autolinked yet can be added manually here, for example:
27+
// add(MyReactNativePackage())
28+
}
3029

3130
override fun getJSMainModuleName(): String = ".expo/.virtual-metro-entry"
3231

3332
override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG
3433

3534
override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
36-
override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED
3735
}
3836
)
3937

@@ -42,11 +40,12 @@ class MainApplication : Application(), ReactApplication {
4240

4341
override fun onCreate() {
4442
super.onCreate()
45-
SoLoader.init(this, OpenSourceMergedSoMapping)
46-
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
47-
// If you opted-in for the New Architecture, we load the native entry point for this app.
48-
load()
43+
DefaultNewArchitectureEntryPoint.releaseLevel = try {
44+
ReleaseLevel.valueOf(BuildConfig.REACT_NATIVE_RELEASE_LEVEL.uppercase())
45+
} catch (e: IllegalArgumentException) {
46+
ReleaseLevel.STABLE
4947
}
48+
loadReactNative(this)
5049
ApplicationLifecycleDispatcher.onApplicationCreate(this)
5150
}
5251

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,14 @@
11
<resources xmlns:tools="http://schemas.android.com/tools">
2-
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
3-
<item name="android:textColor">@android:color/black</item>
4-
<item name="android:editTextStyle">@style/ResetEditText</item>
2+
<style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
3+
<item name="android:enforceNavigationBarContrast" tools:targetApi="29">true</item>
54
<item name="android:editTextBackground">@drawable/rn_edit_text_material</item>
65
<item name="colorPrimary">@color/colorPrimary</item>
76
<item name="android:statusBarColor">#ffffff</item>
87
</style>
9-
<style name="ResetEditText" parent="@android:style/Widget.EditText">
10-
<item name="android:padding">0dp</item>
11-
<item name="android:textColorHint">#c8c8c8</item>
12-
<item name="android:textColor">@android:color/black</item>
13-
</style>
148
<style name="Theme.App.SplashScreen" parent="Theme.SplashScreen">
159
<item name="windowSplashScreenBackground">@color/splashscreen_background</item>
1610
<item name="windowSplashScreenAnimatedIcon">@drawable/splashscreen_logo</item>
1711
<item name="postSplashScreenTheme">@style/AppTheme</item>
12+
<item name="android:windowSplashScreenBehavior">icon_preferred</item>
1813
</style>
1914
</resources>

android/build.gradle

Lines changed: 17 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,24 @@
11
// Top-level build file where you can add configuration options common to all sub-projects/modules.
22

33
buildscript {
4-
ext {
5-
buildToolsVersion = findProperty('android.buildToolsVersion') ?: '35.0.0'
6-
minSdkVersion = Integer.parseInt(findProperty('android.minSdkVersion') ?: '24')
7-
compileSdkVersion = Integer.parseInt(findProperty('android.compileSdkVersion') ?: '35')
8-
targetSdkVersion = Integer.parseInt(findProperty('android.targetSdkVersion') ?: '34')
9-
kotlinVersion = findProperty('android.kotlinVersion') ?: '1.9.24'
10-
11-
ndkVersion = "26.1.10909125"
12-
}
13-
repositories {
14-
google()
15-
mavenCentral()
16-
}
17-
dependencies {
18-
classpath('com.android.tools.build:gradle')
19-
classpath('com.facebook.react:react-native-gradle-plugin')
20-
classpath('org.jetbrains.kotlin:kotlin-gradle-plugin')
21-
}
4+
repositories {
5+
google()
6+
mavenCentral()
7+
}
8+
dependencies {
9+
classpath('com.android.tools.build:gradle')
10+
classpath('com.facebook.react:react-native-gradle-plugin')
11+
classpath('org.jetbrains.kotlin:kotlin-gradle-plugin')
12+
}
2213
}
2314

24-
apply plugin: "com.facebook.react.rootproject"
25-
2615
allprojects {
27-
repositories {
28-
maven {
29-
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
30-
url(new File(['node', '--print', "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim(), '../android'))
31-
}
32-
maven {
33-
// Android JSC is installed from npm
34-
url(new File(['node', '--print', "require.resolve('jsc-android/package.json', { paths: [require.resolve('react-native/package.json')] })"].execute(null, rootDir).text.trim(), '../dist'))
35-
}
36-
37-
google()
38-
mavenCentral()
39-
maven { url 'https://www.jitpack.io' }
40-
}
16+
repositories {
17+
google()
18+
mavenCentral()
19+
maven { url 'https://www.jitpack.io' }
20+
}
4121
}
22+
23+
apply plugin: "expo-root-project"
24+
apply plugin: "com.facebook.react.rootproject"

android/gradle.properties

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m
1515
# When configured, Gradle will run in incubating parallel mode.
1616
# This option should only be used with decoupled projects. More details, visit
1717
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18-
# org.gradle.parallel=true
18+
org.gradle.parallel=true
1919

2020
# AndroidX package structure to make it clearer which packages are bundled with the
2121
# Android operating system, and which are packaged with your app's APK
@@ -41,6 +41,11 @@ newArchEnabled=true
4141
# If set to false, you will be using JSC instead.
4242
hermesEnabled=true
4343

44+
# Use this property to enable edge-to-edge display support.
45+
# This allows your app to draw behind system bars for an immersive UI.
46+
# Note: Only works with ReactActivity and should not be used with custom Activity.
47+
edgeToEdgeEnabled=true
48+
4449
# Enable GIF support in React Native images (~200 B increase)
4550
expo.gif.enabled=true
4651
# Enable webp support in React Native images (~85 KB increase)
@@ -54,3 +59,7 @@ EX_DEV_CLIENT_NETWORK_INSPECTOR=true
5459

5560
# Use legacy packaging to compress native libraries in the resulting APK.
5661
expo.useLegacyPackaging=false
62+
63+
# Specifies whether the app is configured to use edge-to-edge via the app config or plugin
64+
# WARNING: This property has been deprecated and will be removed in Expo SDK 55. Use `edgeToEdgeEnabled` or `react.edgeToEdgeEnabled` to determine whether the project is using edge-to-edge.
65+
expo.edgeToEdgeEnabled=true
181 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)