Closed gelodeesy closed 4 years ago
it happins to me as well on ioinic 4
Any workarounds available?
This is the work around i came up with.
In scanner page
ionViewCanLeave() {
let canGoBack = this.canGoBackService.getValue();
this.canGoBackService.setValue(true);
return canGoBack;
}
And in cancellation of scan block i wrote
if(barcodeData.cancelled) {
if(this.platform.is('android'))
this.canGoBackService.setValue(false);
}
Dedicated service to maintain the boolean.
import { Injectable } from '@angular/core';
@Injectable()
export class CanGoBackService {
private canGoBack = true;
constructor() {}
public setValue(value: boolean) {
this.canGoBack = value;
}
public getValue(): boolean {
return this.canGoBack;
}
}
And before all the transition from scan page i had manually set boolean to true.
this.canGoBackService.setValue(true);
this.nav.push(MyPage)
This worked fine for me. Still trying to find out better way.
Any workarounds for non-Ionic scenarios?
this what i did,
create
private preventBack: any;
then in scanner page put this code
ionViewDidEnter() { if (this.preventBack) { this.preventBack(); } this.preventBack = this.platform.registerBackButtonAction(null); }
ionViewWillLeave() { if (this.preventBack) { this.preventBack(); this.preventBack = null; } }
got it from : http://www.damirscorner.com/blog/posts/20170929-HandlingHardwareBackButtonInIonic.html
hope this helps
If someone is still facing this (with android 9 and barcode scanner) I managed to by pass it by registering a "backbutton" event listener when a cancel is received, and release the event listener after a second. My handler for the "backbutton" dosen't do anything, it just returns false, so the navigation doesn't happens. This listener is working on android only, which is good for this problem.
So just call the following "blockBack" function, when getting a "cancel" from the barcode plugin.
function blockBack(){
// stop back button (for 1 s) // used by barcode camera (when canceling and returnin back) // was sending the back event to the router, and left the screen
document.addEventListener("backbutton", onBackKeyDown, false);
setTimeout(function(){ document.removeEventListener("backbutton", onBackKeyDown, false) }, 1000)
function onBackKeyDown() { // swallow the back button - do nothing return false; } }
Awesome, I actually just trapped the back button and made it into my "home" button! Thanks for the tip!
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
not fixed
any fix ?
My solution:
Globally in the page load:
var backButtonOff = false;
document.addEventListener('deviceready', function () {
document.addEventListener('backbutton', function () {
if (!backButtonOff) {
window.history.back();
}
}, false);
}, false);
When the barcode scanner is triggered:
backButtonOff = true;
cordova.plugins.barcodeScanner.scan(function (result) {
setTimeout(function(){
backButtonOff = false;
}, 1000);
// processing the cancel event or the captured barcode here...
});
Is there any fix/solution for this?
My solution for this issue:
In the root page:
scanCode(anyValue): void {
this.navCtrl.push(BarcodeEscannerPage, {
object: anyValue,
callback: this.handleChildPage
});
}
handleChildPage(text: string, object: any): void {
if (text.length == 0)
return;
}
I created a Page for handle the Scanner (BarcodeScannerPage):
private callback: Function;
private object : any;
constructor(public navCtrl: NavController, public navParams: NavParams, private barcodeScanner: BarcodeScanner) {
this.object = navParams.get('object');
this.callback = navParams.get('callback');
}
ionViewDidLoad() {
this.initScan();
}
initScan(){
this.barcodeScanner
.scan({ prompt: 'Coloque el código a leer en el área permitida' })
.then(barcodeData => {
if(barcodeData.cancelled){
return this.returnData('', this.object);
}
this.returnData(barcodeData.text, this.object);
})
.catch(err => {
console.error("Error", err);
});
}
returnData(text: string, object :any): void {
this.callback(text, object);
this.navCtrl.pop();
}
I hope that it helps.
None of the suggestions work for me. =(
Has anyone solved this?
Is this a problem only on Android Oreo? If so is it a problem with Ionic/Cordova handling the back button properly rather than just with this plugin?
On Ionic 4 with Angular and Android 10 you can use this in ScanPage:
export class ScanPage implements OnInit {
canGoBack: boolean = true;
constructor() {}
onClickScan() {
this.canGoBack = false;
this.barcodeScanner.scan()
.then(barcodeData => {
console.log('Barcode data', barcodeData);
this.canGoBack = true;
}).catch(err => {
this.canGoBack = true;
console.log('Error', err);
});
}
ngOnChanges() {
return this.canGoBack;
}
}
I've tried to override the device's back button from the Ionic way:
`` this.platform.backButton.subscribe(() => { code here } or JS way:
document.addEventListener('backbutton', () => { ```
neither of these were able to stop the app from navigating twice ..
btw @DenHerrRing the ionViewCanLeave() lifecycle hook has been removed since Ionic 4 , so it's not a viable solution.
Please fix this , it's very annoying.
Is this a problem only on Android Oreo? If so is it a problem with Ionic/Cordova handling the back button properly rather than just with this plugin?
yes, only android Oreo
I had this problem using Angular/typescpript with Ionic 4 and deploying to Android. While i was testing the barcode i noticed that if i call the barcode (which would open the camera) inside a modal, pressing the hardware backbutton would cause the barcode camera screen AND the modal to close, imagine that. I could not found a way to fix it, i had to use a workaround. I have no idea if it was a problem with ionic/angular/typescript, but my guess is that the barcode screen captures the hardware backbutton event AND propagates (or does not consume it, i dont know) to the ionic app, forcing the modal to close. My workaround is simple, i want to scan an ean13 code, so i created a modal, with no HTML or CSS but the needed to make it completely transparent. Inside the modal i call the barcode scanner, obtain the data and call the dismiss on the modal controller sending the code scanned from the barcode. Doing this, i can use the onDidDismiss event of the modal that "wraps" the barcode scanner to obtain the code, when it dismiss, but, when the barcode is closed via the hardware backbutton it closes the empty transparent wrapper modal, maintaining the behavior of the app. I hope this helps in anyway possible.
Solution:
Create a service that import bar scanner
Import service on app.modules.ts Providers
On back button method subscriber add this "if"
Be happy =D
I'm trying to override backbutton behavior, but I can't make it work.. Any suggestions?
this.platform.backButton.subscribe((event: Event) => {
console.log(event);
});
with that code I can see the event on my logs when pressing the backbutton, but the app is still navigating back twice.
Please help
@imarquezc , you creating the subscriber in app.components.ts, or in another page ?
@willderazevedo I was creating it in another page. Finally I was able to fix this using @instyo 's solution. Thanks for the replay anyways!
Workaround for Ionic 5
import { BarcodeScannerOptions, BarcodeScanner } from '@ionic-native/barcode-scanner/ngx';
import { Subscription } from 'rxjs';
private preventBack: Subscription;
scan() {
this.preventBack = this.platform.backButton.subscribeWithPriority(9999, () => {});
this.barcodeScanner.scan(this.barcodeScannerOptions).then((barcodeData) => {
console.log(barcodeData);
if (barcodeData.cancelled) {
return;
}
// process result here
}, (err) => {
console.error(err);
}).finally(() => {
window.setTimeout(() => {
this.preventBack.unsubscribe();
}, 1000);
});
}
Have the same issue and @pbakondy workaround suit me the best!
Below solution is work for me for ionic 5.2.3 👍
Check Barcode cancelled action and add flag in localstorage. Check below code
this.barcodeScanner.scan().then((result) => {
if (result.cancelled) {
this.storeData();
}
});
async storeData(){
await localStorage.setItem('scanCancelled', 'true');
}
Write code in app.component.ts file :
async handleBackPress()
{
this.backBtnPress = this.platform.backButton.subscribeWithPriority(100, () =>
{
let flag = localStorage.getItem('scanCancelled');
if (flag === 'true') {
localStorage.setItem('scanCancelled', 'false');
return;
} else {
if (this.router.url === '/events') {
if (this.backPress) {
navigator['app'].exitApp();
} else {
this.commonTask.translateToastMsg('Press back again to exit App', 'info');
this.backPress = true;
setTimeout(function () {
this.backPress = false;
}, 1000);
}
} else {
this.nav.pop();
}
}
});
}
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
This thread has been automatically locked.
Expected Behaviour
When barcodescanner is cancelled, the display should go back to the previous page and close the scanner
Actual Behaviour
When user taps back on Android Oreo, the app goes two pages back and not on the previous page
Reproduce Scenario (including but not limited to)
Only happens on Android Oreo
Steps to Reproduce
Platform and Version (eg. Android 5.0 or iOS 9.2.1)
Android 8.0
(Android) What device vendor (e.g. Samsung, HTC, Sony...)
Samsung Galaxy S8
Cordova CLI version and cordova platform version
android 6.3.0
Plugin version
Sample Code that illustrates the problem
this.barcodeScanner.scan({orientation : "portrait"}).then((imageData) => { if (!imageData.cancelled) { this.processImageData(imageData); } else { this.toastCtrl.create({ message: 'Cancelling scan...', duration: 2000 }).present(); this.disable = false; return; } });
Logs taken while reproducing problem