flutter_armod_widget 2.0.0-pre.1
flutter_armod_widget: ^2.0.0-pre.1 copied to clipboard
Flutter AR-MOD SDK widget for embedding AR(Augmented Reality) features in flutter.
Flutter-ARMOD-Widget #
Flutter AR-MOD widget for embedding AR features in flutter.
What is the ARMOD SDK? #
In short, ARMOD's solution is an AR experience platform solution similar to Snapchat (Lens Studio) and Facebook (SparkAR)!
AR-MOD is a derivative framework based on Unity ARFoundation. MOD in AR-MOD means Modification in English, meaning: modification and module. This concept is widely used in games, corresponding to modifiable video games. Famous games such as Warcraft, Red Alert, Half-Life, CS, Victory Day and more!
We transplant the MOD concept into AR technology to give users more freedom to create the AR creative interactive experience content they need! In this process, users do not need to worry about AR-SDK algorithm and code implementation, but only need to devote themselves to the production of AR creative interactive experience content. With only a small amount of code, you can use all the capabilities of AR-MOD on the APP to create greater commercial value.
Getting Started #
-
Install this plugin to your flutter project. If you do not know how to install the
Flutter Package
you can click here to see the document.Install Guid
The AR-MOD SDK currently provides a plug-in package for Flutter. You can install it through
flutter_armod_widget: ^VERSION
in your flutter projectpubspec.yaml
!# Other config dependencies: flutter: sdk: flutter flutter_armod_widget: ^0.0.3 # Other config
-
Go to PhantomsXR github respository. Download and Unzip it.
-
Choose iOS or Android platform from the options below to set.
Android Setup
- Go to the location of your
FLUTTER SDK PATH/.pub-cache/hosted/pub.dartlang.org/flutter_armod_widget-VERSION/
folder, then paste thelibs
toandroid
platform folder.Maybe hide the
pub-cache
folder. You need to turn on the Show hidden folders option. - Run
Flutter pub get
command in your termial.
iOS Setup
-
Create the
ThirdParties
folder to your XCode project. -
Import
UnityFramework.framework
to the folder(ThridParties). -
Add the Framewrok to
Xcode
->Targets
->Your APP
->General
->Franework,Libraries, and Embedded Content area
, And set the Embed mode toEmbed & Sign
. -
Execute the
cd iOS
command and runPod install
command in your termial. -
Double-Click to open the
Runner.xcworkspace
file. It will be launch the XCode app. -
If you're using Swift, open the ios/Runner/AppDelegate.swift file and change the following:
import UIKit import Flutter + import flutter_armod_widget @UIApplicationMain @objc class AppDelegate: FlutterAppDelegate { override func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { + InitARMODIntegrationWithOptions(argc: CommandLine.argc, argv: CommandLine.unsafeArgv, launchOptions) + let nativeCalls: AnyClass? = NSClassFromString("FrameworkLibAPI") + nativeCalls?.registerAPIforNativeCalls(ARMODCallbackAPI()) GeneratedPluginRegistrant.register(with: self) return super.application(application, didFinishLaunchingWithOptions: launchOptions) } }
If you're using Objective-C, open the ios/Runner/main.m file and change the following:
+ #import "flutter_armod_widget.swift.h" int main(int argc, char * argv[]) { @autoreleasepool { + InitARMODIntegration(argc, argv); + [NSClassFromString(@"FrameworkLibAPI") registerAPIforNativeCalls:[ARMODCallbackAPI alloc]]; return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } }
-
Edit the info.plist
<dict> + <key>io.flutter.embedded_views_preview</key> + <string>YES</string> </dict>
<dict> + <key>Privacy - Camera Usage Description</key> + <string>$(PRODUCT_NAME) uses Cameras</string> </dict>
<dict> + <key>NSBonjourServices</key> + <string>_dartobservatory._tcp</string> </dict>
-
Add
#import <UnityFramework/NativeCallProxy.h>
toRunner-Bridging-Header.h
file.#import "GeneratedPluginRegistrant.h" + #import <UnityFramework/NativeCallProxy.h>
- Go to the location of your
-
Then write a new screen(Flutter) for AR-MOD
import 'dart:async';
import 'package:armod_flutter_store/src/model/data.dart';
import 'package:armod_flutter_store/src/themes/theme.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_armod_widget/flutter_armod_widget.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter/services.dart';
import '../config/phantomsxrConfig.dart';
class ARView extends StatefulWidget {
ARView({Key? key}) : super(key: key);
@override
ARViewState createState() => ARViewState();
}
class ARViewState extends State<ARView> {
late ARMODWidgetController _armodWidgetController;
bool _onWillPop = false;
bool _isClosedByBack = false;
@override
void initState() {
super.initState();
}
@override
void dispose() {
super.dispose();
EasyLoading.dismiss();
}
Widget _appBar() {
return SafeArea(
top: true,
child: GestureDetector(
child: Container(
padding: AppTheme.padding,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Container(
width: 25,
height: 25,
alignment: Alignment.center,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(15)),
),
child: Icon(Icons.close, color: Colors.black54, size: 20),
)
],
),
),
onTap: () async {
await _onBackPressed();
},
));
}
@override
Widget build(BuildContext context) {
return new WillPopScope(
onWillPop: _onBackPressed,
child: new Scaffold(
body: Stack(
children: [
ARMODWidget(
onARMODCreated: onARMODCreate,
onARMODExit: onARMODExit,
onARMODLaunch: onARMODLaunch,
onAddLoadingOverlay: onAddLoadingOverlay,
onDeviceNotSupport: onDeviceNotSupport,
onNeedInstallARCoreService: onNeedInstallARCoreService,
onOpenBuiltInBrowser: onOpenBuiltInBrowser,
onPackageSizeMoreThanPresetSize: onPackageSizeMoreThanPresetSize,
onRecognitionComplete: onRecognitionComplete,
onRecognitionStart: onRecognitionStart,
onRemoveLoadingOverlay: onRemoveLoadingOverlay,
onSdkInitialized: onSdkInitialized,
onThrowException: onThrowException,
onTryAcquireInformation: onTryAcquireInformation,
onUpdateLoadingProgress: onUpdateLoadingProgress,
fullscreen: true,
),
_appBar()
],
),
),
);
}
///Handling the back event
Future<bool> _onBackPressed() async {
//Close AR-MOD SDK
_armodWidgetController.unloadAndHideARMOD();
while (!_onWillPop) {
//We need to delayed executed because release AR-MOD operation is async.
//May need to wait one more frame
await Future.delayed(Duration(milliseconds: 1));
}
_isClosedByBack = true;
return _onWillPop;
}
showAlertDialog(BuildContext context, String title, String msg, bool close) {
// set up the button
Widget okButton = TextButton(
child: Text("OK"),
onPressed: () async {
if (close) {
//Dismiss loading ui
EasyLoading.dismiss();
//Dismiss alert
Navigator.of(context, rootNavigator: true).pop();
//Dismiss view
await _onBackPressed();
}
},
);
// set up the AlertDialog
AlertDialog alert = AlertDialog(
title: Text(title),
content: Text(msg),
actions: [
okButton,
],
);
// show the dialog
showDialog(
barrierDismissible: false,
context: context,
builder: (BuildContext context) {
return alert;
},
);
}
Future<void> onARMODCreate(controller) async {
this._armodWidgetController = controller;
if (await _armodWidgetController.isLoaded() != false)
_armodWidgetController.create();
}
void onARMODLaunch() {
var orientationId =
MediaQuery.of(context).orientation == Orientation.portrait ? '1' : '2';
_armodWidgetController.setDeivcesOrientation(orientationId);
_armodWidgetController.initARMOD('__CONFIGURES__JSON_');
Future.delayed(
Duration(milliseconds: 125),
() => {
_armodWidgetController.fetchProject(AppData.ar_experience_uid),
});
}
void onThrowException(String errorMsg, int erorCode) {
EasyLoading.dismiss();
showAlertDialog(context, "(Error:$erorCode)", errorMsg, true);
}
void onARMODExit() {
//Wait to release all asset
Future.delayed(
Duration(milliseconds: 500),
() => {
_onWillPop = true,
//Close by AR-Experiences
if (!_isClosedByBack) Navigator.of(context).pop(true),
});
}
void onUpdateLoadingProgress(progress) {
EasyLoading.showProgress(progress,
status: '${(progress * 100).toStringAsFixed(0)}%');
}
Future<String> onTryAcquireInformation(String opTag) async {
await Future.delayed(Duration(seconds: 3));
return "onTryAcquireInformation_$opTag";
}
void onAddLoadingOverlay() {
EasyLoading.instance
..indicatorType = EasyLoadingIndicatorType.fadingCircle
..maskColor = Colors.red.withOpacity(0.5)
..dismissOnTap = false;
}
void onRemoveLoadingOverlay() {
EasyLoading.dismiss();
}
void onDeviceNotSupport() {
showAlertDialog(
context,
"Device Not Supported",
"Your device is not supoorted! \n Will downgrade to normal version",
false);
}
void onRecognitionStart() {}
void onNeedInstallARCoreService() {
showAlertDialog(context, "ARCore Service Need",
"You need to install the ARCore service!", false);
}
void onSdkInitialized() {}
void onOpenBuiltInBrowser(url) {}
void onPackageSizeMoreThanPresetSize(currentSize, presetSize) {}
void onRecognitionComplete() {}
}