Flutter Bluetooth detection on iOS for scanning beacons - ios

I'm developing an app and I need to scan iBeacons. I used the beacons_plugin (https://pub.dev/packages/beacons_plugin) and it was working well on Android and iOS. But since the 2.0.0 it's not working anymore on iOS. I tried to understand why but I couldn't. Any help please ?
my info.plist :
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>MiLo</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>$(FLUTTER_BUILD_NAME)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>App needs location permissions to scan nearby beacons.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>App needs location permissions to scan nearby beacons.</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>App needs location permissions to scan nearby beacons.</string>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsLocalNetworking</key>
<true/>
</dict>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
</dict>
</plist>
My widget where I use the plugin :
// All packages needed by the widget
import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:io' show Platform;
import 'dart:convert';
import 'package:beacons_plugin/beacons_plugin.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter_application_1/widgets/beacon_card.dart';
class BeaconDetection extends StatefulWidget {
// Declaration of the variables needed by the widget 1/2
final townId;
final fontsizeValue;
final languageId;
final wordMessageBeforeScan;
final wordButtonLaunchScan;
final wordButtonStopScan;
// Declaration of the variables needed by the widget 2/2
BeaconDetection(
{this.townId,
this.fontsizeValue,
this.languageId,
this.wordMessageBeforeScan,
this.wordButtonLaunchScan,
this.wordButtonStopScan});
#override
_BeaconDetectionState createState() => _BeaconDetectionState();
}
class _BeaconDetectionState extends State<BeaconDetection> {
bool isRunning = false;
String _beaconUuid = '';
double _beaconDistance = 0;
String _beaconDetectedUuid = 'null';
double _beaconDetectedDistance = 0;
final StreamController<String> beaconEventsController =
StreamController<String>.broadcast();
#override
void initState() {
super.initState();
initPlatformState();
}
#override
void dispose() {
beaconEventsController.close();
super.dispose();
}
// Platform messages are asynchronous, so we initialize in an async method.
Future<void> initPlatformState() async {
if (Platform.isAndroid) {
// Prominent disclosure
await BeaconsPlugin.setDisclosureDialogMessage(
title: "Need Location Permission",
message: "This app collects location data to work with beacons.");
// Only in case, you want the dialog to be shown again. By Default, dialog will never be shown if permissions are granted.
// await BeaconsPlugin.clearDisclosureDialogShowFlag(false);
}
BeaconsPlugin.listenToBeacons(beaconEventsController);
// Extraction of the name and the uuid of the beacons of the chosen city from the firebase
FirebaseFirestore.instance
.collection('towns/${widget.townId}/beacons')
.snapshots()
.listen((event) {
event.docs.forEach((element) async {
if (element['name'].isNotEmpty == true &&
element['uuid'].isNotEmpty == true &&
element['visibility'] == true) {
await BeaconsPlugin.addRegion(element['name'], element['uuid']);
}
});
});
// When listening the data from beacons detected
beaconEventsController.stream.listen(
(data) {
if (data.isNotEmpty) {
setState(() {
Map _beaconScanned = jsonDecode(data);
_beaconUuid = _beaconScanned['uuid'];
_beaconDistance = double.parse(_beaconScanned['distance']);
});
// print("Beacons DataReceived: " + data);
FirebaseFirestore.instance
.collection('towns/${widget.townId}/beacons')
.where('uuid', isEqualTo: _beaconUuid)
.snapshots()
.listen((event) {
event.docs.forEach((element) {
if (_beaconUuid == element['uuid'] &&
element['visibility'] == true &&
_beaconDistance <= element['distance']) {
print('Beacon: $_beaconUuid | Distance: $_beaconDistance');
_beaconDetectedUuid = _beaconUuid;
_beaconDetectedDistance = _beaconDistance;
}
});
});
}
},
onDone: () {},
onError: (error) {
print("Error: $error");
});
await BeaconsPlugin.runInBackground(
isRunning); // Send 'true' to run in background
if (Platform.isAndroid) {
BeaconsPlugin.channel.setMethodCallHandler((call) async {
if (call.method == 'scannerReady') {
await BeaconsPlugin.startMonitoring();
setState(() {
isRunning = true;
});
}
});
} else if (Platform.isIOS) {
await BeaconsPlugin.startMonitoring();
setState(() {
isRunning = true;
});
}
if (!mounted) return;
}
Widget build(BuildContext context) {
return Column(
children: [
StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance
.collection('towns/${widget.townId}/beacons')
.where('uuid', isEqualTo: _beaconDetectedUuid)
.snapshots(),
builder: (ctx, snapshot) {
if (snapshot.connectionState ==
ConnectionState.waiting) // Initialisation state
return Container(
margin: const EdgeInsets.all(10),
height: 314, // Beacon card's size
child: Center(child: CircularProgressIndicator()),
);
if (_beaconDetectedUuid == 'null' &&
isRunning == false) // Before first scan State
return Container(
margin: const EdgeInsets.all(10),
height: 314, // Beacon card's size
child: Center(child: Text(widget.wordMessageBeforeScan)),
);
if (_beaconDetectedUuid == 'null' &&
isRunning == true) // Launch first scan state
return Container(
margin: const EdgeInsets.all(10),
height: 314, // Beacon card's size
child: Center(
child: CircularProgressIndicator(),
),
);
final beacons = snapshot.data!.docs;
return BeaconCard( // When the detection is done => Display the widget 'BeaconCard' with the following data
title: beacons[0]['title'],
monument: beacons[0]['monument'],
image: beacons[0]['image'],
duration: beacons[0]['duration'],
distance: _beaconDetectedDistance,
townId: widget.townId,
uuid: beacons[0]['uuid'],
fontsizeValue: widget.fontsizeValue,
languageId: widget.languageId,
);
}),
isRunning
? FloatingActionButton.extended( // If 'isRunning' is true => Display a button to stop the scan
icon: Icon(Icons.bluetooth_disabled),
label: Text(widget.wordButtonStopScan),
backgroundColor: Colors.red,
onPressed: () async {
await BeaconsPlugin.stopMonitoring();
setState(() {
isRunning = false;
});
},
)
: FloatingActionButton.extended( // If 'isRunning' is false => Display a button to start the scan
icon: Icon(Icons.bluetooth),
label: Text(widget.wordButtonLaunchScan),
backgroundColor: Theme.of(context).primaryColor,
onPressed: () async {
initPlatformState();
await BeaconsPlugin.startMonitoring();
setState(() {
isRunning = true;
_beaconDetectedUuid = 'null';
});
},
),
SizedBox(
height: 16,
)
],
);
}
}
Thanks a lot

Related

How to run app on mobile web with flutter URI schemes

I'm trying to start my flutter app when it connects to a specific URI on the mobile web.
Among other methods, we decided to use URI schemes.
Assuming my specific URI link is e.g. https://myFlutterTest.URISchemes
Run the URI like this: https://myFlutterTest.URISchemes/home?<parameter>
I determine whether to run the app normally based on /home. After that, the value of <parameter> is stored in the Map.
I succeeded in receiving android as a URI and running it normally.
But IOS didn't succeed.
Added below to info.plist
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>https</string>
</array>
<key>CFBundleURLName</key>
<string>myFlutterTest.URISchemes</string>
</dict>
</array>
main.dart(
The part that receives and determines the URI path)
Widget build(BuildContext context) {
HttpProvider httpProbvider = HttpProvider();
return Platform.isAndroid
? MaterialApp(
debugShowCheckedModeBanner: false,
initialRoute: "/",
onGenerateRoute: (RouteSettings path) {
if (path.name!.contains("/home")) {
print("path.name : ${path.name}");
return MaterialPageRoute(
builder: (BuildContext context) => Home(),
);
}
},
)
: CupertinoApp(
debugShowCheckedModeBanner: false,
initialRoute: "/",
onGenerateRoute: (RouteSettings path) {
if (path.name!.contains("/home")) {
print("path.name : ${path.name}");
return CupertinoPageRoute(
builder: (BuildContext context) => Home(),
);
}
},
);
}
}
If you know anything wrong, please let me know. Thank you.

Flutter webview is blank on IOS but working on android

I'm using flutter webview to present the payment url in my app using the following class:
class YourWebView extends StatelessWidget {
String url;
bool isFinshed = false;
YourWebView(this.url);
final Completer<WebViewController> _controller =
Completer<WebViewController>();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('اكمال عملية الدفع..'),
leading: new IconButton(
icon: new Icon(Icons.close),
onPressed: () {
if(isFinshed) {
Provider.of<MatchProvider>(context, listen: false)
.getMyComingMatches();
Navigator.of(context).popUntil((route) => route.isFirst);
} else {
Navigator.pop(context);
}
}),
),
body: Builder(builder: (BuildContext context) {
return WebView(
initialUrl: Uri.encodeFull(url),
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController webViewController) {
_controller.complete(webViewController);
},
debuggingEnabled: true,
onPageFinished: (String url) {
SystemChannels.textInput.invokeMethod('TextInput.hide');
if (url.contains("tap/check?tap_id")) {
isFinshed = true;
}
print('Page finished loading: $url');
},
gestureRecognizers: null,
// gestureNavigationEnabled: false
);
}));
}
The url looks like:
https://xxxxxx.com/tap/check?tap_id=chg_TS05162021120xxxxxxx
Everything is working on Android, but on IOS i get a blank screen and i see this error in xcode debug logs :
WebPageProxy::didFailProvisionalLoadForFrame
I have tried to run another urls on the webview and it was working, but the payment url isn't, even though it's working on Android or other browsers.
I think you maybe tried to load a http link in webview instead of https. In that case you should add the following in your info.plist file.
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key><true/>
</dict>
I am not familiar with Flutter, but on iOS, if the system's process for rendering the web content terminated, the webview would be blank, the flutter plugin is handling the situation in here, you may have to check the error and do a reload.

WebView not working in iOS using flutter but working in Android

i am using webview_flutter: 1.0.7 in flutter. It's working in android but not working in iOS.
I have added below code in info.plist for webview_flutter.
<key>io.flutter.embedded_views_preview</key>
<string>YES</string>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
<key>NSAllowsArbitraryLoadsInWebContent</key>
<true/>
</dict>
and webview controller code is
Container(
height: wvHeight,
child: WebView(
onPageFinished: (some) async {
String h = await mWebViewControllerSolution
.evaluateJavascript("document.documentElement.scrollHeight;");
if (h != null) {
print("H = " + h.toString());
double height = double.parse(h);
setState(() {
wvHeight = height;
});
}
},
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController webViewController) {
mWebViewControllerSolution = webViewController;
wvSolutionNavigation(context);
},
),
);
wvSolutionNavigation(BuildContext context) async {
String html = getSolution();
if (!Utils.isTable(html)) {
return;
}
if (html.isEmpty) {
return;
}
final String contentBase64 =
base64Encode(const Utf8Encoder().convert(html));
await mWebViewControllerSolution
.loadUrl('data:text/html; charset=utf-8;base64,$contentBase64');
}
giving error :
Unhandled Exception: PlatformException(loadUrl_failed, Failed parsing the URL, Request was: '{
headers = "";
url = "data:text/html; charset=utf-8;base64,PHA+VGhlIGNvcnJlY3QgYW5zd2VyIGlzIDxzdHJvbmc+T3B0aW9uIDI8L3N0cm9uZz4gaS5lJm5ic3A7PHN0cm9uZz5LZXNhdmFuYW5kYSBCaGFyYXRpIGNhc2UuPC9zdHJvbmc+PC9wPg0KDQo8dWw+DQoJPGxpPkluIHRoZSZuYnNwOzxzdHJvbmc+S2VzYXZhbmFuZGEgQmhhcmF0aSBjYXNlPC9zdHJvbmc+LCB0aGUgU3VwcmVtZSBjb3VydCBoZWxkIHRoYXQgdGhlICZxdW90OzxzdHJvbmc+YmFzaWMgc3RydWN0dXJlIG9mIHRoZSBDb25zdGl0dXRpb24gY291bGQgbm90IGJlIGFicm9nYXRlZCBldmVuIGJ5IGEgY29uc3RpdHV0aW9uYWwgYW1lbmRtZW50JnF1b3Q7PC9zdHJvbmc+PC9saT4NCjwvdWw+DQoNCjx0YWJsZSBib3JkZXI9IjEiIGNlbGxwYWRkaW5nPSIxIiBjZWxsc3BhY2luZz0iMSIgc3R5bGU9IndpZHRoOjM4OC4wcHgiPg0KCTx0Ym9keT4NCgkJPHRyPg0KCQkJPHRkIHN0eWxlPSJ0ZXh0LWFsaWduOmNlbnRlciI+PHN0cm9uZz5DYXNlczwvc3Ryb25nPjwvdGQ+DQoJCQk8dGQgc3R5bGU9InRleHQtYWxpZ246Y2VudGVyIj48c3Ryb25nPlN1cHJlbWUgQ291cnQgdmVyZGljdDwvc3Ryb25nPjwvdGQ+DQoJCTwvdHI+DQoJCTx0cj4NCgkJCTx0ZD5Hb2xha25hdG<…>

programmatically change language of flutter i18n apps doesn't work in iOS

I used flutter_i18n plugin (Android Studio) to generate i18n.dart(class S) and S.of(context).locale_msg will return the locale string. The main code is shown below.
Language should be changed programmatically by invoking onLocaleChange(locale) when click the button in HomePage. It works well in Android simulator, but won't change language in iOS simulator. Wonder what's wrong with my code?
class _PaperMoonAppState extends State<PaperMoonApp> {
SpecifiedLocalizationDelegate _localeOverrideDelegate;
void onLocaleChange(Locale locale) {
setState(() {
if (appVars.appConfig.changeLanguage(locale)) {
_localeOverrideDelegate = new SpecifiedLocalizationDelegate(locale);
appVars.saveConfig(); //print save config file...
}
});
}
#override
void initState() {
SpecifiedLocalizationDelegate.onLocaleChange = this.onLocaleChange;
appVars.loadConfig().then((AppConfig _config) {
appVars.appConfig = _config;
setState(() {
_localeOverrideDelegate =
new SpecifiedLocalizationDelegate(appVars.appConfig.getLocale());
});
});
_localeOverrideDelegate =
new SpecifiedLocalizationDelegate(Locale('zh', ''));
super.initState();
}
#override
Widget build(BuildContext context) {
print(_localeOverrideDelegate.overriddenLocale);
return MaterialApp(
debugShowCheckedModeBanner: false,
title: "Paper Moon",
color: Colors.blueAccent,
localizationsDelegates: [
_localeOverrideDelegate,
S.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate
],
supportedLocales: const <Locale>[
Locale("ja", ""),
Locale("en", ""),
Locale("zh", ""),
],
localeResolutionCallback:
S.delegate.resolution(fallback: _localeOverrideDelegate.overriddenLocale),
home: HomePage(),
// routes: _buildRoutes(),
);
}
}
Custom LocalizationDelegate:
class SpecifiedLocalizationDelegate
extends LocalizationsDelegate<WidgetsLocalizations> {
//class static vars:
//onLocaleChange should be bind to MaterialApp function containing setState().
static LocaleChangeCallback onLocaleChange;
// for instance
final Locale overriddenLocale;
const SpecifiedLocalizationDelegate(this.overriddenLocale);
#override
bool isSupported(Locale locale) => overriddenLocale != null;
#override
Future<WidgetsLocalizations> load(Locale locale) =>
S.delegate.load(overriddenLocale);
#override
bool shouldReload(SpecifiedLocalizationDelegate old) => true;
}
Based on your code, the only thing that seems to be missing is this:
open ios/Runner/Info.plist and add:
<key>CFBundleLocalizations</key>
<array>
<string>ja</string>
<string>en</string>
<string>zh</string>
</array>
As far I as know, by now (march/2019), flutter doesn't yet add automatically the list of supported languages to this file.
I'm using i18n_extensions, but with the same issue...
What worked for me, was use this:
supportedLocales: const <Locale>[
const Locale('en'),
const Locale('pt'),
],
Instead of this:
supportedLocales: const <Locale>[
const Locale('en', 'US'),
const Locale('pt', 'BR'),
],
And then, my i18n.dart. file i've change from this:
extension Localization on String {
static final _t = Translations.from("en_us", {
passwordInput: {
"en_us": "Password",
"pt_br": "Senha",
},
searchingTitle: {
"en_us": "Scanning for devices...",
"pt_br": "Procurando dispositivos...",
},
...
To this:
extension Localization on String {
static final _t = Translations.from("en", {
passwordInput: {
"en": "Password",
"pt": "Senha",
},
searchingTitle: {
"en": "Scanning for devices...",
"pt": "Procurando dispositivos...",
},
It works fine for me.

Ionic 3: WARNING: sanitizing unsafe URL value

I´m trying to take a photo and analyze it with the tesseract OCR engine in ionic 3 App for iOS. I´m trying to run it on a iPhone 8 iOS 11.2.6
Unfortunately I get an error in Xcode after taking a photo, and the app crashes:
NSURLConnection finished with error - code -1002
and also WARNING: sanitizing unsafe URL value assets-library://asset/asset.JPG?id=A791150A-3E89-400E-99D3-E7B3A3D888AA&ext=JPG
Thank you for your help
home.html
<h3 *ngIf="debugText">Debug: {{debugText}}</h3>
<span>{{recognizedText}}</span>
<!--<img src="assets/img/demo.png" #demoImg class="start-api" />-->
<img [src]="image" #imageResult />
<div *ngIf="_ocrIsLoaded && !image">
<!--<img src="assets/img/Start-arrow.png" #start class="start-arrow" />-->
</div>
home.ts:
import { Component, ViewChild, ElementRef, NgZone } from '#angular/core';
import { NavController } from 'ionic-angular';
import { Camera } from '#ionic-native/camera';
import { Platform, ActionSheetController, LoadingController } from 'ionic-angular';
import Tesseract from 'tesseract.js';
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
#ViewChild('imageResult') private imageResult: ElementRef;
#ViewChild('demoImg') private demoImg: ElementRef;
private recognizedText: string;
image: string = '';
_zone: any;
_ocrIsLoaded: boolean = false;
brightness: number = 12;
contrast: number = 52;
unsharpMask: any = { radius: 100, strength: 2 };
hue: number = -100;
saturation: number = -100;
showEditFilters: boolean = false;
debugText: string = '';
constructor(
private camera: Camera,
public navCtrl: NavController,
public platform: Platform,
public loadingCtrl: LoadingController,
public actionsheetCtrl: ActionSheetController) {
this._zone = new NgZone({ enableLongStackTrace: false });
}
openMenu() {
if (this._ocrIsLoaded === true) {
let actionSheet;
if (!this.image) {
actionSheet = this.actionsheetCtrl.create({
title: 'Actions',
cssClass: 'action-sheets-basic-page',
buttons: [
{
text: 'Random demo',
icon: !this.platform.is('ios') ? 'shuffle' : null,
handler: () => {
this.randomDemo()
}
},
{
text: 'Take Photo',
icon: !this.platform.is('ios') ? 'camera' : null,
handler: () => {
this.takePicture()
}
},
{
text: 'Cancel',
role: 'cancel', // will always sort to be on the bottom
icon: !this.platform.is('ios') ? 'close' : null,
handler: () => {
console.log('Cancel clicked');
}
}
]
});
}
else {
actionSheet = this.actionsheetCtrl.create({
title: 'Actions',
cssClass: 'action-sheets-basic-page',
buttons: [
{
text: 'Random demo',
icon: !this.platform.is('ios') ? 'shuffle' : null,
handler: () => {
this.randomDemo()
}
},
{
text: 'Re-Take photo',
icon: !this.platform.is('ios') ? 'camera' : null,
handler: () => {
this.takePicture()
}
},
{
text: 'Apply filters',
icon: !this.platform.is('ios') ? 'barcode' : null,
handler: () => {
this.filter()
}
},
{
text: 'Clean filters',
icon: !this.platform.is('ios') ? 'refresh' : null,
handler: () => {
this.restoreImage()
}
},
{
text: this.showEditFilters == false ? 'Customize filters' : 'Hide customization filters',
icon: !this.platform.is('ios') ? 'hammer' : null,
handler: () => {
this.showEditFilters = this.showEditFilters == false ? true : false;
}
},
{
text: 'Read image',
icon: !this.platform.is('ios') ? 'analytics' : null,
handler: () => {
this.analyze(this.imageResult.nativeElement.src, false);
}
},
{
text: 'Cancel',
role: 'cancel', // will always sort to be on the bottom
icon: !this.platform.is('ios') ? 'close' : null,
handler: () => {
console.log('Cancel clicked');
}
}
]
});
}
actionSheet.present();
}
else {
alert('OCR API is not loaded');
}
}
restoreImage() {
if (this.image) {
this.imageResult.nativeElement.src = this.image;
}
}
takePicture() {
let loader = this.loadingCtrl.create({
content: 'Please wait...'
});
loader.present();
// Take a picture saving in device, as jpg and allows edit
this.camera.getPicture({
quality: 100,
destinationType: this.camera.DestinationType.NATIVE_URI,
encodingType: this.camera.EncodingType.JPEG,
targetHeight: 1000,
sourceType: 1,
allowEdit: true,
saveToPhotoAlbum: true,
correctOrientation: true
}).then((imageURI) => {
loader.dismissAll();
this.image = imageURI;
this.debugText = imageURI;
}, (err) => {
//console.log(`ERROR -> ${JSON.stringify(err)}`);
});
}
filter() {
/// Initialization of glfx.js
/// is important, to use js memory elements
/// access to Window element through (<any>window)
try {
var canvas = (<any>window).fx.canvas();
} catch (e) {
alert(e);
return;
}
/// taken from glfx documentation
var imageElem = this.imageResult.nativeElement; // another trick is acces to DOM element
var texture = canvas.texture(imageElem);
canvas.draw(texture)
.hueSaturation(this.hue / 100, this.saturation / 100)//grayscale
.unsharpMask(this.unsharpMask.radius, this.unsharpMask.strength)
.brightnessContrast(this.brightness / 100, this.contrast / 100)
.update();
/// replace image src
imageElem.src = canvas.toDataURL('image/png');
}
analyze(image, loadAPI) {
let loader = this.loadingCtrl.create({
content: 'Please wait...'
});
loader.present();
if (loadAPI == true) {
this._ocrIsLoaded = false;
}
/// Recognize data from image
Tesseract.recognize(image, {})
.progress((progress) => {
this._zone.run(() => {
loader.setContent(`${progress.status}: ${Math.floor(progress.progress * 100)}%`)
console.log('progress:', progress);
})
})
.then((tesseractResult) => {
this._zone.run(() => {
loader.dismissAll();
if (loadAPI == true) {
this._ocrIsLoaded = true;
}
console.log('Tesseract result: ');
console.log(tesseractResult);
/// Show a result if data isn't initializtion
if (loadAPI != true) { this.recognizedText = tesseractResult.text; }
});
});
}
randomDemo() {
}
ionViewDidLoad() {
console.log('loaded')
this.analyze(this.demoImg.nativeElement.src, true);
}
}
info.plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleDisplayName</key>
<string>Diagnyzer</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIcons</key>
<dict/>
<key>CFBundleIcons~ipad</key>
<dict/>
<key>CFBundleIdentifier</key>
<string>io.ionic.diagnyzer</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>0.0.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>0.0.1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSMainNibFile</key>
<string/>
<key>NSMainNibFile~ipad</key>
<string/>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UIRequiresFullScreen</key>
<true/>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>ionic.local</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
</dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>NSCameraUsageDescription</key>
<string>This app needs camera access</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>This app needs read/write-access photo library access</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string/>
<key>NSMicrophoneUsageDescription</key>
<string>This app needs microphone access</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>This app needs write-access to photo library</string>
</dict>
</plist>
I do not know much about Ionic, but loading an img in Angular could cause an UnsafeUrl Exception.
Maybe you need to use a Dom Sanitizer.
DomSanitizer using example:
Inject it:
constructor(private sanitizer: DomSanitizer,) {}
And use a function to get the img content:
getImgContent(): SafeUrl {
return this.sanitizer.bypassSecurityTrustUrl(this.imgFile);
}
So you use in HTML Part:
<img class="object-img"
[src]="getImgContent()">
Answering a bit late, but try to add File Path plugin to your project. You can pass your URL and the plugin will resolve it.
Note that this plugin is supported only on Android devices
only put en el get Response ( as string) example
TS
let routeImg = (data.base as string);
HTML
<img *ngIf="routeImg " src="routeImg">

Resources