Access accelerometer via Javascript in Android? - javascript

Is there any way to access accelerometer data using Javascript on Android's browser? I know it supports "onorientationchange", but I'd like to get everything.
Clarification: I'm asking how to do this in a website, not a native app.

As of ICS, Android 4.0, you can use the 'devicemotion' event via a JavaScript event listener to access the accelerometer data. See the W3C documentation on how to access it - http://dev.w3.org/geo/api/spec-source-orientation.html.
Note - The W3C documentation title is named with 'device orientation', but the spec does indeed include 'devicemotion' event documentation.

Making an update to this thread.
HTML5 lets someone do this. Detecting whether or not an accelerometer is present is easy.
if (window.DeviceMotionEvent == undefined) {
//No accelerometer is present. Use buttons.
alert("no accelerometer");
}
else {
alert("accelerometer found");
window.addEventListener("devicemotion", accelerometerUpdate, true);
}
In the function that you define to receive the accelerometer events, you can look at the accelerationIncludingGravity member.
function accelerometerUpdate(e) {
var aX = event.accelerationIncludingGravity.x*1;
var aY = event.accelerationIncludingGravity.y*1;
var aZ = event.accelerationIncludingGravity.z*1;
//The following two lines are just to calculate a
// tilt. Not really needed.
xPosition = Math.atan2(aY, aZ);
yPosition = Math.atan2(aX, aZ);
}
More information can be found here: http://dev.w3.org/geo/api/spec-source-orientation.html

You could try with PhoneGap that provides API to access the accelerometer from javascript.
Here the documentation.

If you are trying to access the accelerometer from a webpage hosted on a server (verus one integrated into a native application through WebView), than the accelerometer data does not appear to be available as of now for Android. You can find a more detailed assessment here: http://www.mobilexweb.com/blog/android-froyo-html5-accelerometer-flash-player .
You might also want to check out this SO post: Detect rotation of Android phone in the browser with JavaScript

If I'm reading the docs correctly, you could set up a class (within Java/Android) that provides the accelerometer functionality you need in public functions.
Then setup a javascript interface for the webview using the addJavascriptInterface call, which makes the public functions in that class available to be called from within javascript.

Looking at this post flash.sensors.Accelerometer on Android within web browser it seems accelerometer data is available to flash. So a possible workaround (at least for devices which have flash) would be a small flash applet which grabbed the data for you.
Sounds like a hack, but still sounds better than making the whole thing in flash

Related

Where in metadata of a video in html5 is the fps saved?

In order to fully implement my custom html5 video player, I need the the exact frame rate of a video. However I have not been able to find it yet and am using a standard value of 25.
Typically videos have a frame rate value in meta-data so I accessed meta-data using something like this:
var vid = document.getElementById("myVideo");
vid.onloadedmetadata = function(e) {
console.log(e);
};
However I can't find frame rate here. Maybe I am not reading metadata at all.
I can use your help.
Thanks!
Try https://mediainfo.js.org (github)
It works on ui only, no backend needed
I just implemented it and it looks like it worked perfectly fine (at least in Chrome v 70.0.3538.77) for gettting wide media information
It looks like modern browsers beginning to work with some binary libraries
I'm 95% sure the standard html5 video api does not expose the fps information, from what I've read in the past months - other apis like MPEG-DASH and jwplayer do present more / different data.
Your best bet would be to snoop around w3schools.com/tags/ref_av_dom.asp and similar mdn pages.
You can calculate this in realtime yourself and it should work most of the time but I can imagine there's a case or two when it wouldn't. Look at PresentedFrames and then do something like:
fps = video.time / PresentedFrames
view more about PresentedFrames here (currently proposal) and similar attributes at the same link.
mediainfo.js works pretty good - even if used locally in a browser using 'http(s)://'.
To use it locally, just make sure you also download the accompanying mediainfo.wasm and put it into the same directory as mediainfo.min.js.
Alternatively you can install media-info using npm.
The only caveat is, that it doesn't run from the 'file://' protocol.

is there a difference between alert() vs notification.alert() using phonegap in xcode?

I'm trying to figure out how to fix the titles on my messages that pop up in my iOS app I am attempting to work on seeing as the messages tend to pop up with a long path of where the file is, then the message which is to a point counter productive for the needs of the popup. That said. I started searching for how to fix it and I came up with the notification.alert(). I am assuming that the standard alert() I am using is binded to that with the way cordova/phonegap works. But does this mean I should instead of alert('message') use notification.alert() if so. Then how can I fix the one that is auto generated by the app when I am looking for geolocation information?
As requested "What am I using for geolocation"
geocoder = new google.maps.Geocoder();
if(navigator.geolocation)
{
navigator.geolocation.getCurrentPosition(successFunction, errorFunction);
}
Which is what I do in my web based apps. I know this may not be the ideal solution for phonegap/cordova specifically. So I am searching for the right answer to this as well. But mostly the alerts. I am currently porting over an existing web based app to a phonegap version for iOS so the original question is should I remain using alert() where I do in my web based version or should I convert those as well to notification.alert() or does it really make that big a difference.
Like Noogen already mentioned, you should use notification.alert if you want it to look native and you want to customize the title etc.
For iOS 6 and above, to change the alert asking for permission to use current location, you can set the value for key NSLocationUsageDescription (or Privacy - Location Usage Description) in your app's Info.plist. The title of the alert will still be "YourAppBundleName" Would Like to Use Your Current Location. The value of the NSLocationUsageDescription will be shown as an explanation below the title.
There are similar properties for other permission dialogs as described in Apple's Information Property List Key Reference.
What Google geolocation code are you using that is doing the alert? API should not be doing any alert. The alert and notification.alert are two different functions.
Default alert webview/browser display the page URL in the title. Phonegap people did a great thing by providing the additional notification (alert, prompt, and confirm) API. This is a feature/benefit of PhoneGap. It is also required if you don't want to be rejected by Apple with app must be native look and feel clause. Just change all your alert to notification.alert.
You can also hack/override default alert with window.alert = notification.alert, but I do not recommend this.
Alternatively, you can do something like my AngularJS phonegap $notification friendly factory shown in my response here: Angularjs + phonegap logout on history back

Ideas needed. Javascript+XPCOM+C++ add-on

So, there is a WebRTC inside Firefox and there is a convenient class for making RTC communication possible called RTCPeerConnection which can be instantiated and used from the JavaScript app. You can find some decent example of it on [1].
And here am I with my custom transport (if you're interested - [2]) would like to use it for RTC communication. Briefly, I need to "substitute" the transport layer of WebRTC engine by my custom transport while providing the same RTCPeerConnection-like JavaScript interface for the user. And preferably, it should not look like custom build of Firefox (no patches).
So I've come up with the idea of extension, which will be written in C++ (since it need to be linked with WebRTC library and my custom transport library) and somehow will expose its interface to Javascript. And I've found XPCOM which, as I thought, can provide me this.
So I've started to fight with out-dated and sparsed info on this topic and after 3 days of struggling finally ended up with builded add-on. Unfortunately, I can't access it from Javascript, because of Javascript's "Components.classes is undefined" error. And it seems that there is no way to access it at all. Or I'm wrong on that?
Here is Javascript:
function check()
{
console.debug("checking...");
const {Cc,Ci,Cu} = require("chrome");
var rtc = Components.classes["#named-data.net/ndnrtc;1"].createInstance();
rtc = rtc.QueryInterface(Ci.ndINrtc);
console.debug("rtc: "+rtc);
}
My component is visible with XPCOM Viewer addon and the code above I can execute in the console while empty page is open in Firefox.
Given all that, I would like to ask Firefox experts regarding possible approaches which I can take in order to implement my idea.
Thank you in advance
1 https://apprtc.appspot.com/
2 http://named-data.net
Finally, I've figured out one possible solution for that and describe it in my post

Using the same codebase for phonegap and web?

Is it wise to use the same codebase for our mobile web app and phonegap app? They are meant to be similar, the phonegap version just lets us do more. Can we detect if it's not running on phonegap and sequester calls to the phonegap api or does it make more sense to separate them.
Sure, you can use most of the same codebase.
Some phonegap APIs are the same in html5 (for instance localStorage) so there's no difference in code there.
If you're using phonegap Build service, it will add the phonegap.js / cordova.js script file to your project root. Just include it in your html all the time. Then you can detect whether your application is running within phonegap:
var isPhonegap = function() {
return (typeof(cordova) !== 'undefined' || typeof(phonegap) !== 'undefined');
}
if (isPhonegap()) {
// phonegap.js/cordova.js exists.. now let's handle the onDeviceReady event
} else {
// in-browser
}
If you need some common startup code, put it in a function and call this function from the onDeviceReady handler and the else block above.
If the phonegap api you're calling doesn't have the exact same name as the html5 one (because it has the Moz* or WebKit* prefix for instance), just wrap both inside a new name. For instance:
var requestFileSystem = (isPhonegap() ? requestFileSystem : window.WebKitRequestFileSystem);
If the phonegap API you're using really has no html5 equivalent, try to duplicate the functionality yourself in javascript if possible, otherwise you'll just lose the functionality in your browser. But make sure it degrades gracefully enough without that feature.
Note: to test the mobile devices features like accelerometer, geolocation, etc.. in your browser checkout the Ripple Chrome extension.
I figured out a way to keep the web codebase intact...
The current problem with using the built in deviceready event, is that when the page is loaded, you have no way of telling the app: "Hey this is NOT running on an mobile device, there's no need to wait for the device to be ready to start".
In the native portion of the code, for example for iOS, in MainViewController.m there's a method viewDidLoad, I am sending a javascript variable that I later check for in the web code, if that variable is around, I will wait to start the code for my page until everything is ready (for example, navigator geolocation)
Under MainViewController.m:
- (void) viewDidLoad
{
[super viewDidLoad];
NSString* jsString = [NSString stringWithFormat:#"isAppNative = true;"];
[self.webView stringByEvaluatingJavaScriptFromString:jsString];
}
index.html the code goes like this:
function onBodyLoad()
{
document.addEventListener("deviceready", onDeviceReady, false);
}
function onDeviceReady(){;
myApp.run();
}
try{
if(isAppNative!=undefined);
}catch(err){
$(document).ready(function(){
myApp.run();
});
}
I would use the same codebase. The whole point of PhoneGap is to convert your mobile sites into apps. It isn't that difficult to detect features and screen realestate as appropriate. The trouble with seperate codebases is usually the cost of double-handling your content and styles. If necessary you could separate those out into a shared resource and bundle them at runtime/access but personally I'd still go with keeping it all together.
This blog covers the detection issue (see the comments too): http://bennolan.com/2011/08/22/phonegap-detection.html. The crux of it though is if (window.PhoneGap){...}

Connect Firefox extension with C# application

I need to be able to make an event such that every time a user loads a new page and closes firefox, I need it to call a method in my C# application that takes care of maintaining the user model. I know for sure I need to create some type of firefox extension where I use javascript to check such an event. However, I have no idea how I am going to integrate my C# application with the firefox extension. Can someone provide me with some guidance?
I'll help you out with the parts of the question that I'm familiar with (Javascript based add-ons), and offer some suggestions for the other parts. Here goes nothing!
Add-ons
Firefox add-ons easily provide the tools you need to detect page loads and opening / closing firefox.
To detect page loads you can register a listener to the DOMContentLoaded event in window.
window.addEventListener("DOMContentLoaded", function(event){
var url = event.originalTarget.location.href;
alert("Oh yeah, a document is loading: " + url);
}, false);
Alternatively, you can register a nsIWebProgressListener to listen for location changes. This probably closer to what you want, since DOMContentLoaded is also triggered for iframes.
var listener = {
//unimplemented methods (just give functions which do nothing)
onLocationChange: function(aWebProgress, aRequest, aLocation){
var url = aLocation.asciiSpec;
alert("Oh yeah, a the location changed: " + url);
}
};
gBrowser.addTabsProgressListener(listener);
To detect firefox open / close you need to first understand how firefox add-ons work with respect to multiple windows. When a new window of firefox is launched, you basically have 2 separate copies of your code running. So, if you care about firefox windows being opened and closed you can simply do:
window.addEventListener("load", function(event){
alert("Looks like you just opened up a new window");
}, false);
window.addEventListener("unload", function(event){
alert("Awh, you closed a window");
}, false);
But, most likely you want to detect opening / closing firefox as an entire application. This is achieved using a code-sharing mechanism called Javascript Modules. Javascript modules are loaded just once for the lifetime of the application. So, they enable you to share information between windows. Simply counting the number of windows opened and closed should be sufficient for this functionality.
var EXPORTED_SYMBOLS = ["windowOpened", "windowClosed"];
var windowsOpened = 0;
function windowOpened(){
if( windowsOpened === 0) {
alert("The first window has been opened!");
}
windowsOpened++;
}
function windowClosed(){
windowsOpened++;
if( windowsOpened === 0) {
alert("The last window has been closed!");
}
}
Then you can simply attach the aforementioned event handlers to call these 2 methods from their corresponding load and unload events.
So, this is all great and everything, but now you have to twiddle with the details of getting a baseline Firefox add-on setup. Fortunately, Mozilla has provided a handy Addon Builder to ease this. All the code about (except the Javascript module) should be placed in the ff-overlay.js file (assuming you use the linked builder).
C# communication
I'm a little less knowledgeable about the interprocess communication with C#. However, maybe I can point you in the right direction and let the smart people at SO fill in the rest.
I believe COM Objects are a method of communication between processes on Windows. So, you could build in a Binary Component to your add-on to perform the communication. However, as far as I understand it, setting up binary components is much more difficult than a standard javascript-based add-on. Either way, Mozilla provides a guide for setting it up in Visual Studio.
If you want to stay away from binary components you are left with the javascript enabled components of the SDK. This includes socket communication, files, pipes, a sqlite database etc. This SO question addresses exactly the question you're asking. If it were me, I would choose them in this order.
Sqlite Database
Named Pipes
Sockets
(1) because there is a lot of code samples available for this, and would be easy to implement on both sides. (2) because this would be the way I'd implement IPC if I were given full control of both sides of the application. (3) is last because I hate that crap (maybe I'm biased from Distributed Systems in college).
tl;dr
The page load stuff should be pretty simple. Check out the Addon Builder to get going with a FF addon, and here to see about detecting page loads.
The C# communication is doable, and addressed in this SO Question. I'd do it with a sqlite database for ease if it were me.

Categories