Backbutton on ZXing Scanner doesn´t works (Xamarin Forms) - android

im trying to implement a Barcode Scanner on my project in Xamarin Forms. When i press the back button on the scanning page my app crash. I am getting the following error: System.NullReferenceException: 'Object reference not set to an instance of an object.'
This is my code:
ScanService.cs
public interface ScanningService
{
Task<string> ScanAsync();
}
My code behind:
var scanner = DependencyService.Get<ScanningService>();
var result = await scanner.ScanAsync();
if (result != null){.....}
QRscanningService (On Android):
class QrScanningService : ScanningService
{
public async Task<string> ScanAsync()
{
var optionsCustom = new MobileBarcodeScanningOptions();
var scanner = new MobileBarcodeScanner()
{
TopText = "Acerca la cámara",
BottomText = "Toca la pantalla para enfocar",
};
var scanResult = await scanner.Scan(optionsCustom);
return scanResult.Text;
}
}
Any contribution will be apreciated.

I believe the error occurs inside QRscanningService (On Android).
It is because you're trying to use "Text" from scanResult and scanResult is null
To avoid this, change the last line to something like this:
return scanResult == null ? null: scanResult.Text;

I solved it with the following code on my code behind:
var overlay = new ZXingDefaultOverlay
{
ShowFlashButton = true,
TopText = "Toca la pantalla para enfocar",
BottomText = string.Empty
};
overlay.BindingContext = overlay;
scanPage = new ZXingScannerPage(null, overlay);
overlay.FlashButtonClicked += (s, ed) =>
{
scanPage.ToggleTorch();
};
scanPage.OnScanResult += (result) =>
{
scanPage.IsScanning = false;
Device.BeginInvokeOnMainThread(() =>
{
_ = Navigation.PopModalAsync();
try
{
TxtidR.Text = result.Text;
}
catch (Exception)
{
throw;
}
});
};
await Navigation.PushModalAsync(scanPage);
var scanner = DependencyService.Get<ScanningService>();
}
I hope it works for you!

Related

data displayed on my google sheet turned to undefined

I'm trying to make an android app that use google sheet as my database. But when i input the data to google sheet it turns to 'undefined'. hope someone can help me to fix this
code that contains 'undefined'
function read_all_value(request){
var ss =SpreadsheetApp.openById(SCRIPT_PROP.getProperty("key"));
var output = ContentService.createTextOutput(),
data = {};
//Note : here sheet is sheet name , don't get confuse with other operation
var sheet="sheet1";
data.records = readData_(ss, sheet);
var callback = request.parameters.callback;
if (callback === undefined) {
output.setContent(JSON.stringify(data));
} else {
output.setContent(callback + "(" + JSON.stringify(data) + ")");
}
output.setMimeType(ContentService.MimeType.JAVASCRIPT);
return output;
}
this code too
function readData_(ss, sheetname, properties) {
if (typeof properties == "undefined") {
properties = getHeaderRow_(ss, sheetname);
properties = properties.map(function(p) { return p.replace(/\s+/g, '_'); });
}
var rows = getDataRows_(ss, sheetname),
data = [];
for (var r = 0, l = rows.length; r < l; r++) {
var row = rows[r],
record = {};
for (var p in properties) {
record[properties[p]] = row[p];
}
data.push(record);
}
return data;
}
function getDataRows_(ss, sheetname) {
var sh = ss.getSheetByName(sheetname);
return sh.getRange(2, 1, sh.getLastRow() - 1, sh.getLastColumn()).getValues();
}
function getHeaderRow_(ss, sheetname) {
var sh = ss.getSheetByName(sheetname);
return sh.getRange(1, 1, 1, sh.getLastColumn()).getValues()[0];
}
here is my google sheet
https://docs.google.com/spreadsheets/d/1qX61V-xw3IjK8L373iTqlaSN0cf3-eh3zrpDBYHr8JQ/edit?usp=sharing
Change readData_() function code below -
for (var p in properties) {
record[properties[p]] = row[p];
}
to this -
properties.forEach(function(key, i) {
record[key] = row[i];
});

OAuth2 and UWP Xamarin.Forms

Can any one help me with this problem?
I don`t know how to use OAuth2 with UWP.
For example, on Andriod code of authentication looks like this:
[assembly: ExportRenderer(typeof(LoginPage), typeof(LoginPageRenderer))]
namespace TestTask.Droid
{
class LoginPageRenderer : PageRenderer
{
private static bool _isShown;
protected override void OnElementChanged(ElementChangedEventArgs<Page> e)
{
base.OnElementChanged(e);
if (_isShown) return;
_isShown = true;
var activity = this.Context as Activity;
var auth = new OAuth2Authenticator(
clientId: "someId",
scope: "",
authorizeUrl: new Uri("https://oauth.vk.com/authorize"),
redirectUrl: new Uri("https://oauth.vk.com/blank.html"));
auth.Completed += (sender, eventArgs) => {
if (eventArgs.IsAuthenticated)
{
AuthInfo.Token = eventArgs.Account.Properties["access_token"].ToString();
AuthInfo.UserID = eventArgs.Account.Properties["user_id"].ToString();
}
else
{
// The user cancelled
}
};
activity?.StartActivity((Intent)auth.GetUI(activity));
}
}
}
so, on android the solution is in this method
protected override void OnElementChanged(ElementChangedEventArgs<Page> e)
and in this row fo code
activity?.StartActivity((Intent)auth.GetUI(activity));
My question is: How I can do the same in UWP, or how I can make it work in UWP?
Thank you all! I`ve found a solution for my purpose for UWP platform.
[assembly: ExportRenderer(typeof(LoginPage), typeof(LoginPageRenderer))]
namespace TestTask.UWP
{
public class LoginPageRenderer : PageRenderer
{
private Windows.UI.Xaml.Controls.Frame _frame;
private bool _isShown;
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Page> e)
{
base.OnElementChanged(e);
if (_isShown) return;
_isShown = true;
if (Control == null)
{
WindowsPage windowsPage = new WindowsPage();
var auth = new OAuth2Authenticator(
clientId: "someID",
scope: "",
authorizeUrl: new Uri("https://oauth.vk.com/authorize"),
redirectUrl: new Uri("https://oauth.vk.com/blank.html"));
_frame = windowsPage.Frame;
if (_frame == null)
{
_frame = new Frame();
//_frame.Language = global::Windows.Globalization.ApplicationLanguages.Languages[0];
windowsPage.Content = _frame;
SetNativeControl(windowsPage);
}
auth.Completed += (sender, eventArgs) => {
if (eventArgs.IsAuthenticated)
{
AuthInfo.Token = eventArgs.Account.Properties["access_token"].ToString();
AuthInfo.UserID = eventArgs.Account.Properties["user_id"].ToString();
}
else
{
// The user cancelled
}
};
Type pageType = auth.GetUI();
_frame.Navigate(pageType, auth);
Window.Current.Activate();
}
}
}
}
Please mark it solved!
My question is: How I can do the same in UWP, or how I can make it work in UWP?
I'm not sure whether the Xamarin.Auth supports UWP or not, but for UWP, we can use Web authentication broker for OAuth, you can check the official WebAuthenticationBroker sample, it's not xamarin, but you can code it in native UWP project and use Custom renderer to do the same thing in Xamarin.
Xamarin.Auth supports UWP for Standard/Traditional quite long.
Xamarin.Forms support was recently added and is not tested thoroughly (1.5.0-alpha)

Lokijs DB data removed after rerun using ionic run command?

I am working on a ionic project and trying to use LokiJS. Below is my code,
controller,
$scope.test ={birthdays:[]};
$ionicPlatform.ready(function() {
BirthdayService.initDB();
BirthdayService.getAllBirthdays().then(function(birthdays){
console.log("birthdays=",birthdays);// gives empty array second run...
//var bday1 = {Name:"abrj",Date:new Date()};
//var bday2 = {Name:"abrj2",Date:new Date()};
//BirthdayService.addBirthday(bday1);
//BirthdayService.addBirthday(bday2); added birthdays during the first run.
});
});
I am using cordova-fs-adapter and cordova-file-plugin.
below is my service for adapter integration,
(function() {
angular.module('starter').factory('BirthdayService', ['$q', 'Loki', BirthdayService]);
function BirthdayService($q, Loki) {
var _db;
var _birthdays;
function initDB() {
var fsAdapter = new LokiCordovaFSAdapter({"prefix": "loki"});
_db = new Loki('birthdaysDB',
{
autosave: true,
autosaveInterval: 1000, // 1 second
adapter: fsAdapter
});
};
function getAllBirthdays() {
return $q(function (resolve, reject) {
var options = {
birthdays: {
proto: Object,
inflate: function (src, dst) {
var prop;
for (prop in src) {
if (prop === 'Date') {
dst.Date = new Date(src.Date);
} else {
dst[prop] = src[prop];
}
}
}
}
};
_db.loadDatabase(options, function () {
_birthdays = _db.getCollection('birthdays');
if (!_birthdays) {
_birthdays = _db.addCollection('birthdays');
}
resolve(_birthdays.data);
});
});
};
function addBirthday(birthday) {
console.log("Birthdays=",_birthdays);
_birthdays.insert(birthday);
};
function updateBirthday(birthday) {
_birthdays.update(birthday);
};
function deleteBirthday(birthday) {
_birthdays.remove(birthday);
};
return {
initDB: initDB,
getAllBirthdays: getAllBirthdays,
addBirthday: addBirthday,
updateBirthday: updateBirthday,
deleteBirthday: deleteBirthday
};
}
})();
In first run I am inserting two documents into the birthdays collections.On second run when I trying to check whether they have persisted, they weren't. I know I am doing something wrong.Do suggest.Local storage also gets cleared everytime i rerun(ionic run android)?!

Sometimes $http status 0 but on django the status is 200

Firstly, sorry about my english; I am not a native speaker.
Secondly, I'm making an app for Android using the framework Ionic and I'm using Django as an REST API.
I have issues with a factory: the HTTP status from the request in Django is 200 and the database registers the change, but in the app the HTTP status is 0. This happens only in this factory that contains two POST requests. The other POST requests made on the other factories work fine.
To test the app I use Google Chrome (with the command --disable-web-security), Ionic version 1.5.0, Django version 1.8.2, Cordova version 5.0 (I couldn't find which version of AngularJS I'm using). I have the same issues on several mobile devices.
Here are 3 controllers that cause the problem:
.controller('PlanesCtrl', function($scope, $ionicModal, $ionicPopup,$location, Planes, $window) {
$scope.planes = JSON.parse($window.localStorage['planes']);
$scope.usuario = JSON.parse($window.localStorage['user']);
var usuario_id = {
codusuario: $scope.usuario["codusuario"]
};
$scope.mascotaEscogida = JSON.parse($window.localStorage['mascotaEscogida']);
var especie_id = {
codespecie: $scope.mascotaEscogida.codespecie
};
var mascota_id = {
codmascota: $scope.mascotaEscogida.id
};
var data = {
codespecie: $scope.mascotaEscogida.codespecie,
codmascota: $scope.mascotaEscogida.id
}
$scope.ver_plan = function(plan){
Planes.selectChosenPlan(plan.id);
if (plan.suscrito == 0){
$location.path("/app/planes/" + plan.id);
}
else{
$location.path("/app/entrenar/" + plan.id);
}
};
})
.controller('PlanCtrl', function($scope, $ionicModal,$location, $ionicPopup, $window, Planes) {
$scope.mascotaEscogida = JSON.parse($window.localStorage['mascotaEscogida']);
var mascota_id = {
codmascota: $scope.mascotaEscogida.codmascota
};
$scope.plan = JSON.parse($window.localStorage['planActual']);
var data = {
codplan: $scope.plan.id,
codespecie: $scope.mascotaEscogida.codespecie,
codmascota: $scope.mascotaEscogida.id
};
$scope.suscribir = function(){
var data = {
codplan: $scope.plan.id,
codespecie: $scope.mascotaEscogida.codespecie,
codmascota: $scope.mascotaEscogida.id
};
console.log($scope.plan.id);
console.log($scope.mascotaEscogida.codespecie);
console.log($scope.mascotaEscogida.id);
Planes.suscribir(data, function() {
alert("Su mascota ha sido suscrita al plan con éxito");
} , function() {
} , function() {
console.log("No funciona suscribir en funcion suscribir, PlanCtrl");
});
Planes.buscar(data, function() {
} , function() {
} , function() {
console.log("No funciona buscar en funcion suscribir, PlanCtrl");
});
$location.path("/app/pet/" + mascota_id);
$window.location.reload(true);
};
})
.controller('PetCtrl', function($scope, $stateParams, $filter, $location, Mascota, Planes, $window, $ionicModal) {
$scope.mascotaEscogida = JSON.parse($window.localStorage['mascotaEscogida']);
$scope.usuario_logged = JSON.parse($window.localStorage['user_data']);
$scope.usuario_info = JSON.parse($window.localStorage['user']);
var data = {
codespecie: $scope.mascotaEscogida.codespecie,
codmascota: $scope.mascotaEscogida.id
}
$scope.ver_entrenamientos = function(mascota){
Planes.buscar(data, function() {
alert("Planes encontrados con exito");
} , function() {
alert("La mascotas no posee especie registrada (esto es muy extraño)");
} , function() {
console.log("No funciona buscar en ver_entrenamientos, PetCtrl");
});
$location.path("/app/planes");
$window.location.reload(true);
};
if($scope.usuario_logged === false) {
$location.path('/login');
}
else {
$scope.test = function() {
fecha_hora = $filter('date')(new Date(), 'yyyy-MM-dd HH:mm:ss', '-0300');
var info = {
fecha: fecha_hora,
codmascota: $scope.mascotaEscogida.id,
codusuario: $scope.usuario_info.codusuario
}
Mascota.alimentar(info, function() {
alert("La mascota ha sido alimentada con exito :)");
} , function() {
alert("Lo sentimos, algo ha ocurrido y no podemos registrar la alimentación");
} , function() {
alert("Verifica la conexión a internet");
});
}
}
})
And here is the factory:
.factory("Planes", function($http, $window){
var url = "http://localhost:8000/plan/";
var currentPlanes = function(data){
$window.localStorage['planes'] = JSON.stringify(data);
};
return {
selectChosenPlan: function(id) {
var arregloPlanes = JSON.parse($window.localStorage['planes']);
for (var i = 0; i <= arregloPlanes.length - 1; i++) {
if (parseInt(arregloPlanes[i].id) == id) {
$window.localStorage['planActual'] = JSON.stringify(arregloPlanes[i]);
}
}
},
buscar: function(inf, successFunction, errorFunction, connectionError) {
$http({
method: 'POST',
url: url + 'planes/',
headers: {'Content-Type': 'application/json'},
data: JSON.stringify(inf),
timeout: 20000
}).then(function successCallback(response) {
if (response.data.length > 0) {
console.log("buscar" + response.data[0]);
currentPlanes(response.data);
successFunction();
}
else{
currentPlanes(response.data);
errorFunction();
}
}, function errorCallback(response) {
connectionError();
});
},
suscribir: function(inf, successFunction, errorFunction, connectionError) {
$http({
method: 'POST',
url: url + 'suscribir/',
headers: {'Content-Type': 'application/json'},
data: JSON.stringify(inf),
timeout: 20000
}).then(function successCallback(response) {
if (response.data.length > 0) {
console.log("suscribir" + response.data[0]);
currentPlanes(response.data);
successFunction();
}
else{
currentPlanes(response.data);
errorFunction();
}
}, function errorCallback(response) {
connectionError();
});
}
};
})
I've made some research in the internet, but all the solutions I've found point to the CORS. If that were the problem, the other factory wouldn't work either, so I don't think that's the problem. Some other answers say that the problem could be in the HTML, on the button that calls 'ver_plan' or 'ver_entrenamiento', but both are set with type="button", so the submit wasn't the problem either. The error happens randomly and I can't find the issue in the flow of events. Sometimes, I even get a 'broken pipe' message from Django, but this also happens randomly.
I know that the JSON answer is valid and has the correct format; I'm out of ideas and I need to solve these issues.
Edit: Also, the line console.log("No funciona buscar en funcion suscribir, PlanCtrl"); doesn't appear in the console when I get the problem.
I found the answer a couple of weeks ago. The problem was
$window.location.reload(true); and $location.path();
It is not necessary the line $window.location.reload(true); if $location.path(); is located inside the factory call. For example:
Planes.buscar(data, function() {
$location.path("/app/pet/" + mascota_id);
} , function() {
} , function() {
console.log("No funciona buscar en funcion suscribir, PlanCtrl");
});
This way, the redirection occurs only if the answer from the server was successful and there is no need to use $window.location.reload(true);
I wish I can give you more details about the reason of the problem but my english is not good enough.

How to create a OData List?

I want to create a OList, so that every position opened a new OList if I tap on it. At this moment I have following code:
function readCustomerSuccessCallback(data, response) {
var citems = [];
for (var i = 0; i < data.results.length; i++) {
var citem = new sap.m.StandardListItem(
{
type: "Active",
tap : readProducts(data.results[i].STATION_ID),
title: data.results[i].CUSTOMER_NAME,
description: data.results[i].STATION_ID
});
citems.push(citem);
}
var oList = new sap.m.List({
headerText : "Customers",
setGrowingScrollToLoad: true,
items : citems,
press: function(e) {
console.log(oList.getSelectedItems());
}
});
oList.placeAt("content"); // place model onto UI
}
function readProducts(category) {
console.log("read request started");
startTime = new Date();
if (!haveAppId()) {
return;
}
sURL = myUrl;
var oHeaders = {};
oHeaders['Authorization'] = authStr;
//oHeaders['X-SMP-APPCID'] = appCID; //this header is provided by the logon plugin
var request = {
headers : oHeaders,
requestUri : sURL,
method : "GET"
};
OData.read(request, readProductsSuccessCallback, errorCallback);
}
The function read CustomerSuccesCAllback creates a OList,and if I tap on a field of this list, I want that a new List shows up. For the second step is the function readproducts responsible.
With this code it doesnt work. It shows me not the customers, but only theyre details.
Has anybody an idea?
Change in readCustomerSuccessCallback:
tap: function(e){
readProducts(this.getDescription),
}
//this will stop invoking the function while defining your items

Categories

Resources