Detecting and Applying Current System Language on HTML 5 App on Android - android

I am working on a HTML5 app which uses PhoneGap and Backbone JS.
Problem is that Language changed on Android device through settings doesn't get in my HTML 5 app, though i can see it getting changed in independent Browser instance.
To support globalization of the app I am using i18n plugin to select current language for the app. My app works just fine with iOS. However when i try this on Android, language selected by user doesn't get reflected For example if i choose french as my language from system setting and try to see what is the value of window.navigator.language it remains en as oppose to fr, this gets reflected perfectly on iOS. Just for your information ,as recommended by PhoneGap, on Android I am calling
`public class myApp extends DroidGap {
private String pageURl = "somepath";
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.loadUrl(pageUrl); // this will load my app's main html page.
}
}`
Could somebody please help me in figuring out what the problem is?
Thanks
Big O

Try fetching language from user agent string with following patch, it should work:
var lang;
if (navigator
&& navigator.userAgent
&& (lang = navigator.userAgent
.match(/android.*\W(\w\w)-(\w\w)\W/i))) {
lang = lang[1];
}
if (!lang && navigator) {
if (navigator.language) {
lang = navigator.language;
} else if (navigator.browserLanguage) {
lang = navigator.browserLanguage;
} else if (navigator.systemLanguage) {
lang = navigator.systemLanguage;
} else if (navigator.userLanguage) {
lang = navigator.userLanguage;
}
lang = lang.substr(0, 2);
}
console.log("current language is", lang);

Selected answer doesn't seem to work with Cordova-Crosswalk project. Actually with Moto G2 and Cordova-Crosswalk in returns "99" because the userAgent is like this:
I would recommend to use Cordova Globalization plugin or make own simple plugin with Java method: Locale locale = Locale.getDefault();

Related

Cordova/jQuery - Identifying whether your app is being run on Web/Mobile browser or mobile app (Android/iOS)

I develop apps for Android/iOS using Cordova/Phonegap. I generally use a single code base for my web and mobile content. I use a SQLite database and/or other native plugins when it is a mobile app and have to avoid those LOCs when I'm on web.
But I'm facing a problem identifying whether my app is being run on a web browser on Desktop/Mac/Android/iOS or as a mobile app (Android/iOS).
I have tried userAgent sniffing, but this regex technique fails especially when running the code on mobile browsers. Following is the code I used to identify OS and version of the device:
getOSAndVersion: function() {
var that = this;
var userOS; // will either be iOS, Android or unknown
var userOSver; // this is a string, used to denote OS version
var ua = navigator.userAgent;
var uaindex;
if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(ua)) {
window.deviceType = "Mobile";
} else {
window.deviceType = "Web";
}
// determine OS
if (ua.match(/iPad/i) || ua.match(/iPhone/i)) {
userOS = 'iOS';
uaindex = ua.indexOf('OS ');
}
else if (ua.match(/Android/i)) {
userOS = 'Android';
uaindex = ua.indexOf('Android ');
}
else {
userOS = 'unknown';
}
// determine version
if (userOS === 'iOS' && uaindex > -1) {
userOSver = ua.substr(uaindex + 3, 3).replace('_', '.');
}
else if (userOS === 'Android' && uaindex > -1) {
userOSver = ua.substr(uaindex + 8, 3);
}
else {
userOSver = 'unknown';
}
return { osVersion: userOSver, os: userOS, deviceType: window.deviceType };
}
Is there any other technique I can use to reliably identify where my code is being run?
P.S. : I'm averse to using any other Cordova/JS plugin to identify it but still open for discussion.
In Cordova when app is runing into app the url is prefixed by file:// and when running in mobile browser the url is prefixed with http or https protocal.
Solution :
Get url of you current page (check this)
Identify its prefix if file:// the its app
If http or https then mobile browser
You could just check if cordova is defined?
if (cordova) {
// Running in your app
} else {
// Not running in your app, so website
}

WWW.LoadFromCacheOrDownload is not working in augmented reality app on android phone using unity

I am trying to build an augmented reality app and in that app i want some prefabs to load dynamically. So that with some 3d model prefabs on unity store i created myasset.unity3d . I am using WWW.LoadFromCacheOrDownload to download that unity3d file and using it.
When i am debugging in my laptop the file is downloading and i am using it as i want but when i add build in and try it on android phone download is not happening.
The code i am using to download is
IEnumerator DownloadAndCache() {
while (!Caching.ready)
yield return null;
string bundleURL = "http://s3-ap-southeast-1.amazonaws.com/cf-export/sofa.unity3d";
www = WWW.LoadFromCacheOrDownload (bundleURL, 1);
yield return www;
Debug.Log (www.assetBundle);
AssetBundle bundle = www.assetBundle;
}
So please help me .
i also tried other way of doing it but still i did not succeed
IEnumerator Start () {
WWW www = WWW.LoadFromCacheOrDownload (BundleURL, 1);
yield return www;
AssetBundle bundle = www.assetBundle;
AssetBundleRequest request = bundle.LoadAssetAsync (AssetName, typeof(GameObject));
yield return request;
GameObject obj = request.asset as GameObject;
Instantiate (obj);
bundle.Unload(false);
www.Dispose();
}
The above two methods are working in when testing in unity IDE but if i build using android and install it in android device its not working. I gave internet access to app while building
I printed the error using a text in mobile and please check the screen shot attached below
the first error text is www (variable for downloading) and second is www.error ( actual error). i did not get what that error meant. So please help me
the issue is asset bundle version is not sync with app version. So while making asset bundle i added small code which made my code working. To make Asset bundle my code is
using UnityEditor;
public class CreateAssetBundles
{
[MenuItem ("Assets/Build AssetBundles")]
static void BuildAllAssetBundles ()
{
BuildPipeline.BuildAssetBundles ("Assets/AssetBundles", BuildAssetBundleOptions.None, BuildTarget.Android);
}
}
To use AssetBuundle for Mobile platform:
While creating AssetBundle it must be platform specific. For Android use following Script to create AssetBundle. put it inside "Editor"
using UnityEngine;
using System.Collections;
using UnityEditor;
public class ExportAssetBundles : Editor {
[MenuItem("Assets/Build AssetBundle")]
static void ExportResource()
{
string path = "Assets/AssetBundle/myAssetBundle.unity3d";
Object[] selection = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets);
BuildPipeline.BuildAssetBundle(Selection.activeObject, selection, path,
BuildAssetBundleOptions.CollectDependencies
| BuildAssetBundleOptions.CompleteAssets,BuildTarget.Android);
}
}
Then Create folder "AssetBundle" inside Asset
When you create Assetbundle the AssetBundle.unity3d file will store inside this folder
Now you need to use Created Assetbundle at runtime. For this,
Write a script AssetBundleAugmenter
public class AssetBundleAugmenter : MonoBehaviour {
public string AssetName;
public int Version;
private GameObject mBundleInstance = null;
private bool mAttached = false;
void Start() {
StartCoroutine(DownloadAndCache());
}
// Update is called once per frame
IEnumerator DownloadAndCache() {
while(!Caching.ready)
yield return null;
//you can use remote URL like: www.arprabhu.com/assetBundle OR Local URL
// example URL of file on PC filesystem (Windows)
// string bundleURL = "file:///D:/Unity/AssetBundles/MyAssetBundle.unity3d";
// example URL of file on Android device SD-card
string bundleURL = System.IO.File.ReadAllText("/mnt/sdcard/filepath.txt");
Debug.Log ("Asset Loaded");
using (WWW www = WWW .LoadFromCacheOrDownload(bundleURL, Version)) {
yield return www;
if (www .error != null)
throw new UnityException("WWW Download had an error: " + www .error);
AssetBundle bundle = www .assetBundle;
if (AssetName == "")
Instantiate(bundle.mainAsset);
else
Instantiate(bundle.LoadAsset(AssetName));
// Unload the AssetBundles compressed contents to conserve memory
bundle.Unload(false);
}
}}
Attach this Script to Empty GameObject in your Scene
Congrats!, you are ready to go.
Try checking your androidManifest.xml for the permission to connect to external servers.
Then, if everything seems alright and still doesn't work, my advice is to download the Device Console plugin for the Unity Editor, which is a really nice way to access the internal Android Debugger.
https://www.assetstore.unity3d.com/en/#!/content/44935
Or if you're truly brave: use logcat within the terminal...

nginx redirect from web to mobile application

There are Android and iOS applications, I have dynamical URI and I need to redirect Android and iOS users directly to mobile application via nginx, only if they use this link.
But I don't understand how to handle it without "logical and" or "inner if".
As I understand I have to solve two conditions:
if ($http_user_agent ~* '(iphone|ipod|nokia|аndroid)' ) {
rewrite ^ mobile_application://$host$request_id last;
}
and:
set $my_uri sign-up?invitation=$key #this key is dynamical
if ($request_id = '($my_uri)' ) {
rewrite ^ mobile_application://$host$request_id last;
}
So, I have no idea how to fix it.
set $targeted_mobile no;
if ($http_user_agent ~* "android|iphone|ipod") {
set $targeted_mobile yes;
}
location /deep-link/ {
if ($targeted_mobile = yes) {
rewrite ^/deep-link/(.*) mobile://www.aaa.com/$1 permanent;
}
rewrite ^/deep-link/(.*) https://$server_name/$1 permanent;

Uses native code in cordova application

I have a following code in native android
List<PackageInfo> PackList = getPackageManager().getInstalledPackages(0);
for (int i=0; i < PackList.size(); i++)
{
PackageInfo PackInfo = PackList.get(i);
if ( ( (PackInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) != true)
{
String AppName = PackInfo.applicationInfo.loadLabel(getPackageManager()).toString();
Log.e("App" + Integer.toString(i), AppName);
}
}
for getting information about installed application in mobile. I want to use in cordova/phonegap application.
How I use that?
What steps do I need?
Or is there anyway that same code use in different platforms
(android,windows)?
I also checked this link but didn't understand
Thanks In Advance
To use native code in a phonegap app you have to create a phonegap plugin. This is actually pretty simple:
1) Create you phonegap plugin class, in this case the plugin only responds to the action "toast" to create a native Android toast:
public class ExamplePlugin extends CordovaPlugin {
#Override
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
if("toast".equals(action)) {
// The first String in the arguments array is the text for the toast
String text = args.getString(0);
Toast toast = Toast.makeText(this.cordova.getActivity(), text, Toast.LENGTH_SHORT);
toast.show();
// With PluginResult you can send results back to the js layer.
PluginResult result = new PluginResult(PluginResult.Status.OK, "--toast displayed.");
result.setKeepCallback(true);
callbackContext.sendPluginResult(result);
}
// Return true if everything worked as it should. If an error occurs return false.
// Depending on this return value either the success or error callback is invoked.
return true;
}
#Override
public void initialize(CordovaInterface cordova, CordovaWebView webView) {
super.initialize(cordova, webView);
// Here you can perform some initialisations for your plugin.
}
}
Then in the config.xml of your phonegap app you add this line:
<plugin name="ExamplePlugin" value="com.phonegap.example.ExamplePlugin" />
Name being the name by which you can call the plugin from javascript and value being the complete class name of your plugin.
Now you can call the plugin from javascript:
cordova.exec(successCallback, errorCallback, "ExamplePlugin", "toast", ["Hello Cordova!!1"]);
You supply two callbacks, the name of the plugin you want to call, the action you want to execute and an array of arguments, in our case the plugin is named "ExamplePlugin" the action is "toast" and we only have on string argument as text for our toast.
Of course this just works for Android. If you want the same functionality for different platforms e.g. iOS, Windows Phone etc. You are gonna have to create a plugin for each of them too.
You will need to create a PhoneGap/Cordova plugin.
In the return data (the result) in the plugin you need to return the String.
For recent an example, check out this blog post. It works with AndroidPreferences feature and it uses both sending data and retrieving data.

how to get the default HTTP USER AGENT from the android device?

How to get the default HTTP USER AGENT and its default settings from the android device?
thanks
Nohsib
as Varundroid mentioned in his answer,
String userAgent = System.getProperty("http.agent");
is better way to do it for Android 2.1 and above.
====================
From android source code.
public static String getDefaultUserAgent() {
StringBuilder result = new StringBuilder(64);
result.append("Dalvik/");
result.append(System.getProperty("java.vm.version")); // such as 1.1.0
result.append(" (Linux; U; Android ");
String version = Build.VERSION.RELEASE; // "1.0" or "3.4b5"
result.append(version.length() > 0 ? version : "1.0");
// add the model for the release build
if ("REL".equals(Build.VERSION.CODENAME)) {
String model = Build.MODEL;
if (model.length() > 0) {
result.append("; ");
result.append(model);
}
}
String id = Build.ID; // "MASTER" or "M4-rc20"
if (id.length() > 0) {
result.append(" Build/");
result.append(id);
}
result.append(")");
return result.toString();
}
Edit: See Prakash's answer, which is better for 2.1+.
Try http://developer.android.com/reference/android/webkit/WebSettings.html#getUserAgentString
Note that this User Agent will only apply for the embedded WebKit browser that's used by default in Android. Unfortunately, you'll need to create a new WebView object to get the user agent. Fortunately, the user agent doesn't change often, so you should only need to run this code once in your application lifetime (unless don't care about performance). Just do:
String userAgent = new WebView(this).getSettings().getUserAgentString();
Alternatively, you can use the JavaScript method navigator.getUserAgent().
When you use web view to access the user-agent, make sure you run the
new WebView(this).getSettings().getUserAgentString();
on the UI thread.
If you want access the user agent on background thread.
use
System.getProperty("http.agent")
To check whether a user-agent is valid or not use this
https://deviceatlas.com/device-data/user-agent-tester
Android get user agent
An alternative
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) {
String userAgent = WebSettings.getDefaultUserAgent(context);
}

Categories

Resources