I am trying to display Google Maps in my Ionic app & center on my current location.
When I run this on my laptop, it displays as expected.
But when I try to run it on my mobile device, the map isn't rendering.
Here is the code:
ngAfterViewInit() {
this.locateUser();
console.log('My Coords', this.coordinates);
this.getGoogleMaps().then(googleMaps => {
const mapEl = this.mapElementRef.nativeElement;
const map = new googleMaps.Map(mapEl, {
center: this.coordinates,
zoom: 16
});
googleMaps.event.addListenerOnce(map, 'idle', () => {
this.renderer.addClass(mapEl, 'visible');
});
}).catch(err => {
console.log('Google Maps error:', err);
});
}
private getGoogleMaps() {
const win = window as any;
const googleModule = win.google;
if (googleModule && googleModule.maps) {
return Promise.resolve(googleModule.maps);
}
return new Promise((resolve, reject) => {
const script = document.createElement('script');
script.src = 'https://maps.googleapis.com/maps/api/js?key=myAPIKey';
script.async = true;
script.defer = true;
document.body.appendChild(script);
script.onload = () => {
const loadedGoogleModule = win.google;
if (loadedGoogleModule && loadedGoogleModule.maps) {
resolve(loadedGoogleModule.maps);
} else {
reject('Google Maps SDK not available.');
}
};
});
}
private locateUser() {
if (!Capacitor.isPluginAvailable('Geolocation')) {
this.showErrorAlert();
return;
}
Plugins.Geolocation.getCurrentPosition()
.then(geoPosition => {
this.coordinates = {
lat: geoPosition.coords.latitude,
lng: geoPosition.coords.longitude
};
console.log(this.coordinates);
})
.catch(err => {
this.showErrorAlert();
});
}
Can someone please tell me why this is working on my laptop, but not on my mobile?
Also, here are the steps I'm taking to run on the mobile:
ionic build
ionic capacitor run android
Then I run the app in Android Studio.
Related
I'm using the react native ble manager package to build a react native app that communicates with a python client over BLE.
When writing to a characteristic on Android (this bug does not seem to appear on IOS) the write is successful but shortly after it I receive this error:
ERROR Error writing eeee2a38-0000-1000-8000-00805f9b34fb status=14
This is the simplified code that handles connecting, notifications and writing on the Android side:
import { NativeModules, NativeEventEmitter, Platform } from 'react-native'
import BleManager, { Peripheral } from 'react-native-ble-manager'
import { END } from 'redux-saga'
import { bytesToString } from 'convert-string'
const UPDATE_SERVICE_UUID = '0000180d-aaaa-1000-8000-00805f9b34fb'
export const Characteristic =
{
WIFI_STATUS_UUID: 'bbbb2a38-0000-1000-8000-00805f9b34fb',
WIFI_CREDS_UUID: 'aaaa2a38-0000-1000-8000-00805f9b34fb',
VERSION_UUID: 'cccc2a38-0000-1000-8000-00805f9b34fb',
UPDATE_STATUS_UUID: 'dddd2a38-0000-1000-8000-00805f9b34fb',
DO_UPDATE_UUID: 'eeee2a38-0000-1000-8000-00805f9b34fb',
ERROR_UUID: 'ffff2a38-0000-1000-8000-00805f9b34fb',
}
class BLEManager {
bleManagerModule: any
bleManagerEmitter: any
scanning: boolean
dispatch: any
stopScanListener: any
peripheralDiscoverListener: any
characteristicUpdateListener: any
onDisconnectListener: any
connectTimeout: any
constructor() {
BleManager.start({ showAlert: false })
this.bleManagerModule = NativeModules.BleManager
this.bleManagerEmitter = new NativeEventEmitter(this.bleManagerModule)
this.scanning = false
}
startScan = (onPeripheralFound: (peripheral: Peripheral | null) => void) => {
if (!this.scanning) {
BleManager.scan([], 3, true)
.then(() => {
console.log('Scanning...')
this.scanning = true
this.peripheralDiscoverListener = this.bleManagerEmitter.addListener(
'BleManagerDiscoverPeripheral',
onPeripheralFound,
)
this.stopScanListener = this.bleManagerEmitter.addListener(
'BleManagerStopScan',
() => {
onPeripheralFound(END)
},
)
return
})
.catch(err => {
console.error(err)
})
} else {
console.log('already scanning')
}
return () => {
console.log('stopped scanning')
this.peripheralDiscoverListener.remove()
this.stopScanListener.remove()
}
}
getBondedDevices = (onGetBondedPeripherals: any) => {
BleManager.getBondedPeripherals().then(bondedPeripheralsArray => {
onGetBondedPeripherals(bondedPeripheralsArray)
// TODO: is the END message here necessary?
onGetBondedPeripherals(END)
return
})
return () => {}
}
connectToPeripheral = async (peripheralID: string) => {
try {
await new Promise(async (resolve, reject) => {
this.connectTimeout = setTimeout(reject, 3000)
console.log('connecting to ' + peripheralID)
try {
await BleManager.connect(peripheralID)
await BleManager.retrieveServices(peripheralID)
} catch (error) {
reject()
}
if (this.connectTimeout) {
clearTimeout(this.connectTimeout)
this.connectTimeout = null
this.onDisconnectListener = this.bleManagerEmitter.addListener(
'BleManagerDisconnectPeripheral',
this.onDisconnectPeripheral,
)
resolve()
}
})
} catch (err) {
clearTimeout(this.connectTimeout)
this.connectTimeout = null
console.error('Could not connect to device.')
throw new Error(err)
}
return
}
watchForCharacteristicsUpdates = async (
updateCharValue: (arg0: { payload: any }) => void,
peripheralID: string,
) => {
try {
await BleManager.startNotification(
peripheralID,
UPDATE_SERVICE_UUID,
Characteristic.ERROR_UUID,
)
await BleManager.startNotification(
peripheralID,
UPDATE_SERVICE_UUID,
Characteristic.VERSION_UUID,
)
await BleManager.startNotification(
peripheralID,
UPDATE_SERVICE_UUID,
Characteristic.UPDATE_STATUS_UUID,
)
} catch (e) {
updateCharValue(new Error(e))
console.error(e)
}
console.log('watch for notifications')
this.characteristicUpdateListener = this.bleManagerEmitter.addListener(
'BleManagerDidUpdateValueForCharacteristic',
({ value, characteristic }) => {
// Convert bytes array to string
const data = bytesToString(value)
console.log(
`Received ${data} (${value}) for characteristic ${characteristic}`,
)
updateCharValue({
payload: {
characteristic: characteristic,
data: data,
},
})
},
)
}
disconnectFromPeripheral = async (peripheralID: string) => {
await BleManager.disconnect(peripheralID)
this.characteristicUpdateListener.remove()
}
onDisconnectPeripheral = (peripheralID: string) => {
console.log(peripheralID + ' disconnected')
this.onDisconnectListener.remove()
}
checkIfConnected = async (peripheralID: string) => {
return await BleManager.isPeripheralConnected(peripheralID, [])
}
triggerUpdateCheck = async (peripheralID: string) => {
return await BleManager.write(
peripheralID,
UPDATE_SERVICE_UUID,
Characteristic.WIFI_STATUS_UUID,
[1],
)
}
runUpdate = async (peripheralID: string) => {
return await BleManager.write(
peripheralID,
UPDATE_SERVICE_UUID,
Characteristic.DO_UPDATE_UUID,
[1],
)
}
}
const bleManager = new BLEManager()
export default bleManager
I've researched this a bit and it seems that some people have the problem but I could not find an explanation or solution to it.
I'm even unsure where to start debugging. Any suggestions are welcome.
Details:
Device: [Pixel 6]
OS: [Android 12]
react-native-ble-manager version: ^8.4.1
react-native version: 0.67.4
Note: I've also asked this question on Github: https://github.com/innoveit/react-native-ble-manager/issues/887
The problem (as mentioned by Martijn) was the bug in Bluez which is fixed in 5.65. Simply upgrading and clearing the Bluetooth cache fixed it.
http.setRequestTimeout for Android has no effect, whereas iOS works perfectly. I am using IONIC 5 with Angular. Any suggestions?
import { HTTP } from '#ionic-native/http/ngx';
...
const GetRequestTimeoutSeconcs: number = 30;
...
private http: HTTP,
...
private sendGetCommand(ip: string, command: string): any{
let _self = this;
// Send message
return new Promise(function(resolve, reject) {
_self.http.setRequestTimeout(GetRequestTimeoutSeconcs);
_self.http.get('http://' + ip + '/' + command, {}, {})
.then(data => {
resolve(_self.decodeMessage(data.data));
})
.catch(error => {
reject(error);
});
});
}
I have an ionic5 app with Capacitor that I'd like to deploy on android. When the app starts I'm getting a list of reminders (from API) I'd like to schedule to be shown as local notifications during the day. After deploying it to my device (by .apk file) is working fine when it's open but after some time when the phone is not in use it's getting sleep and no notification appears. What would be the best way to solve that case? This is my last code with BackgroundTask but it doesn't work anyway.
import { Injectable } from "#angular/core";
import { Job } from "src/entities/respons/_respons";
import { Plugins } from '#capacitor/core';
const { LocalNotifications, BackgroundTask } = Plugins;
#Injectable({
providedIn: 'root',
})
export class NotificationsService {
constructor() {
LocalNotifications.requestPermission();
console.log(` Initialized on ${new Date().toLocaleString()}`);
}
async setup(jobs: Job[]) {
let id: number = 0;
let taskId = BackgroundTask.beforeExit(async () => {
let toSchedule = jobs.filter(e => (e.isActive || e.isFuture) && !e.isNotified);
id = toSchedule.length;
console.log(`Setup, count ${id};`)
let notificationInterval = setInterval(async () => {
let toNotify = jobs.filter(e => e.isActive && !e.isNotified);
if (toNotify.length > 0) {
let logger: string = '';
toNotify.forEach(async job => {
let d = new Date(job.since);
logger += `[${d.toLocaleTimeString()} ${job.name}], `;
await LocalNotifications.schedule({
notifications: [
{
id: job.id,
title: `${job.name} ${d.toLocaleTimeString()}`,
body: job.body,
iconColor: '#0081ca'
}
]
});
job.isNotified = true;
id--;
});
console.log(`Tick on ${new Date(Date.now()).toTimeString()} , count ${toNotify.length}; Scheduled: ${logger}`)
}
if (id <= 0) {
console.log(`Task finished ${id}; no.:${taskId}`);
clearInterval(notificationInterval);
BackgroundTask.finish({
taskId
});
} else {
console.log(`Task in progress ${id}; no.:${taskId}`,)
}
}, 60000)
});
}
}
I Making a chess app with react native, i sending & receiving my request with websocket,
when i run my app in ios every thing is ok,but when i run my app in android the web socket not open and return " Expected HTTP 101 response but was '403 Forbidden' ".
my create game code :
createGame() {
const { playConfig } = this.props;
fetch('https://en.lichess.org/setup/ai', {
method: 'POST',
headers: {
Accept: 'application/vnd.lichess.v2+json',
'Content-Type': 'application/json',
},
body: playConfig,
})
.then(res => res.json())
.then(this.onGameCreated);
}
onGameCreated = res => {
const { game } = this.state;
const socketUrl = res.url.socket;
const clientId = Math.random().toString(36).substring(2);
clearInterval(this.interval);
this.wsReady = false;
let url = `wss://socket.lichess.org${socketUrl}?sri=${clientId}&mobile=1`;
this.ws = new WebSocket(
url,
);
this.ws.onmessage = e => {
// a message was received
console.log(`received: ${e.data}`);
const data = JSON.parse(e.data);
let moveData;
let victor;
if (data.t === 'move' && data.v > game.history().length) {
moveData = data.d;
} else if (data.t === 'end') {
victor = data.d;
} else if (data.t === 'b') {
// b for batch
const first = data.d[0];
if (first) {
if (first.d.status && first.d.status.name === 'mate') {
moveData = first.d;
}
if (first.t === 'end') {
victor = first.d;
}
if (first.d.winner) {
victor = first.d.winner;
}
}
}
if (victor) {
dongSound.play();
this.setState({
victor,
});
this.ws = null;
} else if (moveData) {
const { uci, clock } = moveData;
const castle = moveData.castle;
let from = uci.substring(0, 2);
let to = uci.substring(2, 4);
if (castle && castle.king) {
from = castle.king[0];
to = castle.king[1];
}
this.board.movePiece(to, from);
if (clock) {
this.latestClock = clock;
}
}
};
this.ws.onerror = e => {
// an error occurred
console.log(e.message);
};
this.ws.onopen = () => {
this.wsReady = true;
dongSound.play();
this.setState({
initialized: true,
userColor: res.player.color === 'white' ? 'w' : 'b',
});
console.log('ws open');
// ping every second
this.interval = setInterval(
() => {
this.sendMessage({
t: 'p',
v: game.history().length,
});
},
1000,
);
};
};
any one has idea?
thank you in advance
Looks like you don't have permission to open a socket on this webserver.
I don't think the problem is in your Java code but the webserver configuration.
here is code
beacon-provider.ts >>
initialise(): any {
let promise = new Promise((resolve, reject) => {
if (this.platform.is('cordova')) {
IBeacon.enableBluetooth();
this.delegate = IBeacon.Delegate();
this.delegate.didRangeBeaconsInRegion()
.subscribe(
data => {
this.events.publish('didRangeBeaconsInRegion', data);
},
error => console.error()
);
this.region = IBeacon.BeaconRegion('deskBeacon', '24DDF411-8CF1-440C-87CD-E368DAF9C93E');
IBeacon.startRangingBeaconsInRegion(this.region)
.then(
() => {
resolve(true);
},
error => {
console.error('Failed to begin monitoring: ', error);
resolve(false);
}
);
} else {
console.error("This application needs to be running on a device");
resolve(false);
}
});
return promise;
}
}
home.ts >>
export class HomePage {
beacons: BeaconModel[] = [];
zone: any;
constructor(public navCtrl: NavController, public platform: Platform, public beaconProvider: BeaconProvider, public events: Events) {
this.zone = new NgZone({ enableLongStackTrace: false });
}
ionViewDidLoad() {
this.platform.ready().then(() => {
this.beaconProvider.initialise().then((isInitialised) => {
if (isInitialised) {
this.listenToBeaconEvents();
}
});
});
}
listenToBeaconEvents() {
this.events.subscribe('didRangeBeaconsInRegion', (data) => {
this.zone.run(() => {
this.beacons = [];
let beaconList = data.beacons;
beaconList.forEach((beacon) => {
let beaconObject = new BeaconModel(beacon);
this.beacons.push(beaconObject);
});
});
});
}
}
In this code, the result of alert(JSON.stringify(data)) is:
{"eventType":"didRangeBeaconslnRegion","region":{"identifier":"desk beacon","uuid":"24DDF411-8CF1-440C-87CD-E368DAF9C93E","typeName":"BeaconRegion"}, "beacons":[]}
The field data.beacons is empty.
What is the problem?
one more question i try BLE-central plugin first but,
when i was using BLE-central plugin i get signal but it was not given to me major , minor value if i get this value from advertising ?
There are lots of things that might cause this behavior:
Verify that Bluetooth is on
Verify that your app has been granted runtime location permissions needed to detect Bluetooth devices. Go to Settings -> Apps -> [Your app name] -> Permissions, and make sure you see a Location entry with the switch turned on.
Verify using an off-the-shelf detector app that your beacon actually is transmitting the identifier you expect. Try my Locate app here: https://play.google.com/store/apps/details?id=com.radiusnetworks.locate&hl=en