I am trying to send an event from javascript (angular to be specific) to android via the broadcaster plugin : https://github.com/bsorrentino/cordova-broadcaster
In the UI i fire a native event with some data:
this.broadCaster
.fireNativeEvent("com.service.print", { extras: { item: "test data" } })
.then((result) => {
console.log("broadcast sent:" + result);
})
.catch((error) => {
console.log("Error sending broadcast:" + error);
});
On the android i registered a receiver in AndroidManifest.xml:
<receiver android:name="io.ionic.starter.PrintReceiver">
<intent-filter>
<action android:name="com.service.print"></action>
</intent-filter>
</receiver>
And added the PrintReceiver class to handle the broadcast:
public class PrintReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String data = intent.getExtras().getString("data");
List<PrinterCommand> commands = new ArrayList<PrinterCommand>();
// Add commands to be sent
commands.add(
new PrinterCommand(PrinterCommand.CommandType.TEXT, "Normal row 1\n")
);
Gson gson = new Gson();
String json = gson.toJson(commands);
System.out.println("Sending print broadcast: " + json);
Intent printIntent = new Intent(MyPOSUtil.PRINT_BROADCAST);
// Add the commands
printIntent.putExtra("commands", json);
// Send broadcast
LocalBroadcastManager.getInstance(context).sendBroadcastSync(printIntent);
}
}
When i am trying to run the app on Android device i get this error:
2020-07-31 10:31:34.007 11308-11416/io.ionic.starter V/Capacitor/Plugin: To native (Cordova plugin): callbackId: broadcaster343151718, service: broadcaster, action: fireNativeEvent, actionArgs: ["com.service.print",{"extras":{"item":"test data"}},false]
2020-07-31 10:31:34.022 11308-11433/io.ionic.starter V/CDVBroadcaster: sendBroadcast isGlobal=false
2020-07-31 10:31:34.051 11308-11308/io.ionic.starter I/Capacitor/Console: File: http://localhost/auth-auth-module-es2015.js - Line 70 - Msg: Error sending broadcast:OK
Note: i tried using the same plugin to receive a broadcast from android and it works.
What could be the issue here.
Ok Eventually i figured out that there was nothing wrong with the brodcaster plugin and that it actually sends a correct broadcast.
What i learnt is that as of Android 8 you cannot register your receiver in the Manifest.xml, but use context based registration.
Android 8+ manifest registration restrictions
Related
I am building an app with Ionic 5, Capacitor 2 and Angular 11.
I need to capture video and audio using the media capture cordova plugin.
I installed the following modules:
npm install cordova-plugin-media-capture
npm install #ionic-native/media-capture
And added MediaCapture to the providers of my app module.
Then I call mediaCapture.captureVideo() to retrieve a video ; unfortunately an exception is thrown when testing on a browser: cordova_not_available
The github repo states this plugin is web-compatible, and its sources have a browser implementation. However the window.navigator.device.capture is missing to make this plugin work.
Is it a bad configuration from my side? Or this cordova plugin wouldn't be compatible with capacitor?
I made a repro : https://stackblitz.com/edit/ionic-v5-media-capture-capacitor?file=src/app/app.component.ts
Thank you for your help
I wrote a regular Angular version for the web, if anyone need it:
async browserCapture() {
const stream: MediaStream = await navigator.mediaDevices.getUserMedia(this.constraints);
const recorder = new MediaRecorder(stream, {mimeType: 'ogg'});
const chunks: Blob[] = [];
recorder.ondataavailable = (event: BlobEvent) => {
if (event.data && event.data.size > 0) {
chunks.push(event.data);
this.zone.run(() => {
this.recordChunks = [...chunks];
this.cd.markForCheck();
});
}
};
this.recorder.onstop = () => {
this.zone.run(() => {
stream.getTracks().forEach(t => t.stop());
if (chunks?.length) {
this.upload(new Blob(chunks, {type: 'ogg'})); // use the blob result
}
});
};
recorder.start(500);
}
I'm using this plugin: cordova-plugin-media with ionic capacitor instead of cordova with command ionic cap sync.
My code:
audioFile: MediaObject;
constructor(private media: Media, private plt: Platform, private file: File) {}
ionViewDidEnter() {
this.plt.ready()
.then(() => {
setTimeout(() => {
this.audioFile = this.media.create(this.file.externalRootDirectory + 'audiofile.mp3');
this.audioFile.onStatusUpdate.subscribe(status => console.log('status: ', status));
this.audioFile.onSuccess.subscribe(() => console.log('Action is successful'));
this.audioFile.onError.subscribe(error => console.log('Error: ', error));
}, 1000);
})
.catch(err => console.log('ready error: ', err));
}
record() {
// When record button clicked
this.audioFile.startRecord();
}
stop() {
// When stop button clicked
this.audioFile.stopRecord();
this.audioFile.play();
}
When I clicked Record btn, record() was executed and output was: Error: 1 and when I stopped recording than the output was status: 4 and Action is successful
I expected to either play the recording or get audiofile.mp3 in the file manager of my android device but I didn't observed any of it. Can someone help me with this issue?
What I tried:
I thought that its extension issue so I tried replacing mp3 with 3gp and m4a
I tried removing file:// from file.externalRootDirectory with slice method - file.externalRootDirectory.slice(7)
Instead of externalRootDirectory I also tried applicationDirectory and externalDataDirectory
I also submitted my issue on their github repository but I didn't got any response yet
I tried finding solutions on other communities and stackoverflow itself but problem still exists
Android 10 uses a new file system therefore plugins that have not updated themselves might not read/create files on Android 10.
You need to manually add this line in your manifest file : android:requestLegacyExternalStorage="true"
Open your project in Android Studio and open the AndroidManifest file.
In tag inside your manifest file, add android:requestLegacyExternalStorage="true"
Rebuild your project
Hi everyone I am migrating an app from ionic 1 to ionic 5 and I need to integrate the pushwoosh notification service, my project was started not using cordova, instead I use capacitor and I can't find information about how to integrate this service to an ionic 5 application.
Please, we already know that you can use cordova but when using the cordova plugin add pushwoosh-cordova-plugin#8.0.0 it gives you the following message:
Current working directory is not a Cordova-based project.
because as I said before it is a capacitor project not a cordovan project, Btw I already use ionic integrations enable cordova
So... if anyone can help us, It would be very helpful.
OK guys after many hours trying to integrate Pushwoosh into an ionic 5 application for me it was impossible,
If you set everything up correctly, the following will happen:
Your app will connect to Pushwoosh correctly
Your app will correctly register your device in pushwoosh
But your app will not listen to the listeners offered by the official Pushwoosh documentation
document.addEventListener('push-receive',
function (event) {
var message = (<any>event).notification.message;
var userData = (<any>event).notification.userdata;
alert("Push message received: " + message);
console.info(JSON.stringify((<any>event).notification));
//dump custom data to the console if it exists
if (typeof (userData) != "undefined") {
console.warn('user data: ' + JSON.stringify(userData));
}
}
);
This does not work in an ionic 5 app 👆🏽
This does work:
import { Component, OnInit } from '#angular/core';
import {
Plugins,
PushNotification,
PushNotificationToken,
PushNotificationActionPerformed,
} from '#capacitor/core';
const { PushNotifications } = Plugins;
#Component({
selector: 'app-home',
templateUrl: 'home.page.html',
styleUrls: ['home.page.scss'],
})
export class HomePage implements OnInit {
ngOnInit() {
console.log('Initializing HomePage');
// Request permission to use push notifications
// iOS will prompt user and return if they granted permission or not
// Android will just grant without prompting
PushNotifications.requestPermission().then(result => {
if (result.granted) {
// Register with Apple / Google to receive push via APNS/FCM
PushNotifications.register();
} else {
// Show some error
}
});
PushNotifications.addListener(
'registration',
(token: PushNotificationToken) => {
alert('Push registration success, token: ' + token.value);
},
);
PushNotifications.addListener('registrationError', (error: any) => {
alert('Error on registration: ' + JSON.stringify(error));
});
PushNotifications.addListener(
'pushNotificationReceived',
(notification: PushNotification) => {
alert('Push received: ' + JSON.stringify(notification));
},
);
PushNotifications.addListener(
'pushNotificationActionPerformed',
(notification: PushNotificationActionPerformed) => {
alert('Push action performed: ' + JSON.stringify(notification));
},
);
}
}
I tried to combine Pushwoosh with the capacitor but the tokens of the devices that are generated are different so I still didn't get my notifications.
At the end of the day and after many hours and days of work I have no other option than to use firebase and now everything is going much better.
I am developing a webrtc call/videocall app bases on Ionic/AngularJS technologies. The app works with sip.js for call actions over PBX server. For IOS integration with WebRtc, app works with cordova-plugin-iosrtc. When I try connect with PBX to call or received call, app throws errors on two possible use mode of cordova-plugin-iosrtc with sip.js
A) When I try to use cordova-plugin-iosrtc working on peer connection iOS plugin mode ....
telephoneService.js (Angular JS)
var pc = new cordova.plugins.iosrtc.RTCPeerConnection({
iceServers: []
});
cordova.plugins.iosrtc.getUserMedia(
// constraints
{ audio: true, video: true },
// success callback
function (stream) {
console.log('got local MediaStream: ', stream);
pc.addStream(stream);
},
// failure callback
function (error) {
console.error('getUserMedia failed: ', error);
}
);
var sessionDescriptionHandlerOptions = {
constraints: {
audio: audioId,
video: videoId
},
media: {
local: {
audio: document.getElementById('localAudio')
},
remote: {
audio: document.getElementById('remoteAudio')
}
},
extraHeaders: extraHeaders
}
}
userAgent.invite('sipusertocall', sessionDescriptionHandlerOptions);
receive the next error:
undefined is not a object evaluating 'environment.navigator.mediaDevices.getUserMedia' (sip.js lib)
B)
cordova.plugins.iosrtc.registerGlobals(); use iosrtc plugin with webrtc native api (navigator.mediaDevice.getUserMedia(), ....)
navigator.mediaDevices.getUserMedia(
function (stream) {
console.log('got local MediaStream: ', stream);
window.stream = stream;
},
// failure callback
function (error) {
console.error('getUserMedia failed: ', error);
}
)
var sessionDescriptionHandlerOptions = {
constraints: {
audio: audioId,
video: videoId
},
media: {
local: {
audio: document.getElementById('localAudio')
},
remote: {
audio: document.getElementById('remoteAudio')
}
},
extraHeaders: extraHeaders
}
userAgent.invite('sipusertocall', sessionDescriptionHandlerOptions);
App receive from sip.js next error from PBX: Failed:WebRTC Error
Client show next error at same time:
setLocalDescription() must be called with a RTCSessionDescription instance as first argument
So the newer SIP.js is actually passing in an instance of RTCSessionDescriptionInit which although has a similar structure: { sdp: ..., type: ... } to an RTCSessionDescription init is not accepted by the cordova iosrtc implementation.
I have created a fix for this in the form of a custom SDH for SIP.js (as I encountered the exact same issue). My custom SDH converts the object to a new RTCSessionDescription(...) just before it gets passed in to getLocationDescription and setRemoteDescription.
Link to SDH plugin:
https://github.com/iotum/cordova-ios-session-description-handler
Hope this helps!
Wes
I have added Ionic Secure Storage plugin (to store authentication tokens) into my Ionic project, and it works properly locally when running cordova run browser (so that cordova is loaded as a plaform).
However, when I open my project in Ionic DevApp and Ionic View on Android (works correctly on iOS), it fails silently whenever I try to retrieve the saved token.
Here is my code:
// ... unrelated imports omitted
import {Platform} from "ionic-angular";
import {SecureStorage, SecureStorageObject} from "#ionic-native/secure-storage";
#Component({
selector: 'my-component',
templateUrl: 'my-component.html'
})
export class MyComponent {
constructor(private platform: Platform,
private secureStorage: SecureStorage) {
}
ngOnInit() {
this.getToken().then(token => {
// ... do something with the retrieved token
});
}
getToken() {
if (this.platform.is('cordova')) {
/**
* Code below silently fails in Ionic View and Ionic Dev App
* on Android (works correctly on iOS)
*/
return this.platform.ready().then(() =>
return this.secureStorage.create('cp_secure_storage')
.then((storage: SecureStorageObject) => {
return storage.get('TOKEN_NAME')
.then(token => {
console.log(token);
return token;
}, () => null);
});
});
} else {
return Promise.resolve(localStorage.getItem('TOKEN_NAME'));
}
}
}
I have Ionic error monitoring turned on and it catches no errors.
Plugin version:
"#ionic-native/secure-storage": "4.5.3",
"cordova-plugin-secure-storage": "^2.6.8"