Merge branch 'master' of https://github.com/phonegap/phonegap-plugins
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="src" path="gen"/>
|
||||
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
|
||||
<classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
|
||||
<classpathentry kind="lib" path="libs/cordova-2.1.0.jar"/>
|
||||
<classpathentry kind="output" path="bin/classes"/>
|
||||
</classpath>
|
||||
2
Android/ActionBarSherlockTabBar/Example project/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
bin/
|
||||
gen/
|
||||
33
Android/ActionBarSherlockTabBar/Example project/.project
Normal file
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>PhoneGapAndroidTest</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -0,0 +1,11 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=1.6
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=1.6
|
||||
@@ -0,0 +1,49 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.example.phonegapandroidtest"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0" >
|
||||
|
||||
<uses-sdk
|
||||
android:minSdkVersion="7"
|
||||
android:targetSdkVersion="15" />
|
||||
|
||||
<supports-screens
|
||||
android:anyDensity="true"
|
||||
android:largeScreens="true"
|
||||
android:normalScreens="true"
|
||||
android:resizeable="true"
|
||||
android:smallScreens="true" />
|
||||
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.RECEIVE_SMS" />
|
||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
|
||||
<uses-permission android:name="android.permission.READ_CONTACTS" />
|
||||
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
|
||||
<uses-permission android:name="android.permission.BROADCAST_STICKY" />
|
||||
|
||||
<application
|
||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale"
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/AppTheme" >
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:label="@string/title_activity_main" >
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
@@ -0,0 +1,25 @@
|
||||
// Usage: actionBarSherlockTabBar = cordova.require('cordova/plugin/actionBarSherlockTabBar');
|
||||
cordova.define('cordova/plugin/actionBarSherlockTabBar', function(require, exports, module) {
|
||||
var exec = require('cordova/exec');
|
||||
|
||||
var ActionBarSherlockTabBar = function() {}
|
||||
|
||||
ActionBarSherlockTabBar.prototype.setTabSelectedListener = function(callback) {
|
||||
if(typeof callback != 'function')
|
||||
throw 'ActionBarSherlockTabBar.setTabSelectedListener: Callback not a function'
|
||||
|
||||
exec(callback,
|
||||
function() { /* log error here?! */ },
|
||||
'ActionBarSherlockTabBar',
|
||||
'setTabSelectedListener',
|
||||
[])
|
||||
}
|
||||
|
||||
module.exports = new ActionBarSherlockTabBar();
|
||||
|
||||
exec(null,
|
||||
null,
|
||||
'ActionBarSherlockTabBar',
|
||||
'_init',
|
||||
[])
|
||||
});
|
||||
5814
Android/ActionBarSherlockTabBar/Example project/assets/www/cordova-2.1.0.js
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Cordova</title>
|
||||
<script type="text/javascript" charset="utf-8" src="cordova-2.1.0.js"></script>
|
||||
<script type="text/javascript" src="ActionBarSherlockTabBar.js"></script>
|
||||
<script type="text/javascript" src="jquery-1.8.2.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
document.addEventListener('deviceready', function() {
|
||||
navigator.splashscreen.hide()
|
||||
|
||||
$('<p/>').text('PhoneGap ready!').appendTo($('body'))
|
||||
|
||||
actionBarSherlockTabBar = cordova.require('cordova/plugin/actionBarSherlockTabBar')
|
||||
actionBarSherlockTabBar.setTabSelectedListener(function(tabTag) {
|
||||
$('#tab-name').text('Tab "' + tabTag + '" selected.')
|
||||
})
|
||||
}, false)
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World</h1>
|
||||
<p id="tab-name"></p>
|
||||
</body>
|
||||
</html>
|
||||
2
Android/ActionBarSherlockTabBar/Example project/assets/www/jquery-1.8.2.min.js
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
# To enable ProGuard in your project, edit project.properties
|
||||
# to define the proguard.config property as described in that file.
|
||||
#
|
||||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in ${sdk.dir}/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the ProGuard
|
||||
# include property in project.properties.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# Add any project specific keep options here:
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
@@ -0,0 +1,15 @@
|
||||
# This file is automatically generated by Android Tools.
|
||||
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
|
||||
#
|
||||
# This file must be checked in Version Control Systems.
|
||||
#
|
||||
# To customize properties used by the Ant build system edit
|
||||
# "ant.properties", and override values to adapt the script to your
|
||||
# project structure.
|
||||
#
|
||||
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
|
||||
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
|
||||
|
||||
# Project target.
|
||||
target=android-16
|
||||
android.library.reference.1=../dependencies/android/ActionBarSherlock/library
|
||||
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 9.2 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 5.1 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 14 KiB |
@@ -0,0 +1,14 @@
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" >
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:text="@string/hello_world"
|
||||
tools:context=".MainActivity" />
|
||||
|
||||
</RelativeLayout>
|
||||
@@ -0,0 +1,6 @@
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:id="@+id/menu_settings"
|
||||
android:title="@string/menu_settings"
|
||||
android:orderInCategory="100"
|
||||
android:showAsAction="never" />
|
||||
</menu>
|
||||
@@ -0,0 +1,5 @@
|
||||
<resources>
|
||||
|
||||
<style name="AppTheme" parent="@style/Theme.Sherlock.Light" />
|
||||
|
||||
</resources>
|
||||
@@ -0,0 +1,5 @@
|
||||
<resources>
|
||||
|
||||
<style name="AppTheme" parent="@style/Theme.Sherlock.Light.DarkActionBar" />
|
||||
|
||||
</resources>
|
||||
@@ -0,0 +1,9 @@
|
||||
<resources>
|
||||
|
||||
<string name="app_name">PhoneGapAndroidTest</string>
|
||||
<string name="hello_world">Hello world!</string>
|
||||
<string name="menu_settings">Settings</string>
|
||||
<string name="tab_settings">Settings</string>
|
||||
<string name="title_activity_main">MainActivity</string>
|
||||
|
||||
</resources>
|
||||
@@ -0,0 +1,5 @@
|
||||
<resources>
|
||||
|
||||
<style name="AppTheme" parent="@style/Theme.Sherlock.Light" />
|
||||
|
||||
</resources>
|
||||
@@ -0,0 +1,58 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the License is distributed on an
|
||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, either express or implied. See the License for the
|
||||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
-->
|
||||
<cordova>
|
||||
<!--
|
||||
access elements control the Android whitelist.
|
||||
Domains are assumed blocked unless set otherwise
|
||||
-->
|
||||
|
||||
<access origin="http://127.0.0.1*"/> <!-- allow local pages -->
|
||||
|
||||
<!-- <access origin="https://example.com" /> allow any secure requests to example.com -->
|
||||
<!-- <access origin="https://example.com" subdomains="true" /> such as above, but including subdomains, such as www -->
|
||||
<access origin=".*"/>
|
||||
|
||||
<log level="DEBUG"/>
|
||||
<preference name="useBrowserHistory" value="false" />
|
||||
<preference name="exit-on-suspend" value="false" />
|
||||
<plugins>
|
||||
<plugin name="App" value="org.apache.cordova.App"/>
|
||||
<plugin name="Geolocation" value="org.apache.cordova.GeoBroker"/>
|
||||
<plugin name="Device" value="org.apache.cordova.Device"/>
|
||||
<plugin name="Accelerometer" value="org.apache.cordova.AccelListener"/>
|
||||
<plugin name="Compass" value="org.apache.cordova.CompassListener"/>
|
||||
<plugin name="Media" value="org.apache.cordova.AudioHandler"/>
|
||||
<plugin name="Camera" value="org.apache.cordova.CameraLauncher"/>
|
||||
<plugin name="Contacts" value="org.apache.cordova.ContactManager"/>
|
||||
<plugin name="File" value="org.apache.cordova.FileUtils"/>
|
||||
<plugin name="NetworkStatus" value="org.apache.cordova.NetworkManager"/>
|
||||
<plugin name="Notification" value="org.apache.cordova.Notification"/>
|
||||
<plugin name="Storage" value="org.apache.cordova.Storage"/>
|
||||
<plugin name="Temperature" value="org.apache.cordova.TempListener"/>
|
||||
<plugin name="FileTransfer" value="org.apache.cordova.FileTransfer"/>
|
||||
<plugin name="Capture" value="org.apache.cordova.Capture"/>
|
||||
<plugin name="Battery" value="org.apache.cordova.BatteryListener"/>
|
||||
<plugin name="SplashScreen" value="org.apache.cordova.SplashScreen"/>
|
||||
<plugin name="Echo" value="org.apache.cordova.Echo" />
|
||||
|
||||
<plugin name="ActionBarSherlockTabBar" value="de.andidog.phonegapplugins.ActionBarSherlockTabBarPlugin" />
|
||||
</plugins>
|
||||
</cordova>
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
package com.example.phonegapandroidtest;
|
||||
|
||||
import org.apache.cordova.DroidGap;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup.LayoutParams;
|
||||
|
||||
import com.actionbarsherlock.ActionBarSherlock;
|
||||
|
||||
import de.andidog.phonegapplugins.ActionBarSherlockTabBarPlugin;
|
||||
|
||||
public class MainActivity extends DroidGap implements ActionBarSherlockTabBarPlugin.OnInitListener
|
||||
{
|
||||
private ActionBarSherlock sherlock = ActionBarSherlock.wrap(this);
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
// Show the title bar, or else the ActionBar will be null on Android 4.x
|
||||
super.setBooleanProperty("showTitle", true);
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
ActionBarSherlockTabBarPlugin.setOnInitListener(this);
|
||||
|
||||
super.setIntegerProperty("loadUrlTimeoutValue", 60000);
|
||||
|
||||
// Show splashscreen up to 25 seconds (hidden when application is ready, see JavaScript code)
|
||||
super.loadUrl("file:///android_asset/www/index.html", 25000);
|
||||
}
|
||||
|
||||
private void createTabs()
|
||||
{
|
||||
ActionBarSherlockTabBarPlugin.instance.setSherlock(sherlock);
|
||||
|
||||
// You can either provide a text by string literal or resource ID (R.string.something)
|
||||
ActionBarSherlockTabBarPlugin.instance.addTab("tab-home", "Home", null);
|
||||
ActionBarSherlockTabBarPlugin.instance.addTab("tab-settings", R.string.tab_settings, null);
|
||||
|
||||
// Icons are possible, too, but not together with a text label!
|
||||
ActionBarSherlockTabBarPlugin.instance.addTab("tab-search", null, R.drawable.ic_action_search);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActionBarSherlockTabBarPluginInitialized()
|
||||
{
|
||||
// Now it's safe to access ActionBarSherlockTabBarPlugin.instance because the plugin was instantiated
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
createTabs();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// All setContentView methods are overridden because ActionBarSherlock has to modify the view
|
||||
@Override
|
||||
public void setContentView(int layoutResID)
|
||||
{
|
||||
// Don't call super!
|
||||
sherlock.setContentView(layoutResID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentView(View view)
|
||||
{
|
||||
// Don't call super!
|
||||
sherlock.setContentView(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentView(View view, LayoutParams params)
|
||||
{
|
||||
// Don't call super!
|
||||
sherlock.setContentView(view, params);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
package de.andidog.phonegapplugins;
|
||||
|
||||
import org.apache.cordova.api.Plugin;
|
||||
import org.apache.cordova.api.PluginResult;
|
||||
import org.json.JSONArray;
|
||||
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
import android.util.Log;
|
||||
|
||||
import com.actionbarsherlock.ActionBarSherlock;
|
||||
import com.actionbarsherlock.app.ActionBar;
|
||||
import com.actionbarsherlock.app.ActionBar.Tab;
|
||||
|
||||
/**
|
||||
* Acts like a bridge between the ActionBarSherlock tab bar implementation and the WebView. The code in the WebView can
|
||||
* install a callback function that is called when the tab selection changes.
|
||||
*/
|
||||
public class ActionBarSherlockTabBarPlugin extends Plugin implements ActionBar.TabListener
|
||||
{
|
||||
public interface OnInitListener
|
||||
{
|
||||
void onActionBarSherlockTabBarPluginInitialized();
|
||||
}
|
||||
|
||||
private static final String TAG = "ActionBarSherlockTabBarPlugin";
|
||||
|
||||
public String callback;
|
||||
private static OnInitListener onInitListener;
|
||||
|
||||
// https://issues.apache.org/jira/browse/CB-1062
|
||||
public static ActionBarSherlockTabBarPlugin instance;
|
||||
|
||||
protected ActionBarSherlock sherlock;
|
||||
|
||||
public ActionBarSherlockTabBarPlugin()
|
||||
{
|
||||
instance = this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a tab to the tab bar implemented with ActionBarSherlock
|
||||
*
|
||||
* Use this from your main activity, it cannot be called from JavaScript code because you may want to reference
|
||||
* resources (e.g. tab icons of R.drawable).
|
||||
*
|
||||
* @param tabTag
|
||||
* @param text Resource ID for translated text label of the tab.
|
||||
* @param icon Resource ID for a tab icon. Can be NULL, but either text or icon must be given.
|
||||
*/
|
||||
public void addTab(String tabTag, int textResourceId, Integer iconResourceId)
|
||||
{
|
||||
addTab(tabTag, null, textResourceId, iconResourceId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a tab to the tab bar implemented with ActionBarSherlock
|
||||
*
|
||||
* Use this from your main activity, it cannot be called from JavaScript code because you may want to reference
|
||||
* resources (e.g. tab icons of R.drawable).
|
||||
*
|
||||
* @param tabTag
|
||||
* @param text Text label of the tab. Can be NULL, but either text or icon must be given.
|
||||
* @param icon Resource ID for a tab icon. Can be NULL, but either text or icon must be given.
|
||||
*/
|
||||
public void addTab(String tabTag, String text, Integer iconResourceId)
|
||||
{
|
||||
addTab(tabTag, text, null, iconResourceId);
|
||||
}
|
||||
|
||||
protected void addTab(String tabTag, String text, Integer textResourceId, Integer iconResourceId)
|
||||
{
|
||||
if(sherlock == null)
|
||||
throw new IllegalArgumentException("Must call setSherlock first");
|
||||
if(tabTag == null)
|
||||
throw new IllegalArgumentException("tabTag may not be NULL");
|
||||
if((text == null && textResourceId == null) == (iconResourceId == null))
|
||||
throw new IllegalArgumentException("Either text or icon must be set for a tab (not both)");
|
||||
|
||||
final ActionBar actionBar = sherlock.getActionBar();
|
||||
|
||||
Tab tab = actionBar.newTab();
|
||||
|
||||
if(text != null)
|
||||
tab.setText(text);
|
||||
else if(textResourceId != null)
|
||||
tab.setText(textResourceId);
|
||||
else if(iconResourceId != null)
|
||||
tab.setIcon(iconResourceId);
|
||||
|
||||
tab.setTag(tabTag);
|
||||
tab.setTabListener(this);
|
||||
|
||||
actionBar.addTab(tab);
|
||||
}
|
||||
|
||||
public PluginResult execute(String action, JSONArray args, String callbackId)
|
||||
{
|
||||
if(action.equals("setTabSelectedListener"))
|
||||
{
|
||||
this.callback = callbackId;
|
||||
|
||||
if(args.length() != 0)
|
||||
throw new AssertionError("setTabSelectedListener takes no arguments");
|
||||
|
||||
PluginResult res = new PluginResult(PluginResult.Status.NO_RESULT);
|
||||
res.setKeepCallback(true);
|
||||
return res;
|
||||
}
|
||||
else if(action.equals("_init"))
|
||||
{
|
||||
// This is the signal send from the JavaScript that forces construction of this plugin
|
||||
if(onInitListener != null)
|
||||
{
|
||||
onInitListener.onActionBarSherlockTabBarPluginInitialized();
|
||||
onInitListener = null;
|
||||
}
|
||||
|
||||
return new PluginResult(PluginResult.Status.NO_RESULT);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.e(TAG, "Invalid call: " + action);
|
||||
return new PluginResult(PluginResult.Status.INVALID_ACTION);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTabReselected(Tab tab, FragmentTransaction ft)
|
||||
{
|
||||
Log.d(TAG, "Tab " + tab.getTag() + " reselected");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTabSelected(Tab tab, FragmentTransaction ft)
|
||||
{
|
||||
triggerTabSelectedEvent((String)tab.getTag());
|
||||
|
||||
Log.d(TAG, "Tab " + tab.getTag() + " selected");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTabUnselected(Tab tab, FragmentTransaction ft)
|
||||
{
|
||||
Log.d(TAG, "Tab " + tab.getTag() + " unselected");
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the activity that is enhanced with a tab bar
|
||||
*
|
||||
* This method must be run on the UI thread!
|
||||
*/
|
||||
public void setSherlock(ActionBarSherlock sherlock)
|
||||
{
|
||||
if(this.sherlock != null && this.sherlock != sherlock)
|
||||
throw new IllegalStateException("May only set ActionBarSherlock instance of tab bar once");
|
||||
|
||||
this.sherlock = sherlock;
|
||||
|
||||
final ActionBar actionBar = sherlock.getActionBar();
|
||||
|
||||
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
|
||||
actionBar.setDisplayShowHomeEnabled(false);
|
||||
actionBar.setDisplayShowTitleEnabled(false);
|
||||
}
|
||||
|
||||
// What you won't do to hack PhoneGap's plugin initialization order...
|
||||
public static void setOnInitListener(OnInitListener listener)
|
||||
{
|
||||
onInitListener = listener;
|
||||
|
||||
// Trigger immediately if already loaded (probably won't happen)
|
||||
if(instance != null)
|
||||
{
|
||||
onInitListener.onActionBarSherlockTabBarPluginInitialized();
|
||||
onInitListener = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void triggerTabSelectedEvent(String tabTag)
|
||||
{
|
||||
PluginResult res = new PluginResult(PluginResult.Status.OK, tabTag);
|
||||
res.setKeepCallback(true);
|
||||
this.success(res, callback);
|
||||
}
|
||||
}
|
||||
BIN
Android/ActionBarSherlockTabBar/Example screenshot.png
Normal file
|
After Width: | Height: | Size: 9.1 KiB |
132
Android/ActionBarSherlockTabBar/README.md
Normal file
@@ -0,0 +1,132 @@
|
||||
Tab bar for Cordova on Android
|
||||
==============================
|
||||
|
||||

|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
Plugin code is licensed under the [MIT license](http://www.opensource.org/licenses/mit-license.html), [ActionBarSherlock](http://actionbarsherlock.com/) under the Apache License 2.0.
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
- Compatible with Cordova 2.1.0 (older versions not tested)
|
||||
- Should work on Android versions down to 2.1 (SDK version 7)
|
||||
- You can register a callback function that is triggered when the selected tab changes
|
||||
- Only tabs implemented (with text or icon), no other features of ActionBarSherlock
|
||||
- Can show/hide tab bar at runtime
|
||||
- If a tab is reselected, you won't be notified (*TODO*)
|
||||
- Tab creation only from Java code, not from JavaScript (*TODO*)
|
||||
|
||||
Setup
|
||||
-----
|
||||
|
||||
- Download ActionBarSherlock and add the `library` folder as Android library project (see ActionBarSherlock
|
||||
documentation)
|
||||
- Reference the library project in your own Android project and make sure both compile
|
||||
- They must have the same Android support library JAR file, if any (same file checksum)
|
||||
- You may have to change the compiler settings to use Java 1.6 (right-click project, Properties > Java Compiler)
|
||||
- Copy `ActionBarSherlockTabBar.js` from `assets/www` to the appropriate location in your project (e.g. `assets/www`)
|
||||
- Copy the `src` folder to your project
|
||||
- Refresh your Android project (click on project name and press F5)
|
||||
|
||||
Now change your main activity (the one deriving from DroidGap) like this:
|
||||
|
||||
public class MainActivity extends DroidGap implements ActionBarSherlockTabBarPlugin.OnInitListener
|
||||
{
|
||||
private ActionBarSherlock sherlock = ActionBarSherlock.wrap(this);
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
// Show the title bar, or else the ActionBar will be null on Android 4.x
|
||||
super.setBooleanProperty("showTitle", true);
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
ActionBarSherlockTabBarPlugin.setOnInitListener(this);
|
||||
|
||||
// The following two lines have nothing to do with the plugin, just good practice in my opinion:
|
||||
|
||||
super.setIntegerProperty("loadUrlTimeoutValue", 60000);
|
||||
|
||||
// Show splashscreen up to 25 seconds (hidden when application is ready, see JavaScript code)
|
||||
super.loadUrl("file:///android_asset/www/index.html", 25000);
|
||||
}
|
||||
|
||||
private void createTabs()
|
||||
{
|
||||
ActionBarSherlockTabBarPlugin.instance.setSherlock(sherlock);
|
||||
|
||||
// You can either provide a text by string literal or resource ID (R.string.something).
|
||||
ActionBarSherlockTabBarPlugin.instance.addTab("tab-home", "Home", null);
|
||||
ActionBarSherlockTabBarPlugin.instance.addTab("tab-settings", R.string.tab_settings, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActionBarSherlockTabBarPluginInitialized()
|
||||
{
|
||||
// Now it's safe to access ActionBarSherlockTabBarPlugin.instance because the plugin was instantiated
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
createTabs();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// All setContentView methods are overridden because ActionBarSherlock has to modify the view
|
||||
@Override
|
||||
public void setContentView(int layoutResID)
|
||||
{
|
||||
// Don't call super!
|
||||
sherlock.setContentView(layoutResID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentView(View view)
|
||||
{
|
||||
// Don't call super!
|
||||
sherlock.setContentView(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentView(View view, LayoutParams params)
|
||||
{
|
||||
// Don't call super!
|
||||
sherlock.setContentView(view, params);
|
||||
}
|
||||
}
|
||||
|
||||
Set a compatible theme for the activity in `AndroidManifest.xml`. Predefined themes are `Theme.Sherlock`,
|
||||
`Theme.Sherlock.Light` and `Theme.Sherlock.Light.DarkActionBar`. You can define your own with [Android Action Bar Style
|
||||
Generator](http://jgilfelt.github.com/android-actionbarstylegenerator/). Note that the predefined ones must be prefixed
|
||||
like `@style/Theme.Sherlock`.
|
||||
|
||||
As last step, register the plugin in your `config.xml`:
|
||||
|
||||
<plugin name="ActionBarSherlockTabBar" value="de.andidog.phonegapplugins.ActionBarSherlockTabBarPlugin" />
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
Use the plugin like so:
|
||||
|
||||
<script type="text/javascript" src="ActionBarSherlockTabBar.js"></script>
|
||||
<script type="text/javascript">
|
||||
document.addEventListener('deviceready', function() {
|
||||
actionBarSherlockTabBar = cordova.require('cordova/plugin/actionBarSherlockTabBar')
|
||||
|
||||
actionBarSherlockTabBar.setTabSelectedListener(function(tabTag) {
|
||||
console.log('Tab ' + tabTag + ' selected')
|
||||
})
|
||||
|
||||
// Tab bar is shown by default, but you can change that at runtime
|
||||
// actionBarSherlockTabBar.hide()
|
||||
// actionBarSherlockTabBar.show()
|
||||
}
|
||||
</script>
|
||||
|
||||
See also the example project in the repository (note: you have to download and reference ActionBarSherlock yourself).
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
MIT licensed (http://www.opensource.org/licenses/mit-license.html)
|
||||
|
||||
See https://github.com/AndiDog/phonegap-plugins
|
||||
*/
|
||||
|
||||
// Usage: actionBarSherlockTabBar = cordova.require('cordova/plugin/actionBarSherlockTabBar');
|
||||
cordova.define('cordova/plugin/actionBarSherlockTabBar', function(require, exports, module) {
|
||||
var exec = require('cordova/exec')
|
||||
|
||||
var ActionBarSherlockTabBar = function() {}
|
||||
|
||||
ActionBarSherlockTabBar.prototype.hide = function() {
|
||||
exec(null,
|
||||
null,
|
||||
'ActionBarSherlockTabBar',
|
||||
'hide',
|
||||
[])
|
||||
}
|
||||
|
||||
ActionBarSherlockTabBar.prototype.show = function() {
|
||||
exec(null,
|
||||
null,
|
||||
'ActionBarSherlockTabBar',
|
||||
'show',
|
||||
[])
|
||||
}
|
||||
|
||||
ActionBarSherlockTabBar.prototype.setTabSelectedListener = function(callback) {
|
||||
if(typeof callback != 'function')
|
||||
throw 'ActionBarSherlockTabBar.setTabSelectedListener: Callback not a function'
|
||||
|
||||
exec(callback,
|
||||
function() {},
|
||||
'ActionBarSherlockTabBar',
|
||||
'setTabSelectedListener',
|
||||
[])
|
||||
}
|
||||
|
||||
module.exports = new ActionBarSherlockTabBar()
|
||||
|
||||
exec(null,
|
||||
null,
|
||||
'ActionBarSherlockTabBar',
|
||||
'_init',
|
||||
[])
|
||||
});
|
||||
@@ -0,0 +1,214 @@
|
||||
/*
|
||||
MIT licensed (http://www.opensource.org/licenses/mit-license.html)
|
||||
|
||||
See https://github.com/AndiDog/phonegap-plugins
|
||||
*/
|
||||
package de.andidog.phonegapplugins;
|
||||
|
||||
import org.apache.cordova.api.Plugin;
|
||||
import org.apache.cordova.api.PluginResult;
|
||||
import org.json.JSONArray;
|
||||
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
import android.util.Log;
|
||||
|
||||
import com.actionbarsherlock.ActionBarSherlock;
|
||||
import com.actionbarsherlock.app.ActionBar;
|
||||
import com.actionbarsherlock.app.ActionBar.Tab;
|
||||
|
||||
/**
|
||||
* Acts like a bridge between the ActionBarSherlock tab bar implementation and the WebView. The code in the WebView can
|
||||
* install a callback function that is called when the tab selection changes.
|
||||
*/
|
||||
public class ActionBarSherlockTabBarPlugin extends Plugin implements ActionBar.TabListener
|
||||
{
|
||||
public interface OnInitListener
|
||||
{
|
||||
void onActionBarSherlockTabBarPluginInitialized();
|
||||
}
|
||||
|
||||
private static final String TAG = "ActionBarSherlockTabBarPlugin";
|
||||
|
||||
public String callback;
|
||||
private static OnInitListener onInitListener;
|
||||
|
||||
// https://issues.apache.org/jira/browse/CB-1062
|
||||
public static ActionBarSherlockTabBarPlugin instance;
|
||||
|
||||
protected ActionBarSherlock sherlock;
|
||||
|
||||
public ActionBarSherlockTabBarPlugin()
|
||||
{
|
||||
instance = this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a tab to the tab bar implemented with ActionBarSherlock
|
||||
*
|
||||
* Use this from your main activity, it cannot be called from JavaScript code because you may want to reference
|
||||
* resources (e.g. tab icons of R.drawable).
|
||||
*
|
||||
* @param tabTag
|
||||
* @param text Resource ID for translated text label of the tab.
|
||||
* @param icon Resource ID for a tab icon. Can be NULL, but either text or icon must be given.
|
||||
*/
|
||||
public void addTab(String tabTag, int textResourceId, Integer iconResourceId)
|
||||
{
|
||||
addTab(tabTag, null, textResourceId, iconResourceId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a tab to the tab bar implemented with ActionBarSherlock
|
||||
*
|
||||
* Use this from your main activity, it cannot be called from JavaScript code because you may want to reference
|
||||
* resources (e.g. tab icons of R.drawable).
|
||||
*
|
||||
* @param tabTag
|
||||
* @param text Text label of the tab. Can be NULL, but either text or icon must be given.
|
||||
* @param icon Resource ID for a tab icon. Can be NULL, but either text or icon must be given.
|
||||
*/
|
||||
public void addTab(String tabTag, String text, Integer iconResourceId)
|
||||
{
|
||||
addTab(tabTag, text, null, iconResourceId);
|
||||
}
|
||||
|
||||
protected void addTab(String tabTag, String text, Integer textResourceId, Integer iconResourceId)
|
||||
{
|
||||
if(sherlock == null)
|
||||
throw new IllegalArgumentException("Must call setSherlock first");
|
||||
if(tabTag == null)
|
||||
throw new IllegalArgumentException("tabTag may not be NULL");
|
||||
if((text == null && textResourceId == null) == (iconResourceId == null))
|
||||
throw new IllegalArgumentException("Either text or icon must be set for a tab (not both)");
|
||||
|
||||
final ActionBar actionBar = sherlock.getActionBar();
|
||||
|
||||
Tab tab = actionBar.newTab();
|
||||
|
||||
if(text != null)
|
||||
tab.setText(text);
|
||||
else if(textResourceId != null)
|
||||
tab.setText(textResourceId);
|
||||
else if(iconResourceId != null)
|
||||
tab.setIcon(iconResourceId);
|
||||
|
||||
tab.setTag(tabTag);
|
||||
tab.setTabListener(this);
|
||||
|
||||
actionBar.addTab(tab);
|
||||
}
|
||||
|
||||
public PluginResult execute(String action, JSONArray args, String callbackId)
|
||||
{
|
||||
if(action.equals("setTabSelectedListener"))
|
||||
{
|
||||
this.callback = callbackId;
|
||||
|
||||
if(args.length() != 0)
|
||||
throw new AssertionError("setTabSelectedListener takes no arguments");
|
||||
|
||||
PluginResult res = new PluginResult(PluginResult.Status.NO_RESULT);
|
||||
res.setKeepCallback(true);
|
||||
return res;
|
||||
}
|
||||
else if(action.equals("hide"))
|
||||
{
|
||||
final ActionBar actionBar = sherlock.getActionBar();
|
||||
cordova.getActivity().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
actionBar.hide();
|
||||
}
|
||||
});
|
||||
return new PluginResult(PluginResult.Status.NO_RESULT);
|
||||
}
|
||||
else if(action.equals("show"))
|
||||
{
|
||||
final ActionBar actionBar = sherlock.getActionBar();
|
||||
cordova.getActivity().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
actionBar.show();
|
||||
}
|
||||
});
|
||||
return new PluginResult(PluginResult.Status.NO_RESULT);
|
||||
}
|
||||
else if(action.equals("_init"))
|
||||
{
|
||||
// This is the signal send from the JavaScript that forces construction of this plugin
|
||||
if(onInitListener != null)
|
||||
{
|
||||
onInitListener.onActionBarSherlockTabBarPluginInitialized();
|
||||
onInitListener = null;
|
||||
}
|
||||
|
||||
return new PluginResult(PluginResult.Status.NO_RESULT);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.e(TAG, "Invalid call: " + action);
|
||||
return new PluginResult(PluginResult.Status.INVALID_ACTION);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTabReselected(Tab tab, FragmentTransaction ft)
|
||||
{
|
||||
Log.d(TAG, "Tab " + tab.getTag() + " reselected");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTabSelected(Tab tab, FragmentTransaction ft)
|
||||
{
|
||||
triggerTabSelectedEvent((String)tab.getTag());
|
||||
|
||||
Log.d(TAG, "Tab " + tab.getTag() + " selected");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTabUnselected(Tab tab, FragmentTransaction ft)
|
||||
{
|
||||
Log.d(TAG, "Tab " + tab.getTag() + " unselected");
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the activity that is enhanced with a tab bar
|
||||
*
|
||||
* This method must be run on the UI thread!
|
||||
*/
|
||||
public void setSherlock(ActionBarSherlock sherlock)
|
||||
{
|
||||
if(this.sherlock != null && this.sherlock != sherlock)
|
||||
throw new IllegalStateException("May only set ActionBarSherlock instance of tab bar once");
|
||||
|
||||
this.sherlock = sherlock;
|
||||
|
||||
final ActionBar actionBar = sherlock.getActionBar();
|
||||
|
||||
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
|
||||
actionBar.setDisplayShowHomeEnabled(false);
|
||||
actionBar.setDisplayShowTitleEnabled(false);
|
||||
}
|
||||
|
||||
// What you won't do to hack PhoneGap's plugin initialization order...
|
||||
public static void setOnInitListener(OnInitListener listener)
|
||||
{
|
||||
onInitListener = listener;
|
||||
|
||||
// Trigger immediately if already loaded (probably won't happen)
|
||||
if(instance != null)
|
||||
{
|
||||
onInitListener.onActionBarSherlockTabBarPluginInitialized();
|
||||
onInitListener = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void triggerTabSelectedEvent(String tabTag)
|
||||
{
|
||||
PluginResult res = new PluginResult(PluginResult.Status.OK, tabTag);
|
||||
res.setKeepCallback(true);
|
||||
this.success(res, callback);
|
||||
}
|
||||
}
|
||||
62
Android/Analytics/2.0/APACHE2.0LICENSE
Normal file
@@ -0,0 +1,62 @@
|
||||
libGoogleAnalytics.jar is distributed under Apache License, Version 2.0.
|
||||
The text of the Apache License, Version 2.0 licenses is reproduced below.
|
||||
|
||||
----------------------------------------------
|
||||
|
||||
Apache License, Version 2.0
|
||||
FoundationProjectsPeopleGet InvolvedDownloadSupport ApacheHome » Licenses
|
||||
Apache License
|
||||
|
||||
Version 2.0, January 2004
|
||||
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
|
||||
|
||||
You must give any other recipients of the Work or Derivative Works a copy of this License; and
|
||||
|
||||
You must cause any modified files to carry prominent notices stating that You changed the files; and
|
||||
|
||||
You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
|
||||
|
||||
If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
193
Android/Analytics/2.0/README.md
Normal file
@@ -0,0 +1,193 @@
|
||||
# Analytics plugin for Phonegap #
|
||||
|
||||
The analytics client allows you to send page views to Google Analytics server.
|
||||
|
||||
A simple use case would be:
|
||||
|
||||
- Initialize Analytics object with the appropriate Google Analytics account.
|
||||
- Send page views upon user navigation.
|
||||
- Send events upon user interaction.
|
||||
|
||||
## Adding the Plugin to your project ##
|
||||
|
||||
Using this plugin requires [PhoneGap Cordova library for Android](http://phonegap.com/download) version 1.9 or above.
|
||||
|
||||
1. To install the plugin, move www/analytics.js to your project's www folder and include a reference to it in your html file after cordova.js.
|
||||
|
||||
<script type="text/javascript" charset="utf-8" src="cordova.js"></script><br/>
|
||||
<script type="text/javascript" charset="utf-8" src="analytics.js"></script>
|
||||
|
||||
2. Create a directory within your project called "src/com/phonegap/plugins/analytics" and copy src/com/phonegap/plugins/analytics/GoogleAnalyticsTracker.java into it.
|
||||
|
||||
3. Add the following activity to your AndroidManifest.xml file if it not already there. It should be added inside the <application> tag.
|
||||
|
||||
<activity android:name="com.phonegap.DroidGap" android:label="@string/app_name"><br/>
|
||||
<intent-filter><br/>
|
||||
</intent-filter><br/>
|
||||
</activity>
|
||||
|
||||
4. Download [GoogleAnalytics](https://developers.google.com/analytics/devguides/collection/android/resources) library (tested with 1.4.2) and copy "lib/libGoogleAnalytics.jar" into the libs directory within your project. You will also need to right click on this file in eclipse and add the jar to the build path.
|
||||
|
||||
5. In your res/xml/config.xml file add the following line:
|
||||
|
||||
<plugin name="GoogleAnalyticsTracker" value="com.phonegap.plugins.analytics.GoogleAnalyticsTracker" />
|
||||
|
||||
## Using the plugin ##
|
||||
|
||||
The plugin creates the object `window.plugins.analytics`. To use, call one of the following, available methods:
|
||||
|
||||
<pre>
|
||||
/**
|
||||
* Initialize Google Analytics configuration
|
||||
*
|
||||
* @param accountId The Google Analytics account id
|
||||
* @param successCallback The success callback
|
||||
* @param failureCallback The error callback
|
||||
*/
|
||||
|
||||
start(accountId, successCallback, failureCallback);
|
||||
</pre>
|
||||
|
||||
Sample use:
|
||||
|
||||
window.plugins.analytics.start("Your-Account-ID-Here", function(){alert("Start: success");}, function(){alert("Start: failure");});
|
||||
|
||||
<pre>
|
||||
/**
|
||||
* Track a page view on Google Analytics
|
||||
* @param key The name of the tracked item (can be a url or some logical name).
|
||||
* The key name will be presented in Google Analytics report.
|
||||
* @param successCallback The success callback
|
||||
* @param failureCallback The error callback
|
||||
*/
|
||||
|
||||
trackPageView(key, successCallback, failureCallback);
|
||||
</pre>
|
||||
|
||||
Sample use:
|
||||
|
||||
window.plugins.analytics.trackPageView("page1.html", function(){alert("Track: success");}, function(){alert("Track: failure");});
|
||||
|
||||
<pre>
|
||||
/**
|
||||
* Track an event on Google Analytics
|
||||
* @param category The name that you supply as a way to group objects that you want to track
|
||||
* @param action The name the type of event or interaction you want to track for a particular web object
|
||||
* @param label Provides additional information for events that you want to track (optional)
|
||||
* @param value Assign a numerical value to a tracked page object (optional)
|
||||
|
||||
* @param successCallback The success callback
|
||||
* @param failureCallback The error callback
|
||||
*/
|
||||
|
||||
trackEvent(category, action, label, value, successCallback, failureCallback);
|
||||
</pre>
|
||||
|
||||
Sample use:
|
||||
|
||||
window.plugins.analytics.trackEvent("category", "action", "event", 1, function(){alert("Track: success");}, function(){alert("Track: failure");});
|
||||
|
||||
|
||||
Please keep in mind that these methods, as in any other plugin, are ready to be invoked only after '[deviceready](http://docs.phonegap.com/phonegap_events_events.md.html#deviceready)' event has been fired
|
||||
Good practice will be manual dispatch and stop session. Add this code to your main activity:
|
||||
<pre>
|
||||
@Override
|
||||
public void onDestroy()
|
||||
{
|
||||
super.onDestroy();
|
||||
GoogleAnalyticsTracker tracker = com.google.android.apps.analytics.GoogleAnalyticsTracker.getInstance();
|
||||
tracker.dispatch();
|
||||
tracker.stopSession();
|
||||
}
|
||||
</pre>
|
||||
|
||||
## RELEASE NOTES ##
|
||||
|
||||
### AUG, 14, 2012 ###
|
||||
|
||||
* Added suppport for Cordova 1.9 and above
|
||||
|
||||
### AUG, 10, 2011 ###
|
||||
|
||||
* Added event tracking
|
||||
|
||||
### Jul 24, 2011 ###
|
||||
|
||||
* Initial release
|
||||
|
||||
## BUGS AND CONTRIBUTIONS ##
|
||||
|
||||
## LICENSE ##
|
||||
|
||||
PhoneGap is available under *either* the terms of the modified BSD license *or* the
|
||||
MIT License (2008). As a recipient of PhonegGap, you may choose which
|
||||
license to receive this code under (except as noted in per-module LICENSE
|
||||
files). Some modules may not be the copyright of Nitobi. These
|
||||
modules contain explicit declarations of copyright in both the LICENSE files in
|
||||
the directories in which they reside and in the code itself. No external
|
||||
contributions are allowed under licenses which are fundamentally incompatible
|
||||
with the MIT or BSD licenses that PhoneGap is distributed under.
|
||||
|
||||
The text of the MIT and BSD licenses is reproduced below.
|
||||
|
||||
---
|
||||
|
||||
### The "New" BSD License
|
||||
|
||||
Copyright (c) 2005-2010, Nitobi Software Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Neither the name of Phonegap/Nitobi nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
---
|
||||
|
||||
### The MIT License
|
||||
|
||||
Copyright (c) <2010> <Nitobi Software Inc., et. al., >
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
---
|
||||
|
||||
### libGoogleAnalytics.jar
|
||||
|
||||
The libGoogleAnalytics.jar is distributed under Apache License, Version 2.0.
|
||||
License URL: http://www.apache.org/licenses/LICENSE-2.0
|
||||
libGoogleAnalytics.jar URL: http://code.google.com/p/android-scripting/source/browse/android/AndroidScriptingEnvironment/libs/libGoogleAnalytics.jar?r=41b40b84919bdf461784fd86e6ae464697d2abea
|
||||
41
Android/Analytics/2.0/config.xml
Normal file
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<plugin
|
||||
id = "http://phonegap.com/plugins/Analytics"
|
||||
version = "1.0"
|
||||
platform = "Android"
|
||||
min = "1.9"
|
||||
max = "">
|
||||
|
||||
<name short="Analytics 1.0">
|
||||
Analytics plugin allows you to track page views using Google Analytics framework.
|
||||
</name>
|
||||
|
||||
<description>
|
||||
The analytics client allows you to send page views to Google Analytics server.
|
||||
|
||||
A simple use case would be:
|
||||
|
||||
- Initialize Analytics object with the appropriate Google Analytics account.
|
||||
- Send page views upon user navigation.
|
||||
- Send event data upon user interaction.
|
||||
</description>
|
||||
|
||||
<author href="http://www.worklight.com/" email="asafy@worklight.com">Asaf Yishai</author>
|
||||
<author href="http://broderix.blogspot.com/" email="brody.broderix@gmail.com">Kirill Danilov</author>
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
|
||||
<license>
|
||||
PhoneGap is available under *either* the terms of the modified BSD license *or* the
|
||||
MIT License (2008). As a recipient of PhonegGap, you may choose which
|
||||
license to receive this code under (except as noted in per-module LICENSE
|
||||
files). Some modules may not be the copyright of Nitobi. These
|
||||
modules contain explicit declarations of copyright in both the LICENSE files in
|
||||
the directories in which they reside and in the code itself. No external
|
||||
contributions are allowed under licenses which are fundamentally incompatible
|
||||
with the MIT or BSD licenses that PhoneGap is distributed under.
|
||||
|
||||
The libGoogleAnalytics.jar is distributed under Apache License, Version 2.0.
|
||||
</license>
|
||||
</plugin>
|
||||
53
Android/Analytics/2.0/docs/Analytics.md
Normal file
@@ -0,0 +1,53 @@
|
||||
Analytics
|
||||
==========
|
||||
|
||||
Analytics is an object that allows you to track page views using Google Analytics framework.
|
||||
|
||||
Properties
|
||||
----------
|
||||
|
||||
N/A
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
- start: Initialize Google Analytics with the appropriate Google Analytics account.
|
||||
- trackPageView: Track a page view on Google Analytics.
|
||||
|
||||
|
||||
Supported Platforms
|
||||
-------------------
|
||||
|
||||
- Android
|
||||
|
||||
Quick Example
|
||||
------------------------------
|
||||
|
||||
var onStartSuccess = function() {
|
||||
alert("Google Analytics has started successfully");
|
||||
}
|
||||
|
||||
var onStartFailure = function() {
|
||||
alert("Google Analytics failed to start");
|
||||
}
|
||||
|
||||
var onTrackSuccess = function() {
|
||||
alert("A page view has been successfully sent to Google Analytics.");
|
||||
}
|
||||
|
||||
var onTrackFailure = function() {
|
||||
alert("A page view has failed to be submitted to Google Analytics");
|
||||
}
|
||||
|
||||
var onEventSuccess = function() {
|
||||
alert("An event has been successfully sent to Google Analytics.");
|
||||
}
|
||||
|
||||
var onEventFailure = function() {
|
||||
alert("An event has failed to be submitted to Google Analytics");
|
||||
}
|
||||
|
||||
var myGoogleAnalyticsAccountId = "Your-Account-ID-Here"; // Get your account id from http://www.google.com/analytics/
|
||||
window.plugins.analytics.start(myGoogleAnalyticsAccountId, onStartSuccess, onStartFailure);
|
||||
window.plugins.analytics.trackPageView("page1.html", onTrackSuccess, onTrackFailure);
|
||||
window.plugins.analytics.trackEvent("category", "action", "event", 1, onEventSuccess, onEventFailure);
|
||||
BIN
Android/Analytics/2.0/lib/libGoogleAnalytics.jar
Normal file
3
Android/Analytics/2.0/manifest
Normal file
@@ -0,0 +1,3 @@
|
||||
lib/libGoogleAnalytics.jar
|
||||
src/com/phonegap/plugins/analytics/GoogleAnalyticsTracker.java
|
||||
www/analytics.js
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* PhoneGap is available under *either* the terms of the modified BSD license *or* the
|
||||
* MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
|
||||
*
|
||||
* Copyright (c) 2006-2011 Worklight, Ltd.
|
||||
*/
|
||||
|
||||
package com.phonegap.plugins.analytics;
|
||||
|
||||
import org.apache.cordova.api.Plugin;
|
||||
import org.apache.cordova.api.PluginResult;
|
||||
import org.apache.cordova.api.PluginResult.Status;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
public class GoogleAnalyticsTracker extends Plugin {
|
||||
public static final String START = "start";
|
||||
public static final String TRACK_PAGE_VIEW = "trackPageView";
|
||||
public static final String TRACK_EVENT = "trackEvent";
|
||||
public static final String SET_CUSTOM_VARIABLE = "setCustomVariable";
|
||||
|
||||
public static final int DISPATCH_INTERVAL = 20;
|
||||
private com.google.android.apps.analytics.GoogleAnalyticsTracker tracker;
|
||||
|
||||
public GoogleAnalyticsTracker() {
|
||||
tracker = com.google.android.apps.analytics.GoogleAnalyticsTracker.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PluginResult execute(String action, JSONArray data, String callbackId) {
|
||||
PluginResult result = null;
|
||||
if (START.equals(action)) {
|
||||
try {
|
||||
start(data.getString(0));
|
||||
result = new PluginResult(Status.OK);
|
||||
} catch (JSONException e) {
|
||||
result = new PluginResult(Status.JSON_EXCEPTION);
|
||||
}
|
||||
} else if (TRACK_PAGE_VIEW.equals(action)) {
|
||||
try {
|
||||
trackPageView(data.getString(0));
|
||||
result = new PluginResult(Status.OK);
|
||||
} catch (JSONException e) {
|
||||
result = new PluginResult(Status.JSON_EXCEPTION);
|
||||
}
|
||||
} else if (TRACK_EVENT.equals(action)) {
|
||||
try {
|
||||
trackEvent(data.getString(0), data.getString(1), data.getString(2), data.getInt(3));
|
||||
result = new PluginResult(Status.OK);
|
||||
} catch (JSONException e) {
|
||||
result = new PluginResult(Status.JSON_EXCEPTION);
|
||||
}
|
||||
} else if (SET_CUSTOM_VARIABLE.equals(action)){
|
||||
try {
|
||||
setCustomVar(data.getInt(0), data.getString(1), data.getString(2), data.getInt(3));
|
||||
} catch (JSONException e) {
|
||||
result = new PluginResult(Status.JSON_EXCEPTION);
|
||||
}
|
||||
} else {
|
||||
result = new PluginResult(Status.INVALID_ACTION);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void start(String accountId) {
|
||||
tracker.startNewSession(accountId, DISPATCH_INTERVAL, this.cordova.getActivity());
|
||||
}
|
||||
|
||||
private void trackPageView(String key) {
|
||||
tracker.trackPageView(key);
|
||||
}
|
||||
|
||||
private void trackEvent(String category, String action, String label, int value){
|
||||
tracker.trackEvent(category, action, label, value);
|
||||
}
|
||||
|
||||
private void setCustomVar(int index, String label, String value, int scope) {
|
||||
tracker.setCustomVar(index, label, value, scope);
|
||||
}
|
||||
}
|
||||
95
Android/Analytics/2.0/www/analytics.js
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* PhoneGap is available under *either* the terms of the modified BSD license *or* the
|
||||
* MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
|
||||
*
|
||||
* Copyright (c) 2006-2011 Worklight, Ltd.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
var Analytics = function () {};
|
||||
|
||||
/**
|
||||
* Initialize Google Analytics configuration
|
||||
*
|
||||
* @param accountId The Google Analytics account id
|
||||
* @param successCallback The success callback
|
||||
* @param failureCallback The error callback
|
||||
*/
|
||||
Analytics.prototype.start = function(accountId, successCallback, failureCallback) {
|
||||
return cordova.exec(
|
||||
successCallback,
|
||||
failureCallback,
|
||||
'GoogleAnalyticsTracker',
|
||||
'start',
|
||||
[accountId]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Track a page view on Google Analytics
|
||||
* @param key The name of the tracked item (can be a url or some logical name).
|
||||
* The key name will be presented in Google Analytics report.
|
||||
* @param successCallback The success callback
|
||||
* @param failureCallback The error callback
|
||||
*/
|
||||
Analytics.prototype.trackPageView = function(key, successCallback, failureCallback) {
|
||||
return cordova.exec(
|
||||
successCallback,
|
||||
failureCallback,
|
||||
'GoogleAnalyticsTracker',
|
||||
'trackPageView',
|
||||
[key]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Track an event on Google Analytics
|
||||
* @param category The name that you supply as a way to group objects that you want to track
|
||||
* @param action The name the type of event or interaction you want to track for a particular web object
|
||||
* @param label Provides additional information for events that you want to track (optional)
|
||||
* @param value Assign a numerical value to a tracked page object (optional)
|
||||
|
||||
* @param successCallback The success callback
|
||||
* @param failureCallback The error callback
|
||||
*/
|
||||
|
||||
Analytics.prototype.trackEvent = function(category, action, label, value, successCallback, failureCallback){
|
||||
return cordova.exec(
|
||||
successCallback,
|
||||
failureCallback,
|
||||
'GoogleAnalyticsTracker',
|
||||
'trackEvent',
|
||||
[
|
||||
category,
|
||||
action,
|
||||
typeof label === "undefined" ? "" : label,
|
||||
(isNaN(parseInt(value,10))) ? 0 : parseInt(value, 10)
|
||||
]);
|
||||
};
|
||||
|
||||
Analytics.prototype.setCustomVar = function(index, label, value, scope, successCallback, failureCallback){
|
||||
return cordova.exec(
|
||||
successCallback,
|
||||
failureCallback,
|
||||
'GoogleAnalyticsTracker',
|
||||
'setCustomVariable',
|
||||
[
|
||||
(isNaN(parseInt(index,10))) ? 0 : parseInt(index, 10),
|
||||
label,
|
||||
value,
|
||||
(isNaN(parseInt(scope,10))) ? 0 : parseInt(scope, 10)
|
||||
]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Load Analytics
|
||||
*/
|
||||
|
||||
if(!window.plugins) {
|
||||
window.plugins = {};
|
||||
}
|
||||
|
||||
if (!window.plugins.analytics) {
|
||||
window.plugins.analytics = new Analytics();
|
||||
}
|
||||
170
Android/AppPreferences/2.0.0/README.md
Normal file
@@ -0,0 +1,170 @@
|
||||
# Application Preferences plugin for Phonegap #
|
||||
Originally by Simon MacDonald (@macdonst)
|
||||
|
||||
Please note that the following steps are for PhoneGap 2.0
|
||||
|
||||
Information on writing plugins for PhoneGap 2.0 was taken from [this blog](http://simonmacdonald.blogspot.com/2012/08/so-you-wanna-write-phonegap-200-android.html) by Simon MacDonald (@macdonst)
|
||||
|
||||
## Adding the Plugin to your project ##
|
||||
|
||||
1) To install the plugin, move applicationPreferences.js to your project's www folder and include a reference to it in your html files.
|
||||
|
||||
`<script type="text/javascript" charset="utf-8" src="applicationPreferences.js"></script>`
|
||||
|
||||
2) Create a folder called 'com/simonmacdonald/prefs' within your project's src folder.
|
||||
3) And copy the AppPreferences.java file into that new folder.
|
||||
|
||||
`mkdir <your_project>/src/com/simonmacdonald/prefs`
|
||||
|
||||
`cp ./src/com/simonmacdonald/prefs/AppPreferences.java <your_project>/src/com/simonmacdonald/prefs`
|
||||
|
||||
4) In your `res/xml/config.xml` file add the following element as a child to the `<plugins>` element.
|
||||
|
||||
`<plugin name="applicationPreferences" value="com.simonmacdonald.prefs.AppPreferences"/>`
|
||||
|
||||
## Using the plugin ##
|
||||
|
||||
Create an object to be used to call the defined plugin methods.
|
||||
|
||||
var preferences = cordova.require("cordova/plugin/applicationpreferences");
|
||||
|
||||
The `preferences` object created above will be used in the following examples.
|
||||
|
||||
### get ###
|
||||
|
||||
In order to get the value a property you would call the get method.
|
||||
|
||||
/**
|
||||
* Get the value of the named property.
|
||||
*
|
||||
* @param key
|
||||
*/
|
||||
get(key, success, fail)
|
||||
|
||||
Sample use:
|
||||
|
||||
preferences.get("myKey", function(value) {
|
||||
alert("Value is " + value);
|
||||
}, function(error) {
|
||||
alert("Error! " + JSON.stringify(error));
|
||||
});
|
||||
|
||||
### set ###
|
||||
|
||||
In order to set the value a property you would call the set method.
|
||||
|
||||
/**
|
||||
* Set the value of the named property.
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
set(key, value, success, fail)
|
||||
|
||||
Sample use:
|
||||
|
||||
preferences.set("myKey", "myValue", function() {
|
||||
alert("Successfully saved!");
|
||||
}, function(error) {
|
||||
alert("Error! " + JSON.stringify(error));
|
||||
});
|
||||
|
||||
|
||||
### remove ###
|
||||
|
||||
In order to remove a key along with the value, you would call the remove method.
|
||||
|
||||
/**
|
||||
* Remove the key along with the value
|
||||
*
|
||||
* @param key
|
||||
*/
|
||||
remove(key, success, fail)
|
||||
|
||||
Sample use:
|
||||
|
||||
preferences.remove("myKey", function(value) {
|
||||
alert("Value removed!");
|
||||
}, function(error) {
|
||||
alert("Error! " + JSON.stringify(error));
|
||||
});
|
||||
|
||||
### clear ###
|
||||
|
||||
In order to remove all shared preferences, you would call the clear method.
|
||||
|
||||
/**
|
||||
* Clear all shared preferences
|
||||
*
|
||||
*/
|
||||
clear(success, fail)
|
||||
|
||||
Sample use:
|
||||
|
||||
preferences.clear(function() {
|
||||
alert("Cleared all preferences!");
|
||||
}, function(error) {
|
||||
alert("Error! " + JSON.stringify(error));
|
||||
});
|
||||
|
||||
### load ###
|
||||
|
||||
In order to get all the properties you can call the load method. The success callback of the load method will be called with a JSONObject which contains all the preferences.
|
||||
|
||||
/**
|
||||
* Get all the preference values.
|
||||
*
|
||||
*/
|
||||
load(success, fail)
|
||||
|
||||
Sample use:
|
||||
|
||||
preferences.load(function(prefs) {
|
||||
alert(JSON.stringify(prefs));
|
||||
}, function() {
|
||||
alert("Error! " + JSON.stringify(error));
|
||||
});
|
||||
|
||||
### show ###
|
||||
|
||||
If you want to load the PreferenceActivity of your application that displays all the preferences you can call the show method with the class name.
|
||||
|
||||
/**
|
||||
* Get all the preference values.
|
||||
*
|
||||
*/
|
||||
show(activity, success, fail)
|
||||
|
||||
Sample use:
|
||||
|
||||
function showPreferenceActivity() {
|
||||
preferences.show("com.ranhiru.apppreferences.PreferenceActivity", function() {
|
||||
alert("Showing Preferences Activity!");
|
||||
}, function(error) {
|
||||
alert("Error! " + JSON.stringify(error));
|
||||
});
|
||||
}
|
||||
|
||||
## Licence ##
|
||||
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2012 Simon MacDonald
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
@@ -0,0 +1,39 @@
|
||||
cordova.define("cordova/plugin/applicationpreferences", function(require, exports, module) {
|
||||
var exec = require("cordova/exec");
|
||||
var AppPreferences = function () {};
|
||||
|
||||
var AppPreferencesError = function(code, message) {
|
||||
this.code = code || null;
|
||||
this.message = message || '';
|
||||
};
|
||||
|
||||
AppPreferencesError.NO_PROPERTY = 0;
|
||||
AppPreferencesError.NO_PREFERENCE_ACTIVITY = 1;
|
||||
|
||||
AppPreferences.prototype.get = function(key,success,fail) {
|
||||
cordova.exec(success,fail,"applicationPreferences","get",[key]);
|
||||
};
|
||||
|
||||
AppPreferences.prototype.set = function(key,value,success,fail) {
|
||||
cordova.exec(success,fail,"applicationPreferences","set",[key, value]);
|
||||
};
|
||||
|
||||
AppPreferences.prototype.load = function(success,fail) {
|
||||
cordova.exec(success,fail,"applicationPreferences","load",[]);
|
||||
};
|
||||
|
||||
AppPreferences.prototype.show = function(activity,success,fail) {
|
||||
cordova.exec(success,fail,"applicationPreferences","show",[activity]);
|
||||
};
|
||||
|
||||
AppPreferences.prototype.clear = function(success,fail) {
|
||||
cordova.exec(success,fail,"applicationPreferences","clear", []);
|
||||
};
|
||||
|
||||
AppPreferences.prototype.remove = function(keyToRemove, success,fail) {
|
||||
cordova.exec(success,fail,"applicationPreferences","remove", [keyToRemove]);
|
||||
};
|
||||
|
||||
var appPreferences = new AppPreferences();
|
||||
module.exports = appPreferences;
|
||||
});
|
||||
@@ -0,0 +1,97 @@
|
||||
package com.simonmacdonald.prefs;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.cordova.api.Plugin;
|
||||
import org.apache.cordova.api.PluginResult;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.SharedPreferences.Editor;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.util.Log;
|
||||
|
||||
public class AppPreferences extends Plugin {
|
||||
|
||||
private static final String LOG_TAG = "AppPrefs";
|
||||
private static final int NO_PROPERTY = 0;
|
||||
private static final int NO_PREFERENCE_ACTIVITY = 1;
|
||||
|
||||
@Override
|
||||
public PluginResult execute(String action, JSONArray args, String callbackId) {
|
||||
PluginResult.Status status = PluginResult.Status.OK;
|
||||
String result = "";
|
||||
|
||||
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this.cordova.getActivity());
|
||||
|
||||
try {
|
||||
if (action.equals("get")) {
|
||||
String key = args.getString(0);
|
||||
if (sharedPrefs.contains(key)) {
|
||||
Object obj = sharedPrefs.getAll().get(key);
|
||||
return new PluginResult(status, obj.toString());
|
||||
} else {
|
||||
return createErrorObj(NO_PROPERTY, "No such property called " + key);
|
||||
}
|
||||
} else if (action.equals("set")) {
|
||||
String key = args.getString(0);
|
||||
String value = args.getString(1);
|
||||
Editor editor = sharedPrefs.edit();
|
||||
if ("true".equals(value.toLowerCase()) || "false".equals(value.toLowerCase())) {
|
||||
editor.putBoolean(key, Boolean.parseBoolean(value));
|
||||
} else {
|
||||
editor.putString(key, value);
|
||||
}
|
||||
return new PluginResult(status, editor.commit());
|
||||
} else if (action.equals("load")) {
|
||||
JSONObject obj = new JSONObject();
|
||||
Map prefs = sharedPrefs.getAll();
|
||||
Iterator it = prefs.entrySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
Map.Entry pairs = (Map.Entry)it.next();
|
||||
obj.put(pairs.getKey().toString(), pairs.getValue().toString());
|
||||
}
|
||||
return new PluginResult(status, obj);
|
||||
} else if (action.equals("show")) {
|
||||
String activityName = args.getString(0);
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.setClassName(this.cordova.getActivity(), activityName);
|
||||
try {
|
||||
this.cordova.getActivity().startActivity(intent);
|
||||
} catch (ActivityNotFoundException e) {
|
||||
return createErrorObj(NO_PREFERENCE_ACTIVITY, "No preferences activity called " + activityName);
|
||||
}
|
||||
} else if (action.equals("clear")) {
|
||||
Editor editor = sharedPrefs.edit();
|
||||
editor.clear();
|
||||
return new PluginResult(status, editor.commit());
|
||||
} else if (action.equals("remove")) {
|
||||
String key = args.getString(0);
|
||||
if (sharedPrefs.contains(key)) {
|
||||
Editor editor = sharedPrefs.edit();
|
||||
editor.remove(key);
|
||||
return new PluginResult(status, editor.commit());
|
||||
} else {
|
||||
return createErrorObj(NO_PROPERTY, "No such property called " + key);
|
||||
}
|
||||
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
status = PluginResult.Status.JSON_EXCEPTION;
|
||||
}
|
||||
return new PluginResult(status, result);
|
||||
}
|
||||
|
||||
private PluginResult createErrorObj(int code, String message) throws JSONException {
|
||||
JSONObject errorObj = new JSONObject();
|
||||
errorObj.put("code", code);
|
||||
errorObj.put("message", message);
|
||||
return new PluginResult(PluginResult.Status.ERROR, errorObj);
|
||||
}
|
||||
|
||||
}
|
||||
116
Android/AugmentedReality-Wikitude/Documentation/Documentation.md
Normal file
@@ -0,0 +1,116 @@
|
||||
## Wikitude PhoneGap Plugin Documentation
|
||||
by ``` Wikitude GmbH ```
|
||||
|
||||
|
||||
### DESCRIPTION
|
||||
***
|
||||
|
||||
This document describes all available PhoneGap bindings which exists in the Wikitude PhoneGap Plugin.
|
||||
|
||||
|
||||
#### Getting information about the device
|
||||
|
||||
###### isDeviceSupported
|
||||
Call ``` isDeviceSupported ``` to determinate if the current device is capable of launching ARchitect Worlds.
|
||||
|
||||
@param onSuccessCallback - A callback which gets called if the current device supports launching ARchitect Worlds
|
||||
@param onErrorCallback - An callback which gets called if the current device does not fulfil all needs to lauch ARchitect Worlds
|
||||
@param Plugin name - The name of the plugin you want to call a function
|
||||
@param Plugin function - The name of the function you want to call on the plugin
|
||||
@param options - No options
|
||||
|
||||
cordova.exec(deviceSupportedCallback, deviceNotSupportedCallback, "WikitudePlugin", "isDeviceSupported", [""]);
|
||||
|
||||
|
||||
#### Managing the ARchitectView
|
||||
|
||||
|
||||
###### open
|
||||
Call open to add the ARchitectView to your applications view hierarchy and loads the specified ARchitect World.
|
||||
|
||||
@param onSuccessCallback - A success callback
|
||||
@param onErrorCallback - An error callback
|
||||
@param Plugin name - The name of the plugin you want to call a function
|
||||
@param Plugin function - The name of the function you want to call on the plugin
|
||||
@param options - a dictionary containing two pairs:
|
||||
@pair apiKey : The Wikitude SDK Key provided to you after you purchased the Wikitude SDK or an empty string if you're using a trial version
|
||||
@pair filePath : A filepath to a local bundle resource or to a file on e.g. your dropbox
|
||||
|
||||
cordova.exec(architectWorldLaunchedCallback, architectWorldFailedLaunchingCallback, "WikitudePlugin", "open", [{ apiKey: myApiKey, filePath: worldPath}]);
|
||||
|
||||
###### close
|
||||
This call will remove the ARchitectView from the view hierarchy and also stops all ongoing Wikitude updates.
|
||||
|
||||
@param onSuccessCallback - A success callback
|
||||
@param onErrorCallback - An error callback
|
||||
@param Plugin name - The name of the plugin you want to call a function
|
||||
@param Plugin function - The name of the function you want to call on the plugin
|
||||
@param options - No options
|
||||
|
||||
cordova.exec(onWikitudeOK, onWikitudeError, "WikitudePlugin", "close", [""]);
|
||||
|
||||
###### show
|
||||
This call hides the ARchitectView, but keeps it alive in memory.
|
||||
|
||||
@param onSuccessCallback - A success callback
|
||||
@param onErrorCallback - An error callback
|
||||
@param Plugin name - The name of the plugin you want to call a function
|
||||
@param Plugin function - The name of the function you want to call on the plugin
|
||||
@param options - No options
|
||||
|
||||
cordova.exec(onWikitudeOK, onWikitudeError, "WikitudePlugin", "hide", [""]);
|
||||
|
||||
###### hide
|
||||
This call will show the ARchitectView again if it was hidden with the ``` hide ``` call.
|
||||
|
||||
@param onSuccessCallback - A success callback
|
||||
@param onErrorCallback - An error callback
|
||||
@param Plugin name - The name of the plugin you want to call a function
|
||||
@param Plugin function - The name of the function you want to call on the plugin
|
||||
@param options - No options
|
||||
|
||||
cordova.exec(onWikitudeOK, onWikitudeError, "WikitudePlugin", "show", [""]);
|
||||
|
||||
|
||||
|
||||
#### Interacting with the ARchitectView
|
||||
|
||||
###### callJavaScript
|
||||
This function will evaluate the passed JavaScript in the current ARchitect World context.
|
||||
|
||||
@param onSuccessCallback - A success callback
|
||||
@param onErrorCallback - An error callback
|
||||
@param Plugin name - The name of the plugin you want to call a function
|
||||
@param Plugin function - The name of the function you want to call on the plugin
|
||||
@param options - A JavaScript array with a JavaScript string at first position
|
||||
|
||||
cordova.exec(onWikitudeOK, onWikitudeError, "WikitudePlugin", "callJavascript", [js]);
|
||||
|
||||
###### onUrlInvoke
|
||||
This function will set an callback which gets called if you call ``` document.location = architectsdk://aRequestWithParameters?id=5&name=Poi5 ```.
|
||||
|
||||
@param onSuccessCallback - A callback which gets called every time you call ` architectsdk:// `
|
||||
@param onErrorCallback - An error callback
|
||||
@param Plugin name - The name of the plugin you want to call a function
|
||||
@param Plugin function - The name of the function you want to call on the plugin
|
||||
@param options - No options
|
||||
|
||||
cordova.exec(onUrlInvokeCallback, onWikitudeError, "WikitudePlugin", "onUrlInvoke", [""]);
|
||||
|
||||
###### setLocation
|
||||
This function allows you to set a location for your current ARchitectView
|
||||
|
||||
|
||||
@param onSuccessCallback - A success callback
|
||||
@param onErrorCallback - An error callback
|
||||
@param Plugin name - The name of the plugin you want to call a function
|
||||
@param Plugin function - The name of the function you want to call on the plugin
|
||||
@param options - A dictionary containing the new latitude, longitude, altitude, accuracy
|
||||
@pair lat : The new latitude
|
||||
@pair lon : The new longitude
|
||||
@pair alt : The new altitude
|
||||
@pair acc : The accuracy of the new locations
|
||||
|
||||
cordova.exec(onUrlInvokeCallback, onWikitudeError, "WikitudePlugin", "setLocation", [""]);
|
||||
|
||||
|
||||
110
Android/AugmentedReality-Wikitude/Plugin/README.md
Normal file
@@ -0,0 +1,110 @@
|
||||
# Augmented Reality - Wikitude SDK Plugin
|
||||
by Wikitude GmbH - [www.wikitude.com](http://www.wikitude.com)
|
||||
|
||||
Interested in advanced usage of the plugin and need assistance?
|
||||
[Register as a Wikitude developer](http://developer.wikitude.com) and get support in our forum.
|
||||
|
||||
For further questions visit us on www.wikitude.com or contact us via `phonegap <at> wikitude.com`
|
||||
|
||||
#### Important: This plugin runs on latest [PhoneGap 2.x](http://docs.phonegap.com/en/2.0.0/guide_getting-started_android_index.md.html#Getting%20Started%20with%20Android) only
|
||||
|
||||
|
||||
## DESCRIPTION
|
||||
|
||||
|
||||
The Wikitude PhoneGap Plugin enables web developers to embed an Augmented Reality view into their PhoneGap project. One can create a fully featured app with advanced Augmented Reality features, including Image Recognition, purely using HTML, CSS and Javascript.
|
||||
|
||||
###The Wikitude PhoneGap Plugin
|
||||
|
||||
* Available for iOS and Android
|
||||
* Simple and seamless native PhoneGap integration
|
||||
* Fully customizable Augmented Realty view
|
||||
* Includes the full feature set of the Wikitude SDK
|
||||
* AR content is purely written in HTML and JavaScript
|
||||
|
||||

|
||||
|
||||
###The Augmented Reality View
|
||||
From a technical point of view the SDK adds a UI component, similar to a web view. In contrast to a standard web view this AR view can render Augmented Reality content.
|
||||
|
||||
Note: Content developed for this AR View is written in JavaScript and HTML. The .html and .js files for this view are different from the PhoneGap .js and .html files. The AR engine working in the background is called ARchitect Engine and is powering the SDK.
|
||||
|
||||
###Further developer resources
|
||||
* [Full documentation and additional tutorials](http://forum.wikitude.com/documentation)
|
||||
* [Developer Forum](http://forum.wikitude.com/home)
|
||||
* [Wikitude SDK Download](http://forum.wikitude.com/download)
|
||||
* [Google+ Page for News](https://plus.google.com/u/0/103004921345651739447/posts)
|
||||
* [Developer Newsletter](http://www.wikitude.com/developer/newsletter)
|
||||
|
||||
|
||||
|
||||
##Prerequisites
|
||||
* Having set-up [PhoneGap 2.x](http://docs.phonegap.com/en/2.0.0/guide_getting-
|
||||
started_android_index.md.html#Getting%20Started%20with%20Android) project.
|
||||
* In case you didn't set `<uses-sdk android:minSdkVersion="8"/>` or higher in `AndroidManifest.xml` be aware that the Wikitude SDK runs only on Android 2.2+ devices (=Android SDK v8); you must not call the plugin on devices with lower SDK version.
|
||||
|
||||
## SETUP - 'Basic' Plugin
|
||||
|
||||
|
||||
1. Create a folder called `com/wikitude/phonegap` within your project's `src`- folder and copy `WikitudePlugin.java` into it
|
||||
|
||||
2. Add following line to your `res/xml/config.xml`
|
||||
|
||||
`<plugin name="WikitudePlugin" value="com.wikitude.phonegap.WikitudePlugin"/>`
|
||||
|
||||
3. Copy `WikitudePlugin.js` in `assets/www`-folder and ensure to include it in the related HTMLs.
|
||||
|
||||
|
||||
4. Download the [Wikitude SDK](http://www.wikitude.com), copy the wikitudesdk.jar in the Android-folder to your projects `libs`-folder and add it to your project's build path
|
||||
|
||||
5. Visit [Wikitude Developer Site](http://developer.wikitude.com) to find Samples and license your app to get rid of the watermarking
|
||||
|
||||
|
||||
|
||||
## Optional SETUP - 'Extended' Plugin (incl. Vuforia ImageRecognition)
|
||||
|
||||
####In case you use ImageRecognition in your project, you need to use this Extended Plugin instead of the Basic One.
|
||||
|
||||
Prerequisites: Having already set-up your [PhoneGap 2.x](http://docs.phonegap.com/en/2.0.0/guide_getting-started_android_index.md.html#Getting%20Started%20with%20Android) project.
|
||||
|
||||
1. Create a folder called `com/wikitude/phonegap` within your project's `src/` folder and opy `WikitudePlugin.java` and `WikitudePluginVuforia.java` into it.
|
||||
|
||||
2. Add following line to your `res/xml/config.xml`
|
||||
|
||||
3. Copy `WikitudePlugin.js` in `assets/www`-folder and ensure to include it in the related HTMLs.
|
||||
|
||||
`<plugin name="WikitudePlugin" value="com.wikitude.phonegap.WikitudePluginVuforia"/>`
|
||||
4. Download the [Wikitude SDK](http://www.wikitude.com), copy the wikitudesdk.jar in the Android-folder to your projects `libs`-folder and add it to your project's build path. Also copy the `libExtensionVuforia.so` into `libs/armeabi`
|
||||
|
||||
5. Download Vuforia SDK from [Qualcomm Vuforia Website](https://ar.qualcomm.at/qdevnet/) and copy `QCAR.jar` to your projects `libs`-folder and add it to your project's build. Also copy Vuforia's `libQCAR.so` to your `libs/armeabi`-folder
|
||||
|
||||
6. Visit [Wikitude Developer Site](http://developer.wikitude.com) to find Samples and license your app to get rid of the watermarking
|
||||
|
||||
## JAVASCRIPT INTERFACE
|
||||
|
||||
Its simple to use the Wikitude Plugin within your PhoneGap application.
|
||||
|
||||
We wrapped all ``` cordova.exec ``` calls into a separate JavaScript wrapper which handles location updates and some more functionality behind the scenes.
|
||||
|
||||
You will mainly work with the ``` WikitudePlugin ``` where all you have to do is to call ```Wikitude.isDeviceReady(successCallback, errorCallback)``` and in your successCallback, you can call ```WikitudePlugin.loadARchitectWorld(successCallback, errorCallback, "path/to/your/world")```.
|
||||
|
||||
|
||||
If you have purchased a Wikitude SDK license, you can enter you SDK Key in the ```WikitudePlugin.js``` file at line 9.
|
||||
|
||||
|
||||
## LICENSE
|
||||
|
||||
Copyright 2012 [Wikitude GmbH ](http://www.wikitude.com)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
427
Android/AugmentedReality-Wikitude/Plugin/WikitudePlugin.java
Normal file
@@ -0,0 +1,427 @@
|
||||
package com.wikitude.phonegap;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewGroup.LayoutParams;
|
||||
import android.view.ViewManager;
|
||||
|
||||
import com.phonegap.api.Plugin;
|
||||
import com.phonegap.api.PluginResult;
|
||||
import com.wikitude.architect.ArchitectUrlListener;
|
||||
import com.wikitude.architect.ArchitectView;
|
||||
import com.wikitude.architect.ArchitectView.ArchitectConfig;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Basic PhoneGap Wikitude ARchitect Plugin
|
||||
*
|
||||
* You must add "<plugin name="WikitudePlugin" value="com.wikitude.phonegap.WikitudePlugin"/>"
|
||||
* in config.xml to enable this plug-in in your project
|
||||
*
|
||||
* Also ensure to have wikitudesdk.jar in your libs folder
|
||||
*
|
||||
* Note:
|
||||
* This plug-in is written under Apache License, Version 2.0
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
*
|
||||
* @version 1.0.0
|
||||
* @author Wikitude GmbH; www.wikitude.com
|
||||
*/
|
||||
public class WikitudePlugin extends Plugin implements ArchitectUrlListener {
|
||||
|
||||
/** PhoneGap-root to Android-app-assets folder ; e.g. use "assets/foo.html" as source if you want to load foo.html from your android-project's assets-folder */
|
||||
private static final String LOCAL_ASSETS_PATH_ROOT = "assets/";
|
||||
|
||||
/* various JSON-Object keys*/
|
||||
private static final String JSON_KEY_APIKEY = "sdkKey";
|
||||
private static final String JSON_KEY_FILE_PATH = "filePath";
|
||||
|
||||
private static final String JSON_KEY_LOCATION_ALTITUDE = "alt";
|
||||
private static final String JSON_KEY_LOCATION_ACCURACY = "acc";
|
||||
private static final String JSON_KEY_LOCATION_LATITUDE = "lat";
|
||||
private static final String JSON_KEY_LOCATION_LONGITUDE = "lon";
|
||||
|
||||
/* static action strings */
|
||||
|
||||
/**
|
||||
* opens architect-view (add to view stack)
|
||||
*/
|
||||
private static final String ACTION_OPEN = "open";
|
||||
|
||||
/**
|
||||
* closes architect-view (remove view stack)
|
||||
*/
|
||||
private static final String ACTION_CLOSE = "close";
|
||||
|
||||
/**
|
||||
* set visibility of architectView to visible (of present)
|
||||
*/
|
||||
private static final String ACTION_SHOW = "show";
|
||||
|
||||
/**
|
||||
* set visibility of architectView to invisible (of present)
|
||||
*/
|
||||
private static final String ACTION_HIDE = "hide";
|
||||
|
||||
/**
|
||||
* inject location information
|
||||
*/
|
||||
private static final String ACTION_SET_LOCATION = "setLocation";
|
||||
|
||||
/**
|
||||
* callback for uri-invocations
|
||||
*/
|
||||
private static final String ACTION_ON_URLINVOKE = "onUrlInvoke";
|
||||
|
||||
/**
|
||||
* life-cycle notification for resume
|
||||
*/
|
||||
private static final String ACTION_ON_RESUME = "onResume";
|
||||
|
||||
/**
|
||||
* life-cycle notification for pause
|
||||
*/
|
||||
private static final String ACTION_ON_PAUSE = "onPause";
|
||||
|
||||
/**
|
||||
* check if view is on view-stack (no matter if visible or not)
|
||||
*/
|
||||
private static final String ACTION_STATE_ISOPEN = "isOpen";
|
||||
|
||||
/**
|
||||
* opens architect-view (add to view stack)
|
||||
*/
|
||||
private static final String ACTION_IS_DEVICE_SUPPORTED = "isDeviceSupported";
|
||||
|
||||
/**
|
||||
* check if view is on view-stack (no matter if visible or not)
|
||||
*/
|
||||
private static final String ACTION_CALL_JAVASCRIPT = "callJavascript";
|
||||
|
||||
/**
|
||||
* the Wikitude ARchitectview
|
||||
*/
|
||||
private ArchitectView architectView;
|
||||
|
||||
/**
|
||||
* callback-Id of url-invocation method
|
||||
*/
|
||||
private String urlInvokeCallbackId = null;
|
||||
|
||||
/**
|
||||
* callback-id of "open"-action method
|
||||
*/
|
||||
private String openCallbackId = null;
|
||||
|
||||
@Override
|
||||
public PluginResult execute( final String action, final JSONArray args, final String callbackId ) {
|
||||
|
||||
/* hide architect-view -> destroy and remove from activity */
|
||||
if ( WikitudePlugin.ACTION_CLOSE.equals( action ) ) {
|
||||
if ( this.architectView != null ) {
|
||||
this.cordova.getActivity().runOnUiThread( new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
removeArchitectView();
|
||||
}
|
||||
} );
|
||||
return new PluginResult( PluginResult.Status.OK, action + ": architectView is present" );
|
||||
}
|
||||
else {
|
||||
return new PluginResult( PluginResult.Status.ERROR, action + ": architectView is not present" );
|
||||
}
|
||||
}
|
||||
|
||||
/* return success only if view is opened (no matter if visible or not) */
|
||||
if ( WikitudePlugin.ACTION_STATE_ISOPEN.equals( action ) ) {
|
||||
if ( this.architectView != null ) {
|
||||
return new PluginResult( PluginResult.Status.OK, action + ": architectView is present" );
|
||||
} else {
|
||||
return new PluginResult( PluginResult.Status.ERROR, action + ": architectView is not present" );
|
||||
}
|
||||
}
|
||||
|
||||
/* return success only if view is opened (no matter if visible or not) */
|
||||
if ( WikitudePlugin.ACTION_IS_DEVICE_SUPPORTED.equals( action ) ) {
|
||||
if ( ArchitectView.isDeviceSupported( this.cordova.getActivity() ) ) {
|
||||
return new PluginResult( PluginResult.Status.OK, action + ": this device is ARchitect-ready" );
|
||||
} else {
|
||||
return new PluginResult( PluginResult.Status.ERROR, action + ": Sorry, this device is NOT ARchitect-ready" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* life-cycle's RESUME */
|
||||
if ( WikitudePlugin.ACTION_ON_RESUME.equals( action ) ) {
|
||||
|
||||
if ( this.architectView != null ) {
|
||||
this.cordova.getActivity().runOnUiThread( new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
WikitudePlugin.this.architectView.onResume();
|
||||
}
|
||||
} );
|
||||
|
||||
return new PluginResult( PluginResult.Status.OK, action + ": architectView is present" );
|
||||
}
|
||||
return new PluginResult( PluginResult.Status.ERROR, action + ": architectView is not present" );
|
||||
}
|
||||
|
||||
/* life-cycle's PAUSE */
|
||||
if ( WikitudePlugin.ACTION_ON_PAUSE.equals( action ) ) {
|
||||
if ( architectView != null ) {
|
||||
this.cordova.getActivity().runOnUiThread( new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
WikitudePlugin.this.architectView.onPause();
|
||||
}
|
||||
} );
|
||||
|
||||
return new PluginResult( PluginResult.Status.OK, action + ": architectView is present" );
|
||||
}
|
||||
return new PluginResult( PluginResult.Status.ERROR, action + ": architectView is not present" );
|
||||
}
|
||||
|
||||
/* set visibility to "visible", return error if view is null */
|
||||
if ( WikitudePlugin.ACTION_SHOW.equals( action ) ) {
|
||||
|
||||
if ( this.architectView != null ) {
|
||||
this.architectView.setVisibility( View.VISIBLE );
|
||||
return new PluginResult( PluginResult.Status.OK, action + ": architectView is present" );
|
||||
} else {
|
||||
return new PluginResult( PluginResult.Status.ERROR, action + ": architectView is not present" );
|
||||
}
|
||||
}
|
||||
|
||||
/* set visibility to "invisible", return error if view is null */
|
||||
if ( WikitudePlugin.ACTION_HIDE.equals( action ) ) {
|
||||
|
||||
if ( this.architectView != null ) {
|
||||
this.architectView.setVisibility( View.INVISIBLE );
|
||||
return new PluginResult( PluginResult.Status.OK, action + ": architectView is present" );
|
||||
} else {
|
||||
return new PluginResult( PluginResult.Status.ERROR, action + ": architectView is not present" );
|
||||
}
|
||||
}
|
||||
|
||||
/* define call-back for url-invocations */
|
||||
if ( WikitudePlugin.ACTION_ON_URLINVOKE.equals( action ) ) {
|
||||
this.urlInvokeCallbackId = callbackId;
|
||||
PluginResult result = new PluginResult( PluginResult.Status.NO_RESULT, action + ": registered callback" );
|
||||
result.setKeepCallback( true );
|
||||
return result;
|
||||
}
|
||||
|
||||
/* location update */
|
||||
if ( WikitudePlugin.ACTION_SET_LOCATION.equals( action ) ) {
|
||||
if ( this.architectView != null ) {
|
||||
try {
|
||||
String arrStr = args.getString( 0 );
|
||||
JSONObject arr = new JSONObject( arrStr );
|
||||
final double lat = arr.getDouble( WikitudePlugin.JSON_KEY_LOCATION_LATITUDE );
|
||||
final double lon = arr.getDouble( WikitudePlugin.JSON_KEY_LOCATION_LONGITUDE );
|
||||
Object altObj = arr.get( WikitudePlugin.JSON_KEY_LOCATION_ALTITUDE );
|
||||
float alt = Float.MIN_VALUE;
|
||||
|
||||
if ( altObj != null && altObj instanceof Double ) {
|
||||
alt = ((Double)altObj).floatValue();
|
||||
}
|
||||
|
||||
final float altitude = alt;
|
||||
|
||||
final Double acc = arr.getDouble( WikitudePlugin.JSON_KEY_LOCATION_ACCURACY );
|
||||
if ( this.cordova != null && this.cordova.getActivity() != null ) {
|
||||
this.cordova.getActivity().runOnUiThread( new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if ( acc != null ) {
|
||||
WikitudePlugin.this.architectView.setLocation( lat, lon, altitude, acc.floatValue() );
|
||||
} else {
|
||||
WikitudePlugin.this.architectView.setLocation( lat, lon, altitude );
|
||||
}
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
} catch ( Exception e ) {
|
||||
return new PluginResult( PluginResult.Status.ERROR, action + ": exception thrown, " + e != null ? e.getMessage() : "(exception is NULL)" );
|
||||
}
|
||||
return new PluginResult( PluginResult.Status.OK, action + ": updated location" );
|
||||
}
|
||||
|
||||
/* return error if there is no architect-view active*/
|
||||
return new PluginResult( PluginResult.Status.ERROR, action + ": architectview is not active" );
|
||||
}
|
||||
|
||||
if ( WikitudePlugin.ACTION_CALL_JAVASCRIPT.equals( action ) ) {
|
||||
if ( this.architectView != null ) {
|
||||
String logMsg = null;
|
||||
try {
|
||||
final String callJS = args.getString( 0 );
|
||||
logMsg = callJS;
|
||||
this.cordova.getActivity().runOnUiThread( new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
WikitudePlugin.this.architectView.callJavascript( callJS );
|
||||
}
|
||||
} );
|
||||
|
||||
} catch ( JSONException je ) {
|
||||
return new PluginResult( PluginResult.Status.ERROR, action + ": exception thrown, " + je != null ? je.getMessage() : "(exception is NULL)" );
|
||||
}
|
||||
return new PluginResult( PluginResult.Status.OK, action + ": called js, '" + logMsg + "'" );
|
||||
} else {
|
||||
return new PluginResult( PluginResult.Status.ERROR, action + ": architectview is not active" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* initial set-up, show ArchitectView full-screen in current screen/activity */
|
||||
if ( WikitudePlugin.ACTION_OPEN.equals( action ) ) {
|
||||
this.openCallbackId = callbackId;
|
||||
PluginResult result = null;
|
||||
String arrStr = null;
|
||||
|
||||
try {
|
||||
arrStr = args.getString( 0 );
|
||||
|
||||
// arrStr = arrStr.substring( 1, arrStr.length() - 1 );
|
||||
|
||||
JSONObject arr = new JSONObject( arrStr );
|
||||
|
||||
final String apiKey = arr.getString( WikitudePlugin.JSON_KEY_APIKEY );
|
||||
final String filePath = arr.getString( WikitudePlugin.JSON_KEY_FILE_PATH );
|
||||
|
||||
this.cordova.getActivity().runOnUiThread( new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
WikitudePlugin.this.addArchitectView( apiKey, filePath );
|
||||
|
||||
/* call success method once architectView was added successfully */
|
||||
if ( WikitudePlugin.this.openCallbackId != null ) {
|
||||
PluginResult result = new PluginResult( PluginResult.Status.OK );
|
||||
result.setKeepCallback( false );
|
||||
WikitudePlugin.this.success( result, WikitudePlugin.this.openCallbackId );
|
||||
}
|
||||
} catch ( Exception e ) {
|
||||
/* in case "addArchitectView" threw an exception -> notify callback method asynchronously */
|
||||
WikitudePlugin.this.error( e != null ? e.getMessage() : "Exception is 'null'", WikitudePlugin.this.openCallbackId );
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
} catch ( Exception e ) {
|
||||
result = new PluginResult( PluginResult.Status.ERROR, action + ": exception thown, " + e != null ? e.getMessage() : "(exception is NULL)" );
|
||||
result.setKeepCallback( false );
|
||||
return result;
|
||||
}
|
||||
|
||||
/* adding architect-view is done in separate thread, ensure to setKeepCallback so one can call success-method properly later on */
|
||||
result = new PluginResult( PluginResult.Status.NO_RESULT, action + ": no result required, just registered callback-method" );
|
||||
result.setKeepCallback( true );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* fall-back return value */
|
||||
return new PluginResult( PluginResult.Status.ERROR, "no such action: " + action );
|
||||
}
|
||||
|
||||
/**
|
||||
* called when url was invoked in architectView (by e.g. calling document.location = "myprotocoll://foo";
|
||||
* @param url the invoked url (e.g. "myprotocoll://foo")
|
||||
* @return true if call was handled properly
|
||||
*/
|
||||
@Override
|
||||
public boolean urlWasInvoked( String url ) {
|
||||
|
||||
/* call callback-method if set*/
|
||||
if ( this.urlInvokeCallbackId != null ) {
|
||||
try {
|
||||
/* pass called url as String to callback-method */
|
||||
PluginResult res = new PluginResult( PluginResult.Status.OK, url );
|
||||
res.setKeepCallback( true );
|
||||
this.success( res, this.urlInvokeCallbackId );
|
||||
return true;
|
||||
} catch ( Exception e ) {
|
||||
this.error( "invalid url invoked: " + url, this.urlInvokeCallbackId );
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* hides/removes ARchitect-View completely
|
||||
* @return true if successful, false otherwise
|
||||
*/
|
||||
private boolean removeArchitectView() {
|
||||
if ( this.architectView != null ) {
|
||||
/* fake life-cycle calls, because activity is already up and running */
|
||||
this.architectView.onPause();
|
||||
this.architectView.onDestroy();
|
||||
this.architectView.setVisibility( View.INVISIBLE );
|
||||
((ViewManager)this.architectView.getParent()).removeView( this.architectView );
|
||||
this.architectView = null;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Architect-Configuration required for proper set-up
|
||||
* @param apiKey
|
||||
* @return
|
||||
*/
|
||||
protected ArchitectConfig getArchitectConfig( final String apiKey ) {
|
||||
/* no special set-up required in default Wikitude-Plugin, further things required in advanced usage (e.g. Vuforia Image Recognition) */
|
||||
return new ArchitectConfig( apiKey );
|
||||
}
|
||||
|
||||
/**
|
||||
* add architectView to current screen
|
||||
* @param apiKey developers's api key to use (hides watermarking/intro-animation if it matches your package-name)
|
||||
* @param filePath the url (starting with http:// for online use; starting with LOCAL_ASSETS_PATH_ROOT if oyu want to load assets within your app-assets folder)
|
||||
* @throws IOException might be thrown from ARchitect-SDK
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
private void addArchitectView( final String apiKey, String filePath ) throws IOException {
|
||||
if ( this.architectView == null ) {
|
||||
this.architectView = new ArchitectView( (Activity)this.ctx.getContext() );
|
||||
|
||||
/* add content view and fake initial life-cycle */
|
||||
((Activity)this.ctx.getContext()).addContentView( this.architectView, new ViewGroup.LayoutParams( LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT ) );
|
||||
|
||||
/* fake life-cycle calls, because activity is already up and running */
|
||||
this.architectView.onCreate( getArchitectConfig( apiKey ) );
|
||||
this.architectView.onPostCreate();
|
||||
|
||||
/* register self as url listener to fwd these native calls to PhoneGap */
|
||||
this.architectView.registerUrlListener( WikitudePlugin.this );
|
||||
|
||||
/* load asset from local directory if prefix is used */
|
||||
if ( filePath.startsWith( WikitudePlugin.LOCAL_ASSETS_PATH_ROOT ) ) {
|
||||
filePath = filePath.substring( WikitudePlugin.LOCAL_ASSETS_PATH_ROOT.length() );
|
||||
}
|
||||
this.architectView.load( filePath );
|
||||
|
||||
/* also a fake-life-cycle call (the last one before it is really shown in UI */
|
||||
this.architectView.onResume();
|
||||
}
|
||||
}
|
||||
}
|
||||
383
Android/AugmentedReality-Wikitude/Plugin/WikitudePlugin.js
Normal file
@@ -0,0 +1,383 @@
|
||||
var WikitudePlugin = {
|
||||
|
||||
/**
|
||||
*
|
||||
* This is the SDK Key, provided to you after you purchased the Wikitude SDK from http://www.wikitude.com/developer/sdk
|
||||
* If you're having a trial version, leave this string empty
|
||||
*
|
||||
*/
|
||||
mySDKKey : "ENTER-YOUR-KEY-HERE",
|
||||
|
||||
/** true if architectview is open */
|
||||
isOpened : false,
|
||||
|
||||
/**
|
||||
*
|
||||
* called when user pressed back-button on Android device
|
||||
*
|
||||
*/
|
||||
backButtonCallback : null,
|
||||
|
||||
/**
|
||||
*
|
||||
* Change the value of this variable to modify the location update rate
|
||||
*
|
||||
*/
|
||||
locationUpdateRate : 3000,
|
||||
|
||||
/**
|
||||
*
|
||||
* This variable represents if the current device is capable of running the Wikitude SDK
|
||||
*
|
||||
*/
|
||||
isDeviceSupported : false,
|
||||
|
||||
/**
|
||||
*
|
||||
* This watchID is used to shedule location updates
|
||||
*
|
||||
*/
|
||||
watchID : null,
|
||||
|
||||
/**
|
||||
*
|
||||
* Callbacks to get device information if ARchitect Worlds can be launched
|
||||
*
|
||||
*/
|
||||
onDeviceSupportedCallback : null,
|
||||
onDeviceNotSupportedCallback : null,
|
||||
|
||||
/**
|
||||
*
|
||||
* Callbacks to get notified if the ARchitect World finished launching or if something went wrong during the World launch
|
||||
*
|
||||
*/
|
||||
onARchitectWorldLaunchedCallback : null,
|
||||
onARchitectWorldFailedLaunchingCallback : null,
|
||||
|
||||
/**
|
||||
*
|
||||
* This function gets called if PhoneGap reports that it has finished loading successfully.
|
||||
*
|
||||
*/
|
||||
isDeviceSupported: function(successCallback, errorCallback)
|
||||
{
|
||||
|
||||
WikitudePlugin.onDeviceSupportedCallback = successCallback;
|
||||
WikitudePlugin.onDeviceNotSupportedCallback = errorCallback;
|
||||
|
||||
|
||||
// PhoneGap is running, so the first thing we do is to check if the current device is capable of running the Wikitude Plugin
|
||||
cordova.exec(WikitudePlugin.deviceIsARchitectReady, WikitudePlugin.deviceIsNotARchitectReady, "WikitudePlugin", "isDeviceSupported", [""]);
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* Declare what should happen when user pressed back-button while architect-view is opened.
|
||||
* If not declared/called or null: ARchitect-View is closed
|
||||
*
|
||||
*/
|
||||
onPressedBackButton : function(callback)
|
||||
{
|
||||
WikitudePlugin.backButtonCallback = callback;
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* This function gets called if the Wikitude Plugin reports that the device is able to start the Wikitude SDK
|
||||
*
|
||||
*/
|
||||
deviceIsARchitectReady : function()
|
||||
{
|
||||
// We keep track of the device status
|
||||
WikitudePlugin.isDeviceSupported = true;
|
||||
|
||||
|
||||
if(WikitudePlugin.onDeviceSupportedCallback)
|
||||
{
|
||||
WikitudePlugin.onDeviceSupportedCallback();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* This function gets called if the Wikitude Plugin reports that the device is not able of starting the Wikitude SDK.
|
||||
*
|
||||
*/
|
||||
deviceIsNotARchitectReady : function()
|
||||
{
|
||||
WikitudePlugin.isDeviceSupported = false;
|
||||
|
||||
// In this case we notify the user that his device is not supported by the Wikitude SDK
|
||||
if(WikitudePlugin.onDeviceNotSupportedCallback)
|
||||
{
|
||||
WikitudePlugin.onDeviceNotSupportedCallback();
|
||||
}
|
||||
},
|
||||
|
||||
/*
|
||||
* =============================================================================================================================
|
||||
*
|
||||
* PUBLIC API
|
||||
*
|
||||
* =============================================================================================================================
|
||||
*/
|
||||
|
||||
/* Managing ARchitect world loading */
|
||||
|
||||
/**
|
||||
*
|
||||
* Call this function if you want to load an ARchitect World
|
||||
*
|
||||
* @param {String} worldPath The path to an ARchitect world ether on the device or on e.g. your dropbox
|
||||
*
|
||||
*/
|
||||
loadARchitectWorld : function(worldPath)
|
||||
{
|
||||
|
||||
// before we actually call load, we check again if the device is able to open the world
|
||||
if(WikitudePlugin.isDeviceSupported)
|
||||
{
|
||||
|
||||
// the 'open' function of the Wikitude Plugin requires a option dictionary with two keys:
|
||||
// @param {Object} options (required)
|
||||
// @param {String} options.sdkKey License key for the Wikitude SDK
|
||||
// @param {String} options.filePath The path to a local ARchitect world or to a ARchitect world on a server or your dropbox
|
||||
|
||||
cordova.exec(WikitudePlugin.worldLaunched, WikitudePlugin.worldFailedLaunching, "WikitudePlugin", "open", [{ sdkKey: WikitudePlugin.mySDKKey, filePath: worldPath}]);
|
||||
|
||||
|
||||
// We add an event listener on the resume and pause event of the application lifecycle
|
||||
document.addEventListener("resume", WikitudePlugin.onResume, false);
|
||||
document.addEventListener("pause", WikitudePlugin.onPause, false);
|
||||
|
||||
WikitudePlugin.isOpened = true;
|
||||
document.addEventListener("backbutton", WikitudePlugin.onBackButton, false);
|
||||
|
||||
// After we started loading the world, we start location updates
|
||||
WikitudePlugin.startLocationUpdates();
|
||||
|
||||
}else
|
||||
{
|
||||
// if the device is not able to start the Wikitude SDK, we notify the user again
|
||||
WikitudePlugin.deviceNotARchitectReady();
|
||||
}
|
||||
},
|
||||
|
||||
/* Managing the Wikitude SDK Lifecycle */
|
||||
|
||||
/**
|
||||
*
|
||||
* Use this function to stop the Wikitude SDK and to remove the ARchitectView from the screen
|
||||
*
|
||||
*/
|
||||
close : function()
|
||||
{
|
||||
document.removeEventListener("pause", WikitudePlugin.onPause, false);
|
||||
document.removeEventListener("resume", WikitudePlugin.onResume, false);
|
||||
|
||||
WikitudePlugin.stopLocationUpdates();
|
||||
|
||||
cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "close", [""]);
|
||||
WikitudePlugin.isOpened = false;
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* Use this function to only hide the Wikitude SDK. All location and rendering updates are still active
|
||||
*
|
||||
*/
|
||||
hide : function()
|
||||
{
|
||||
cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "hide", [""]);
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* Use this function to show the Wikitude SDK if it was hidden before
|
||||
*
|
||||
*/
|
||||
show : function()
|
||||
{
|
||||
cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "show", [""]);
|
||||
},
|
||||
|
||||
/* Interacting with the Wikitude SDK */
|
||||
|
||||
/**
|
||||
*
|
||||
* Use this function to call javascript which will be executed in the context of your ARchitect World
|
||||
*
|
||||
*
|
||||
* @param js The JavaScript that gets evaluated in context of the ARchitect World
|
||||
*
|
||||
*/
|
||||
callJavaScript : function(js)
|
||||
{
|
||||
cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "callJavascript", [js]);
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* Use this function to set a callback which will be invoked when the ARchitect World calls for example
|
||||
* document.location = "architectsdk://opendetailpage?id=9";
|
||||
*
|
||||
*
|
||||
* @param onUrlInvokeCallback A function which gets called when the ARchitect World invokes a call to "document.location = architectsdk://"
|
||||
*/
|
||||
setOnUrlInvokeCallback : function(onUrlInvokeCallback)
|
||||
{
|
||||
cordova.exec(onUrlInvokeCallback, WikitudePlugin.onWikitudeError, "WikitudePlugin", "onUrlInvoke", [""]);
|
||||
},
|
||||
|
||||
|
||||
/*
|
||||
* =============================================================================================================================
|
||||
*
|
||||
* Callbacks of public functions
|
||||
*
|
||||
* =============================================================================================================================
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* Use this callback to get notified if the world loaded successfully
|
||||
*
|
||||
*/
|
||||
worldLaunched : function()
|
||||
{
|
||||
if(WikitudePlugin.onARchitectWorldLaunchedCallback)
|
||||
{
|
||||
WikitudePlugin.onARchitectWorldLaunchedCallback();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* Use this callback to get notified if the Wikitude SDK wasn't able to load the ARchitect World
|
||||
*
|
||||
*/
|
||||
worldFailedLaunching : function(err)
|
||||
{
|
||||
if(WikitudePlugin.onARchitectWorldFailedLaunchingCallback)
|
||||
{
|
||||
WikitudePlugin.onARchitectWorldFailedLaunchingCallback(err);
|
||||
}
|
||||
},
|
||||
|
||||
/* Lifecycle updates */
|
||||
|
||||
/**
|
||||
*
|
||||
* This function actually starts the PhoneGap location updates
|
||||
*
|
||||
*/
|
||||
startLocationUpdates : function()
|
||||
{
|
||||
|
||||
WikitudePlugin.watchID = navigator.geolocation.watchPosition(WikitudePlugin.onReceivedLocation, WikitudePlugin.onWikitudeError, { frequency: WikitudePlugin.locationUpdateRate });
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* This callback gets called everytime the location did update
|
||||
*
|
||||
*/
|
||||
onReceivedLocation : function(position)
|
||||
{
|
||||
|
||||
// Every time that PhoneGap did received a location update, we pass the location into the Wikitude SDK
|
||||
cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "setLocation", [{ lat: position.coords.latitude, lon: position.coords.longitude, alt: position.coords.altitude, acc: position.coords.accuracy}]);
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* Use this function to stop location updates
|
||||
*
|
||||
*/
|
||||
stopLocationUpdates : function()
|
||||
{
|
||||
|
||||
// We clear the location update watch which was responsible for updating the location in a specific time interval
|
||||
navigator.geolocation.clearWatch(WikitudePlugin.watchID);
|
||||
WikitudePlugin.watchID = null;
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* This function gets called every time the application did become active.
|
||||
*
|
||||
*/
|
||||
onResume : function()
|
||||
{
|
||||
|
||||
// Call the Wikitude SDK that the application did become active again
|
||||
cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "onResume", [""]);
|
||||
|
||||
// And start continuing updating the user location
|
||||
WikitudePlugin.startLocationUpdates();
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* This function gets called every time the application is about to become inactive
|
||||
*
|
||||
*/
|
||||
onPause : function()
|
||||
{
|
||||
|
||||
// Call the Wikitude SDK that the application did resign active
|
||||
cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "onPause", [""]);
|
||||
|
||||
// And stop all ongoing location updates
|
||||
WikitudePlugin.stopLocationUpdates();
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* Android specific!
|
||||
* This function gets called if the user presses the back button.
|
||||
* You may define your own implementation by using WikitudePlugin.onPressedBackButton(method)
|
||||
*
|
||||
*/
|
||||
onBackButton : function()
|
||||
{
|
||||
if (WikitudePlugin.isOpened) {
|
||||
if (WikitudePlugin.backButtonCallback==null) {
|
||||
WikitudePlugin.close();
|
||||
document.removeEventListener("backbutton", WikitudePlugin.onBackButton, false);
|
||||
} else {
|
||||
WikitudePlugin.backButtonCallback();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* This function gets called every time the application is about to become inactive
|
||||
*
|
||||
*/
|
||||
onWikitudeOK : function()
|
||||
{
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* This function gets called every time the application is about to become inactive
|
||||
*
|
||||
*/
|
||||
onWikitudeError : function()
|
||||
{
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* This function gets called every time the application is about to become inactive
|
||||
*
|
||||
*/
|
||||
report: function(id)
|
||||
{
|
||||
console.log("app report: " + id);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,89 @@
|
||||
package com.wikitude.phonegap;
|
||||
|
||||
import android.app.Activity;
|
||||
|
||||
import com.qualcomm.QCAR.QCAR;
|
||||
import com.wikitude.architect.ArchitectView.ArchitectConfig;
|
||||
import com.wikitude.architect.VuforiaInterface;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Advanced Wikitude ARchitect Plugin (= Basic Plugin + Vuforia Image Recognition feature-set)
|
||||
*
|
||||
* You must add "wikitudesdk.jar" and "QCAR.lib" to your libs folder and build-path and have "libQCAR.so" in project's "libs/armeabi/" directory
|
||||
*
|
||||
* Also add "<plugin name="WikitudePlugin" value="com.wikitude.phonegap.WikitudePluginVuforia"/>"
|
||||
* (replace Basic-plugin entry if necessary)
|
||||
*
|
||||
* in config.xml to enable this plug-in in your project; Ensure your architectSDK key is Vuforia-ready
|
||||
*
|
||||
* Note:
|
||||
* This plug-in is written under Apache License, Version 2.0
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
*
|
||||
* @version 1.0.0
|
||||
* @author Wikitude GmbH; www.wikitude.com
|
||||
*/
|
||||
public class WikitudePluginExtended extends WikitudePlugin {
|
||||
|
||||
|
||||
static {
|
||||
System.loadLibrary( "QCAR" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Architect-Configuration required for proper set-up
|
||||
* @param apiKey
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
protected ArchitectConfig getArchitectConfig( final String apiKey ) {
|
||||
final ArchitectConfig config = super.getArchitectConfig( apiKey );
|
||||
|
||||
/* required for Vuforia */
|
||||
config.setVuforiaInterface( new VuforiaServiceImplementation() );
|
||||
return config;
|
||||
}
|
||||
|
||||
/* required for Vuforia */
|
||||
private class VuforiaServiceImplementation implements VuforiaInterface {
|
||||
|
||||
@Override
|
||||
public void deInit() {
|
||||
QCAR.deinit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int init() {
|
||||
return QCAR.init();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
QCAR.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
QCAR.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSurfaceChanged( final int arg0, final int arg1 ) {
|
||||
QCAR.onSurfaceChanged( arg0, arg1 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSurfaceCreated() {
|
||||
QCAR.onSurfaceCreated();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInitParameters( final Activity activity, final int nFlags ) {
|
||||
QCAR.setInitParameters( activity, nFlags );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="src" path="gen"/>
|
||||
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
|
||||
<classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
|
||||
<classpathentry kind="lib" path="libs/wikitudesdk.jar"/>
|
||||
<classpathentry kind="lib" path="libs/cordova-2.0.0.jar"/>
|
||||
<classpathentry kind="output" path="bin/classes"/>
|
||||
</classpath>
|
||||
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>HelloWorld</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -0,0 +1,67 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.wikitude.phonegapsamplehelloworld"
|
||||
android:versionCode="1"
|
||||
android:versionName="0.9" >
|
||||
|
||||
<uses-sdk android:minSdkVersion="8"/>
|
||||
|
||||
<supports-screens
|
||||
android:largeScreens="true"
|
||||
android:normalScreens="true"
|
||||
android:smallScreens="true"
|
||||
android:resizeable="true"
|
||||
android:anyDensity="true" />
|
||||
|
||||
<!--
|
||||
|
||||
Please check: Wikitude's AR does not need these permissions, maybe you need them anyway
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
<uses-permission android:name="android.permission.RECEIVE_SMS" />
|
||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
|
||||
<uses-permission android:name="android.permission.READ_CONTACTS" />
|
||||
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
|
||||
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
|
||||
<uses-permission android:name="android.permission.BROADCAST_STICKY" />
|
||||
|
||||
-->
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_GPS" />
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
|
||||
|
||||
<!-- AHAU: required hardware components -->
|
||||
<uses-feature android:name="android.hardware.camera" android:required="true" />
|
||||
|
||||
<!-- you need to have a way to find users location -->
|
||||
<uses-feature android:name="android.hardware.location" android:required="true" />
|
||||
|
||||
<!-- you need to have a accelerometer -->
|
||||
<uses-feature android:name="android.hardware.sensor.accelerometer" android:required="true" />
|
||||
|
||||
<!-- you need to have a compass -->
|
||||
<uses-feature android:name="android.hardware.sensor.compass" android:required="true" />
|
||||
|
||||
<application
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:label="@string/app_name" android:debuggable="true">
|
||||
<activity
|
||||
android:name="com.wikitude.phonegap.PhonegapSampleActivity"
|
||||
android:label="@string/app_name" android:configChanges="orientation|keyboardHidden|screenSize">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
@@ -0,0 +1,52 @@
|
||||
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="target-densitydpi=device-dpi, width = 540, user-scalable = 0" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>My ARchitect World</title>
|
||||
|
||||
|
||||
|
||||
<!-- Include the ARchitect library -->
|
||||
<script src="architect://architect.js"></script>
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
var label = null;
|
||||
|
||||
function createLabelAtLocation(geoLocation)
|
||||
{
|
||||
label = new AR.Label("No Text", 2, {onClick : function(){
|
||||
document.location = "architectsdk://didClickedOnLabel?text=HelloWorld";
|
||||
}});
|
||||
|
||||
var geoObject = new AR.GeoObject(geoLocation, {drawables: {cam: label}});
|
||||
}
|
||||
|
||||
function setupScene()
|
||||
{
|
||||
createLabelAtLocation( new AR.RelativeLocation(null, 100, 0, 0) );
|
||||
}
|
||||
|
||||
function didReceivedNewTextForLabel(text)
|
||||
{
|
||||
alert(text + " - text");
|
||||
if(label)
|
||||
{
|
||||
label.text = text;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body onLoad="setupScene()">
|
||||
</body>
|
||||
|
||||
</html>
|
||||
5724
Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/cordova-2.0.0.js
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
html,
|
||||
body {
|
||||
height:100%;
|
||||
font-size:12px;
|
||||
width:100%;
|
||||
}
|
||||
|
||||
html {
|
||||
display:table;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color:#A7A7A7;
|
||||
background-image:linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
|
||||
background-image:-webkit-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
|
||||
background-image:-ms-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
|
||||
background-image:-webkit-gradient(
|
||||
linear,
|
||||
left top,
|
||||
left bottom,
|
||||
color-stop(0, #A7A7A7),
|
||||
color-stop(0.51, #E4E4E4)
|
||||
);
|
||||
display:table-cell;
|
||||
font-family:'HelveticaNeue-Light', 'HelveticaNeue', Helvetica, Arial, sans-serif;
|
||||
text-transform:uppercase;
|
||||
vertical-align:middle;
|
||||
}
|
||||
|
||||
.app {
|
||||
background-image:url(../img/cordova.png);
|
||||
background-repeat:no-repeat;
|
||||
margin:0px auto;
|
||||
width:275px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size:2em;
|
||||
font-weight:300;
|
||||
margin:0px;
|
||||
overflow:visible;
|
||||
padding:0px;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
.status {
|
||||
background-color:#333333;
|
||||
border-radius:4px;
|
||||
-webkit-border-radius:4px;
|
||||
color:#FFFFFF;
|
||||
font-size:1em;
|
||||
margin:0px auto;
|
||||
padding:2px 10px;
|
||||
text-align:center;
|
||||
width:100%;
|
||||
max-width:175px;
|
||||
}
|
||||
|
||||
.status.complete {
|
||||
background-color:#4B946A;
|
||||
}
|
||||
|
||||
.hide {
|
||||
display:none;
|
||||
}
|
||||
|
||||
@keyframes fade {
|
||||
from { opacity: 1.0; }
|
||||
50% { opacity: 0.4; }
|
||||
to { opacity: 1.0; }
|
||||
}
|
||||
|
||||
@-webkit-keyframes fade {
|
||||
from { opacity: 1.0; }
|
||||
50% { opacity: 0.4; }
|
||||
to { opacity: 1.0; }
|
||||
}
|
||||
|
||||
.blink {
|
||||
animation:fade 3000ms infinite;
|
||||
-webkit-animation:fade 3000ms infinite;
|
||||
}
|
||||
|
||||
/* portrait */
|
||||
/* @media screen and (max-aspect-ratio: 1/1) */
|
||||
.app {
|
||||
background-position:center top;
|
||||
height:100px; /* adds enough room for text */
|
||||
padding:180px 0px 0px 0px; /* background height - shadow offset */
|
||||
}
|
||||
|
||||
/* lanscape (when wide enough) */
|
||||
@media screen and (min-aspect-ratio: 1/1) and (min-width:445px) {
|
||||
.app {
|
||||
background-position:left center;
|
||||
height:140px; /* height + padding = background image size */
|
||||
padding-left:170px; /* background width */
|
||||
padding-top:60px; /* center the text */
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 20 KiB |
@@ -0,0 +1,33 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
|
||||
<meta name="viewport" content="width=320; user-scalable=no" />
|
||||
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
|
||||
|
||||
<title>PhoneGap and Wikitude</title>
|
||||
|
||||
<link rel="stylesheet" href="master.css" type="text/css" media="screen" title="no title">
|
||||
|
||||
<script type="text/javascript" charset="utf-8" src="cordova-2.0.0.js"></script>
|
||||
<script type="text/javascript" charset="utf-8" src="js/main.js"></script>
|
||||
<script type="text/javascript" charset="utf-8" src="js/WikitudePlugin.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="css/index.css" />
|
||||
<title>Hello Cordova</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="app">
|
||||
<h1>Apache Cordova™</h1>
|
||||
<div id="deviceready">
|
||||
<p class="status pending blink">Connecting to Device</p>
|
||||
<p class="status complete blink hide">Device is Ready</p>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript" src="cordova-2.0.0.js"></script>
|
||||
<script type="text/javascript" src="js/index.js"></script>
|
||||
<script type="text/javascript" src="js/WikitudePlugin.js"></script>
|
||||
<script type="text/javascript">
|
||||
app.initialize();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,383 @@
|
||||
var WikitudePlugin = {
|
||||
|
||||
/**
|
||||
*
|
||||
* This is the SDK Key, provided to you after you purchased the Wikitude SDK from http://www.wikitude.com/developer/sdk
|
||||
* If you're having a trial version, leave this string empty
|
||||
*
|
||||
*/
|
||||
mySDKKey : "ENTER-YOUR-KEY-HERE",
|
||||
|
||||
/** true if architectview is open */
|
||||
isOpened : false,
|
||||
|
||||
/**
|
||||
*
|
||||
* called when user pressed back-button on Android device
|
||||
*
|
||||
*/
|
||||
backButtonCallback : null,
|
||||
|
||||
/**
|
||||
*
|
||||
* Change the value of this variable to modify the location update rate
|
||||
*
|
||||
*/
|
||||
locationUpdateRate : 3000,
|
||||
|
||||
/**
|
||||
*
|
||||
* This variable represents if the current device is capable of running the Wikitude SDK
|
||||
*
|
||||
*/
|
||||
isDeviceSupported : false,
|
||||
|
||||
/**
|
||||
*
|
||||
* This watchID is used to shedule location updates
|
||||
*
|
||||
*/
|
||||
watchID : null,
|
||||
|
||||
/**
|
||||
*
|
||||
* Callbacks to get device information if ARchitect Worlds can be launched
|
||||
*
|
||||
*/
|
||||
onDeviceSupportedCallback : null,
|
||||
onDeviceNotSupportedCallback : null,
|
||||
|
||||
/**
|
||||
*
|
||||
* Callbacks to get notified if the ARchitect World finished launching or if something went wrong during the World launch
|
||||
*
|
||||
*/
|
||||
onARchitectWorldLaunchedCallback : null,
|
||||
onARchitectWorldFailedLaunchingCallback : null,
|
||||
|
||||
/**
|
||||
*
|
||||
* This function gets called if PhoneGap reports that it has finished loading successfully.
|
||||
*
|
||||
*/
|
||||
isDeviceSupported: function(successCallback, errorCallback)
|
||||
{
|
||||
|
||||
WikitudePlugin.onDeviceSupportedCallback = successCallback;
|
||||
WikitudePlugin.onDeviceNotSupportedCallback = errorCallback;
|
||||
|
||||
|
||||
// PhoneGap is running, so the first thing we do is to check if the current device is capable of running the Wikitude Plugin
|
||||
cordova.exec(WikitudePlugin.deviceIsARchitectReady, WikitudePlugin.deviceIsNotARchitectReady, "WikitudePlugin", "isDeviceSupported", [""]);
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* Declare what should happen when user pressed back-button while architect-view is opened.
|
||||
* If not declared/called or null: ARchitect-View is closed
|
||||
*
|
||||
*/
|
||||
onPressedBackButton : function(callback)
|
||||
{
|
||||
WikitudePlugin.backButtonCallback = callback;
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* This function gets called if the Wikitude Plugin reports that the device is able to start the Wikitude SDK
|
||||
*
|
||||
*/
|
||||
deviceIsARchitectReady : function()
|
||||
{
|
||||
// We keep track of the device status
|
||||
WikitudePlugin.isDeviceSupported = true;
|
||||
|
||||
|
||||
if(WikitudePlugin.onDeviceSupportedCallback)
|
||||
{
|
||||
WikitudePlugin.onDeviceSupportedCallback();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* This function gets called if the Wikitude Plugin reports that the device is not able of starting the Wikitude SDK.
|
||||
*
|
||||
*/
|
||||
deviceIsNotARchitectReady : function()
|
||||
{
|
||||
WikitudePlugin.isDeviceSupported = false;
|
||||
|
||||
// In this case we notify the user that his device is not supported by the Wikitude SDK
|
||||
if(WikitudePlugin.onDeviceNotSupportedCallback)
|
||||
{
|
||||
WikitudePlugin.onDeviceNotSupportedCallback();
|
||||
}
|
||||
},
|
||||
|
||||
/*
|
||||
* =============================================================================================================================
|
||||
*
|
||||
* PUBLIC API
|
||||
*
|
||||
* =============================================================================================================================
|
||||
*/
|
||||
|
||||
/* Managing ARchitect world loading */
|
||||
|
||||
/**
|
||||
*
|
||||
* Call this function if you want to load an ARchitect World
|
||||
*
|
||||
* @param {String} worldPath The path to an ARchitect world ether on the device or on e.g. your dropbox
|
||||
*
|
||||
*/
|
||||
loadARchitectWorld : function(worldPath)
|
||||
{
|
||||
|
||||
// before we actually call load, we check again if the device is able to open the world
|
||||
if(WikitudePlugin.isDeviceSupported)
|
||||
{
|
||||
|
||||
// the 'open' function of the Wikitude Plugin requires a option dictionary with two keys:
|
||||
// @param {Object} options (required)
|
||||
// @param {String} options.sdkKey License key for the Wikitude SDK
|
||||
// @param {String} options.filePath The path to a local ARchitect world or to a ARchitect world on a server or your dropbox
|
||||
|
||||
cordova.exec(WikitudePlugin.worldLaunched, WikitudePlugin.worldFailedLaunching, "WikitudePlugin", "open", [{ sdkKey: WikitudePlugin.mySDKKey, filePath: worldPath}]);
|
||||
|
||||
|
||||
// We add an event listener on the resume and pause event of the application lifecycle
|
||||
document.addEventListener("resume", WikitudePlugin.onResume, false);
|
||||
document.addEventListener("pause", WikitudePlugin.onPause, false);
|
||||
|
||||
WikitudePlugin.isOpened = true;
|
||||
document.addEventListener("backbutton", WikitudePlugin.onBackButton, false);
|
||||
|
||||
// After we started loading the world, we start location updates
|
||||
WikitudePlugin.startLocationUpdates();
|
||||
|
||||
}else
|
||||
{
|
||||
// if the device is not able to start the Wikitude SDK, we notify the user again
|
||||
WikitudePlugin.deviceNotARchitectReady();
|
||||
}
|
||||
},
|
||||
|
||||
/* Managing the Wikitude SDK Lifecycle */
|
||||
|
||||
/**
|
||||
*
|
||||
* Use this function to stop the Wikitude SDK and to remove the ARchitectView from the screen
|
||||
*
|
||||
*/
|
||||
close : function()
|
||||
{
|
||||
document.removeEventListener("pause", WikitudePlugin.onPause, false);
|
||||
document.removeEventListener("resume", WikitudePlugin.onResume, false);
|
||||
|
||||
WikitudePlugin.stopLocationUpdates();
|
||||
|
||||
cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "close", [""]);
|
||||
WikitudePlugin.isOpened = false;
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* Use this function to only hide the Wikitude SDK. All location and rendering updates are still active
|
||||
*
|
||||
*/
|
||||
hide : function()
|
||||
{
|
||||
cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "hide", [""]);
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* Use this function to show the Wikitude SDK if it was hidden before
|
||||
*
|
||||
*/
|
||||
show : function()
|
||||
{
|
||||
cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "show", [""]);
|
||||
},
|
||||
|
||||
/* Interacting with the Wikitude SDK */
|
||||
|
||||
/**
|
||||
*
|
||||
* Use this function to call javascript which will be executed in the context of your ARchitect World
|
||||
*
|
||||
*
|
||||
* @param js The JavaScript that gets evaluated in context of the ARchitect World
|
||||
*
|
||||
*/
|
||||
callJavaScript : function(js)
|
||||
{
|
||||
cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "callJavascript", [js]);
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* Use this function to set a callback which will be invoked when the ARchitect World calls for example
|
||||
* document.location = "architectsdk://opendetailpage?id=9";
|
||||
*
|
||||
*
|
||||
* @param onUrlInvokeCallback A function which gets called when the ARchitect World invokes a call to "document.location = architectsdk://"
|
||||
*/
|
||||
setOnUrlInvokeCallback : function(onUrlInvokeCallback)
|
||||
{
|
||||
cordova.exec(onUrlInvokeCallback, WikitudePlugin.onWikitudeError, "WikitudePlugin", "onUrlInvoke", [""]);
|
||||
},
|
||||
|
||||
|
||||
/*
|
||||
* =============================================================================================================================
|
||||
*
|
||||
* Callbacks of public functions
|
||||
*
|
||||
* =============================================================================================================================
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* Use this callback to get notified if the world loaded successfully
|
||||
*
|
||||
*/
|
||||
worldLaunched : function()
|
||||
{
|
||||
if(WikitudePlugin.onARchitectWorldLaunchedCallback)
|
||||
{
|
||||
WikitudePlugin.onARchitectWorldLaunchedCallback();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* Use this callback to get notified if the Wikitude SDK wasn't able to load the ARchitect World
|
||||
*
|
||||
*/
|
||||
worldFailedLaunching : function(err)
|
||||
{
|
||||
if(WikitudePlugin.onARchitectWorldFailedLaunchingCallback)
|
||||
{
|
||||
WikitudePlugin.onARchitectWorldFailedLaunchingCallback(err);
|
||||
}
|
||||
},
|
||||
|
||||
/* Lifecycle updates */
|
||||
|
||||
/**
|
||||
*
|
||||
* This function actually starts the PhoneGap location updates
|
||||
*
|
||||
*/
|
||||
startLocationUpdates : function()
|
||||
{
|
||||
|
||||
WikitudePlugin.watchID = navigator.geolocation.watchPosition(WikitudePlugin.onReceivedLocation, WikitudePlugin.onWikitudeError, { frequency: WikitudePlugin.locationUpdateRate });
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* This callback gets called everytime the location did update
|
||||
*
|
||||
*/
|
||||
onReceivedLocation : function(position)
|
||||
{
|
||||
|
||||
// Every time that PhoneGap did received a location update, we pass the location into the Wikitude SDK
|
||||
cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "setLocation", [{ lat: position.coords.latitude, lon: position.coords.longitude, alt: position.coords.altitude, acc: position.coords.accuracy}]);
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* Use this function to stop location updates
|
||||
*
|
||||
*/
|
||||
stopLocationUpdates : function()
|
||||
{
|
||||
|
||||
// We clear the location update watch which was responsible for updating the location in a specific time interval
|
||||
navigator.geolocation.clearWatch(WikitudePlugin.watchID);
|
||||
WikitudePlugin.watchID = null;
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* This function gets called every time the application did become active.
|
||||
*
|
||||
*/
|
||||
onResume : function()
|
||||
{
|
||||
|
||||
// Call the Wikitude SDK that the application did become active again
|
||||
cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "onResume", [""]);
|
||||
|
||||
// And start continuing updating the user location
|
||||
WikitudePlugin.startLocationUpdates();
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* This function gets called every time the application is about to become inactive
|
||||
*
|
||||
*/
|
||||
onPause : function()
|
||||
{
|
||||
|
||||
// Call the Wikitude SDK that the application did resign active
|
||||
cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "onPause", [""]);
|
||||
|
||||
// And stop all ongoing location updates
|
||||
WikitudePlugin.stopLocationUpdates();
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* Android specific!
|
||||
* This function gets called if the user presses the back button.
|
||||
* You may define your own implementation by using WikitudePlugin.onPressedBackButton(method)
|
||||
*
|
||||
*/
|
||||
onBackButton : function()
|
||||
{
|
||||
if (WikitudePlugin.isOpened) {
|
||||
if (WikitudePlugin.backButtonCallback==null) {
|
||||
WikitudePlugin.close();
|
||||
document.removeEventListener("backbutton", WikitudePlugin.onBackButton, false);
|
||||
} else {
|
||||
WikitudePlugin.backButtonCallback();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* This function gets called every time the application is about to become inactive
|
||||
*
|
||||
*/
|
||||
onWikitudeOK : function()
|
||||
{
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* This function gets called every time the application is about to become inactive
|
||||
*
|
||||
*/
|
||||
onWikitudeError : function()
|
||||
{
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* This function gets called every time the application is about to become inactive
|
||||
*
|
||||
*/
|
||||
report: function(id)
|
||||
{
|
||||
console.log("app report: " + id);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,116 @@
|
||||
var app = {
|
||||
initialize: function() {
|
||||
this.bind();
|
||||
},
|
||||
bind: function() {
|
||||
document.addEventListener('deviceready', this.deviceready, false);
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* This function extracts an url parameter
|
||||
*
|
||||
*/
|
||||
getUrlParameterForKey : function( url, requestedParam )
|
||||
{
|
||||
requestedParam = requestedParam.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
|
||||
var regexS = "[\\?&]"+requestedParam+"=([^&#]*)";
|
||||
var regex = new RegExp( regexS );
|
||||
var results = regex.exec( url );
|
||||
if( results == null )
|
||||
return "";
|
||||
else
|
||||
{
|
||||
var result = decodeURIComponent(results[1]);
|
||||
return result;
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* This function gets called if you call "document.location = architectsdk://" in your ARchitect World
|
||||
*
|
||||
*
|
||||
* @param url The url which was called in ARchitect World
|
||||
*
|
||||
*/
|
||||
onClickInARchitectWorld : function(url)
|
||||
{
|
||||
|
||||
app.report("you clicked on a label with text: " + app.getUrlParameterForKey(url, 'text'));
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* This function gets called it the Wikitude SDK is able to start an ARchitect World (the current device is supported by the Wikitude SDK)
|
||||
*
|
||||
*/
|
||||
onDeviceIsReadyCallback : function()
|
||||
{
|
||||
// The device is able to launch ARchitect World, so we load the 'Hello World' example
|
||||
WikitudePlugin.loadARchitectWorld("assets/world/HelloWorld.html");
|
||||
|
||||
// To be able to respond on events inside the ARchitect World, we set a onURLInvoke callback
|
||||
WikitudePlugin.setOnUrlInvokeCallback(app.onClickInARchitectWorld);
|
||||
|
||||
// This is a example how you can interact with the ARchitect World to pass in additional information
|
||||
// In this example, a JavaScript function gets called which sets a new text for a label
|
||||
WikitudePlugin.callJavaScript("didReceivedNewTextForLabel('Hello World')");
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* This function gets if the current device is not capable of running ARchitect Worlds
|
||||
*
|
||||
*/
|
||||
onDeviceIsUnsupportedCallback : function()
|
||||
{
|
||||
app.report('device is not supported');
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* This function gets if the ARchitect World finished loading
|
||||
*
|
||||
*/
|
||||
onARchitectWorldLaunchedCallback : function()
|
||||
{
|
||||
app.report('ARchitect World launched');
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* This function gets if the ARchitect failed loading
|
||||
*
|
||||
*/
|
||||
onARchitectWorldFailedLaunchingCallback : function(err)
|
||||
{
|
||||
app.report('ARchitect World failed launching');
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* This function gets called when the Wikitude SDK is ready to start an ARchitect World (the current device is supported by the Wikitude SDK)
|
||||
*
|
||||
*/
|
||||
deviceready: function() {
|
||||
// note that this is an event handler so the scope is that of the event
|
||||
// so we need to call app.report(), and not this.report()
|
||||
app.report('deviceready');
|
||||
|
||||
// When PhoneGap finished loading we forward this event into the Wikitude SDK wrapper.
|
||||
// @param {function} A function which gets called if the device is able to launch ARchitect Worlds
|
||||
// @param {function} A function which gets called if the device is not able to launch ARchitect Worlds
|
||||
WikitudePlugin.isDeviceSupported(app.onDeviceIsReadyCallback, app.onDeviceIsUnsupportedCallback);
|
||||
|
||||
// set a callback on the WikitudePlugin to get informed when the ARchitect World finished loading
|
||||
WikitudePlugin.onARchitectWorldLaunchedCallback = app.onARchitectWorldLaunchedCallback;
|
||||
|
||||
// Set a callback on the WikitudePlugin to get informed when the ARchitect World failed loading
|
||||
WikitudePlugin.onARchitectWorldFailedLaunchingCallback = app.onARchitectWorldFailedLaunchingCallback;
|
||||
},
|
||||
report: function(id) {
|
||||
console.log("report:" + id);
|
||||
}
|
||||
};
|
||||
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 4.0 KiB |
|
After Width: | Height: | Size: 39 KiB |
|
After Width: | Height: | Size: 5.3 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 4.0 KiB |
|
After Width: | Height: | Size: 5.9 KiB |
|
After Width: | Height: | Size: 7.5 KiB |
|
After Width: | Height: | Size: 7.1 KiB |
|
After Width: | Height: | Size: 7.7 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 4.8 KiB |
|
After Width: | Height: | Size: 213 KiB |
|
After Width: | Height: | Size: 217 KiB |
|
After Width: | Height: | Size: 42 KiB |
|
After Width: | Height: | Size: 41 KiB |
|
After Width: | Height: | Size: 90 KiB |
|
After Width: | Height: | Size: 88 KiB |
|
After Width: | Height: | Size: 478 KiB |
|
After Width: | Height: | Size: 493 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 398 KiB |
|
After Width: | Height: | Size: 412 KiB |
|
After Width: | Height: | Size: 1.5 MiB |