var application = require("application");
application.on(application.uncaughtErrorEvent, function (args) {
if (args.android) {
// For Android applications, args.android is an NativeScriptError.
console.log("NativeScriptError: " + args.android);
} else if (args.ios) {
// For iOS applications, args.ios is NativeScriptError.
console.log("NativeScriptError: " + args.ios);
}
});
I tried above example in {N}#2.0.1 but it does not work for me.
Can you explain more detail?
Answered in NativeScript github repository enter link description here as follows:
application.uncaughtErrorEvent will trigger whenever your app is crashing and the cause is not handled.
For example:
if you try to initialize an android button with null context like this in your main-page.js it will throw an error
in main-page.js
var btn = new android.widget.Button(null);
What you can do to catch this error is to use uncaughtErrorEvent
in app.js
"use strict";
var application = require("application");
application.on(application.uncaughtErrorEvent, function (args) {
if (args.android) {
// For Android applications, args.android is an NativeScriptError.
console.log(" *** NativeScriptError *** : " + args.android);
console.log(" *** StackTrace *** : " + args.android.stackTrace);
console.log(" *** nativeException *** : " + args.android.nativeException);
}
else if (args.ios) {
// For iOS applications, args.ios is NativeScriptError.
console.log("NativeScriptError: " + args.ios);
}
});
application.start({ moduleName: "main-page" });
From the log you can see the following information:
NativeScriptError : Error: The application crashed because of an uncaught exception.
from the stackTrace you can see the cause of this error :
Attempt to invoke virtual method 'android.content.res.Resources
android.content.Context.getResources()' on null reference object
You also have a pointer where the error has occured:
Frame: function:'navigatingTo', `file:'/data/data/org.nativescript.cameraUpload/files/app/main-page.js',
line: 11, column: 15`
Related
I'm trying to access the image from whats app on sharing the image content. so i have already written code for chooser intent in android manifest. now to handle the incoming image i wrote code like below
application.android.on(application.AndroidApplication.activityStartedEvent, function (args) {
console.log("Event: " + args.eventName + ", Activity: " + args.activity);
// Event: activityStarted, Activity: com.tns.NativeScriptActivity#8a3b9cc
let intent = args.activity.getIntent();
let action = intent.getAction();
let type = intent.getType();
console.log(intent);
//Intent { act=android.intent.action.SEND typ=image/* flg=0x1b080001 cmp=org.myapp.new_app/com.tns.NativeScriptActivity clip={image/* U:content://com.whatsapp.fileprovider/external/WhatsApp/.Shared/photo.jpg} (has extras) }
console.log(action);
//android.intent.action.SEND
console.log(type);
// image/*
let imageUri = intent.getParcelableExtra(intent.EXTRA_STREAM);
console.log(imageUri);
//null
}
I expect the output not to be null
The log already shows you what exactly you have to read from intent (clip).
intent.getClipData().getItemAt(0).getUri()
I have following piece of code created in Android Studio:
public void onClick(View v) {
final TelephonyManager telephony = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
if (telephony.getPhoneType() == TelephonyManager.PHONE_TYPE_GSM) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
final GsmCellLocation location = (GsmCellLocation) telephony.getCellLocation();
if (location != null) {
Toast.makeText(MainActivity.this,"LAC: " + location.getLac() + " CID: " + location.getCid(),Toast.LENGTH_LONG).show();
}
}
}
If NativeScript have 100% access do Android API how reach same result in .ts NativeScript?
Please refer the docs on Java to JS to understand how the native api calls are marshalled into JS / TS.
You will be able to get the current activity from application module with application.android.foregroundActivity. So the code below should return instance of telephony manager.
const telephony = application.android.foregroundActivity.getSystemService(android.content.Context.TELEPHONY_SERVICE)
Use nativescript-permissions plugin to acquire permissions or to know whether your app already has the required permissions on device.
There is also nativescript-toast plugin that implements cross platform toast messages.
Thanks Manoj for useful help.
So steps that needed to be taken are:
Install:
npm install tns-platform-declarations --save-dev
Add two lines into references.d.ts, in my case it was in file ProjectName\references.d.ts
/// <reference path="node_modules/tns-platform-declarations/android.d.ts" />
/// <reference path="node_modules/tns-platform-declarations/ios.d.ts" />
Install nativescript-permissions plugin: tns plugin add nativescript-permissions
Install nativescript-toast plugin $ tns plugin add nativescript-toast
Import libraries on the begining of file
var application = require("application");
const permissions = require( "nativescript-permissions" );
import * as Toast from 'nativescript-toast';
And write code to get LAC, CID, MCC, MNC
buttonGetInfoTap(args) {
const telephonyService = application.android.foregroundActivity.getSystemService(android.content.Context.TELEPHONY_SERVICE);
permissions.requestPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION, "I need these permissions because I'm cool")
.then( () => {
if (telephonyService.getPhoneType() == android.telephony.TelephonyManager.PHONE_TYPE_GSM) {
let location = <android.telephony.gsm.GsmCellLocation>telephonyService.getCellLocation();
if (location != null) {
console.log("LAC: " + location.getLac() + " CID: " + location.getCid())
Toast.makeText("LAC: " + location.getLac() + " CID: " + location.getCid(), "long").show();
const networkOperator = telephonyService.getNetworkOperator();
const MCC =networkOperator.substring(0,3)
const MNC =networkOperator.substring(3)
Toast.makeText("MCC:"+MCC+"MNC:"+MNC, "long").show();
}
}
})
.catch( () => {
Toast.makeText("No permission", "long").show();
});
}
Looking at this code, I'm wondering what triggers onNotificationGCM? It is triggered when the app is registered but when does it get triggered again, say, when when I want to push a message to the user? I have a chat app that I'd like to push a message when chats come in. So I understand that I register the device but then this code needs to run again, I assume, with the new event. I just need understand part flow and part code.
// handle GCM notifications for Android
$window.onNotificationGCM = function (event) {
switch (event.event) {
case 'registered':
if (event.regid.length > 0) {
// Your GCM push server needs to know the regID before it can push to this device
// here is where you might want to send it the regID for later use.
var device_token = event.regid;
RequestsService.register(device_token).then(function(response){
alert('registered!');
});
//send device reg id to server
}
break;
case 'message':
// if this flag is set, this notification happened while we were in the foreground.
// you might want to play a sound to get the user's attention, throw up a dialog, etc.
if (event.foreground) {
console.log('INLINE NOTIFICATION');
var my_media = new Media("/android_asset/www/" + event.soundname);
my_media.play();
} else {
if (event.coldstart) {
console.log('COLDSTART NOTIFICATION');
} else {
console.log('BACKGROUND NOTIFICATION');
}
}
navigator.notification.alert(event.payload.message);
console.log('MESSAGE -> MSG: ' + event.payload.message);
//Only works for GCM
console.log('MESSAGE -> MSGCNT: ' + event.payload.msgcnt);
//Only works on Amazon Fire OS
console.log('MESSAGE -> TIME: ' + event.payload.timeStamp);
break;
case 'error':
console.log('ERROR -> MSG:' + event.msg);
break;
default:
console.log('EVENT -> Unknown, an event was received and we do not know what it is');
break;
}
};
Have a look at this example:
case 'message':
/*
if (e.foreground) {
window.alert("Message recieved");
}
else {
if (e.coldstart) {
window.alert("Coldstart Notification");
} else {
window.alert("Background Notification");
}
}
window.alert("Notification message: " + e.payload.message
+ "\n\n Time: " + e.payload.conversation);
*/
var data = e.payload;
if (data.conversation){
window.history.replaceState(null, '', '#/chats/');
ProjectName.conversation.load(data.conversation);
}
if (data.product){
window.history.replaceState(null, '', '#/product/' + data.product);
}
break;
case 'error':
// window.alert("Notification error: " + e.msg);
break;
default:
// window.alert("Notification - Unknown event");
break;
}
The e.payload contains all data that you send to your application, including message. You can access your other variables in case 'message'
I have a function that works perfect within a Qt application, but when called from a console application it fails. The function needs to verify an image file exists and can be read to a usable format:
void VerifyImageFormat(const QString& ImageFile)
{
if (ImageFile.isEmpty())
{
return;
}
QFile file(ImageFile);
if(!file.exists())
{
QString Error("Failed to open image file ");
Error += ImageFile;
throw Error.toStdString();
}
if(QImage(ImageFile).format() == QImage::Format_Invalid)
{
QString Error(ImageFile);
Error += " is of invalid image format.";
throw Error.toStdString();
}
}
I really need this functionality in my console application - what do I do?
I have read NsIContentPolicy and have searched whole Stackoverflow for a proper tutorial for implementing NsIContentPolicy, but all in vain. I know that Adblock uses NsIContentPolicy as their main weapon. Reverse engineering Adblock didn't help me to understand how to implement NsIContentPolicy. Is there any simple addon using NsIContentPolicy for learning, or any good tutorial on NsIContentPolicy?
I am not aware of any good tutorial but I can give you some minimal example code:
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
let policy =
{
classDescription: "Test content policy",
classID: Components.ID("{12345678-1234-1234-1234-123456789abc}"),
contractID: "#adblockplus.org/test-policy;1",
xpcom_categories: ["content-policy"],
init: function()
{
let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
registrar.registerFactory(this.classID, this.classDescription, this.contractID, this);
let catMan = Cc["#mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager);
for each (let category in this.xpcom_categories)
catMan.addCategoryEntry(category, this.contractID, this.contractID, false, true);
onShutdown.add((function()
{
for each (let category in this.xpcom_categories)
catMan.deleteCategoryEntry(category, this.contractID, false);
// This needs to run asynchronously, see bug 753687
Services.tm.currentThread.dispatch(function()
{
registrar.unregisterFactory(this.classID, this);
}.bind(this), Ci.nsIEventTarget.DISPATCH_NORMAL);
}).bind(this));
},
// nsIContentPolicy interface implementation
shouldLoad: function(contentType, contentLocation, requestOrigin, node, mimeTypeGuess, extra)
{
dump("shouldLoad: " + contentType + " " +
(contentLocation ? contentLocation.spec : "null") + " " +
(requestOrigin ? requestOrigin.spec : "null") + " " +
node + " " +
mimeTypeGuess + "\n");
return Ci.nsIContentPolicy.ACCEPT;
},
shouldProcess: function(contentType, contentLocation, requestOrigin, node, mimeTypeGuess, extra)
{
dump("shouldProcess: " + contentType + " " +
(contentLocation ? contentLocation.spec : "null") + " " +
(requestOrigin ? requestOrigin.spec : "null") + " " +
node + " " +
mimeTypeGuess + "\n");
return Ci.nsIContentPolicy.ACCEPT;
},
// nsIFactory interface implementation
createInstance: function(outer, iid)
{
if (outer)
throw Cr.NS_ERROR_NO_AGGREGATION;
return this.QueryInterface(iid);
},
// nsISupports interface implementation
QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPolicy, Ci.nsIFactory])
};
policy.init();
This comes from the minimal content policy implementation I use to look at issues with the content policies implementation - it doesn't do anything other than dumping all content policies calls to the console (window.dump documentation). Obviously, in a real implementation the fields classDescription , classID and contractID should be changed to something proper. onShutdown belongs to the private framework I am using: this extension is restartless which is why it needs to register the component "manually" and will also run this code to remove it if it is shut down during a browser session.
You can also download the complete extension: testpolicy.xpi.