Android SDK React Native<> Kotlin Bridge
Sample Project for React native (Kotlin-React Bridge)
GitHub: Link | Please request access to Spyne Team
Branch Name: react_native_kotlin_bridge_android
SpyneModule.java
(android/app/src/main/java/com.your.package.name): This class defines the native module that interacts with the Spyne library. It's located in your app's package directory within the Android project.
SpynePackage.java
(android/app/src/main/java/com.your.package.name): This class defines a React package that registers the SpyneModule. It's located in your app's package directory within the Android project.
MainApplication.java
(android/app/src/main/java/com.your.package.name): This is the main application class where you initialize the Spyne library and register the SpynePackage. It's located in your app's package directory within the Android project.
We need to update the enterprise-specific API key in this class.
AndroidBridging.js (Your React Native project root directory)
This JavaScript file defines functions that interact with the SpyneModule methods. It's located in the root directory of your React Native project.
Add dependency in build.gradle (module)
// Spyne Sdk
implementation "com.github.Spyne-Tech:spyne-android-sdk:3.0.3"
In Project-level Build.gradle verify minSdkVersion, compileSdkVersion and targetSdkVersion should be
minSdkVersion = 26
compileSdkVersion = 34
targetSdkVersion = 34
Add this for jitpack Authorization in Project-level Build.gradle
allprojects {
repositories {
google()
mavenCentral()
maven {
url "<https://jitpack.io">
credentials { username = project.properties['authToken'] }
}
}
}
And ‘authToken’ value will be in gradle.properties
authToken=jp_g1e1t35osldunpv5a8u4dcjovr
File Structure:
project-root/
├── android/
│ ├── app/
│ │ └── src/
│ │ └── main/
│ │ └── java/
│ │ └── com/
│ │ └── yourapp
│ │ ├── SpyneModule.java // Java class
│ │ └── SpynePackage.java // Java class
│ │ └── MainApplication
│
├── androidBridging.ts // TypeScript file defining the bridge to call the SpyneModule methods
│
│
└── app.tsx // // Main React Native application file
App.tsx file:
import React, { useEffect } from 'react';
import {
Platform,
View,
Text,
NativeModules,
NativeEventEmitter,
TouchableOpacity,
Button,
StyleSheet,
} from 'react-native';
import { start } from './androidBridging'; // Import the Android bridging module
const App = () => {
const handleStart = () => {
start('[[email protected]](mailto:[email protected])', 'uniqueTest123', 'prod_seY3vxhATCH', false);
};
const handleStart360 = () => {
start('[[email protected]](mailto:[email protected])', 'uniqueTest123', 'prod_seY3vxhATCH', true);
};
return (
<View style={styles.container}>
<Button title="Shoot Images" onPress={handleStart} style={styles.button} />
<View style={styles.spacer} />
<Button title="Shoot Video" onPress={handleStart360} style={styles.button} />
</View>
);
};
const styles = StyleSheet.create({
container: { flex: 1, justifyContent: 'center',alignItems: 'center',},
button: { marginVertical: 10,},
spacer: { height: 20,},
});
export default App;
SpyneModule.java:
@ReactModule(name = SpyneModule.NAME)
@ReactModule(name = SpyneModule.NAME)
public class SpyneModule extends ReactContextBaseJavaModule implements Spyne.SkuListener {
public static final String NAME = "SpyneModule";
public SpyneModule(ReactApplicationContext reactContext) {
super(reactContext);
}
@NonNull
@Override
public String getName() {
return "Spyne";
}
@ReactMethod
public void start(String userID, String uniqueId, String vehicleType, Boolean is360) {
Activity activity = getCurrentActivity();
if (activity != null) {
start(activity, userID, uniqueId, vehicleType, is360);
}
}
public void start(Context context, String userID, String uniqueId, String vehicleType, Boolean is360) {
Activity activity = getCurrentActivity();
if (activity != null) {
Spyne.ShootBuilder builder = new Spyne.ShootBuilder(
context,
userID,
this,
8);
builder.uniqueShootId(uniqueId)
.shootType(ShootType.SHOOT)
.classifier(Classifier.RESTRICTIVE)
.gyroMeter(Gyrometer.RESTRICTIVE)
.subcategoryId(vehicleType)
.syncProject(true);
Spyne spyne = builder.build();
if (is360) {
spyne.startVideoThreeSixty(); // for video shoot flow
} else {
spyne.start(); // for catalog
}
}
}
@Override
public void onShootCompleted(@NonNull String skuId, boolean isReshoot, boolean isThreeSixty) {
// SKU ID will receive at the time of project completion
}
@Override
public void onSkuCreated(@NonNull String skuId) {
// SKU ID will receive at the time of creation of project
}
@Override
public void onProgressChanges(@NonNull String s, double v) {
// Handle progress changes
}
}
SpynePackage.java:
public class SpynePackage implements ReactPackage {
@NonNull
@Override
public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactContext) {
return Arrays.<NativeModule>asList(new SpyneModule(reactContext));
}
@NonNull
@Override
public List<ViewManager> createViewManagers(@NonNull ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}
androidBridging.js :
import { NativeModules } from 'react-native';
const Spyne = NativeModules.Spyne
? NativeModules.Spyne
: new Proxy(
{},
{
get() {
throw new Error('Spyne module not linked');
},
}
);
export const start = (userID, uniqueId, vehicleType, is360) => {
return Spyne.start(userID, uniqueId, vehicleType, is360);
}
MainApplication :
class MainApplication : Application(), ReactApplication {
private val API_KEY = "Enter your Enterprise API Key"
private val CATEGORY_ID = "cat_d8R14zUNE"
override val reactNativeHost: ReactNativeHost =
object : DefaultReactNativeHost(this) {
override fun getPackages(): List<ReactPackage> =
PackageList(this).packages.apply {
// Packages that cannot be autolinked yet can be added manually here, for example:
// add(MyReactNativePackage())
add(SpynePackage())
}
override fun getJSMainModuleName(): String = "index"
override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG
override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED
}
override val reactHost: ReactHost
get() = getDefaultReactHost(applicationContext, reactNativeHost)
override fun onCreate() {
super.onCreate()
SoLoader.init(this, false)
Spyne.Companion.init(this, API_KEY, CATEGORY_ID)
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
// If you opted-in for the New Architecture, we load the native entry point for this app.
load()
}
}
}
Updated 1 day ago