mirror of
https://github.com/purplecabbage/phonegap-plugins.git
synced 2026-04-24 03:00:11 -04:00
Merge branch 'master' of https://github.com/phonegap/phonegap-plugins
This commit is contained in:
44
Android/AppBlade/AppBlade.js
Normal file
44
Android/AppBlade/AppBlade.js
Normal file
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* AppBlade.js
|
||||
*
|
||||
* Phonegap AppBlade Instance plugin
|
||||
* Copyright (c) AppBlade 2012
|
||||
*
|
||||
*/
|
||||
|
||||
// --------------------------------------------------------
|
||||
|
||||
var AppBlade = function(){};
|
||||
|
||||
// --------------------------------------------------------
|
||||
|
||||
AppBlade.prototype.setupAppBlade = function(project, token, secret, timestamp) {
|
||||
cordova.exec(null, null, "AppBlade", "setupAppBlade", [project, token, secret, timestamp]);
|
||||
};
|
||||
|
||||
AppBlade.prototype.catchAndReportCrashes = function() {
|
||||
// Automatically set with Register on Android
|
||||
//cordova.exec("AppBlade.catchAndReportCrashes");
|
||||
};
|
||||
|
||||
AppBlade.prototype.checkAuthentication = function() {
|
||||
console.log("Checking authentication");
|
||||
cordova.exec(null, null, "AppBlade", "checkAuthentication", []);
|
||||
};
|
||||
|
||||
AppBlade.prototype.allowFeedbackReporting = function() {
|
||||
// Not supported yet
|
||||
//cordova.exec("AppBlade.allowFeedbackReporting");
|
||||
};
|
||||
|
||||
// --------------------------------------------------------
|
||||
|
||||
cordova.addConstructor(function() {
|
||||
|
||||
if (!window.Cordova) {
|
||||
window.Cordova = cordova;
|
||||
};
|
||||
|
||||
if(!window.plugins) window.plugins = {};
|
||||
window.plugins.appBlade = new AppBlade();
|
||||
});
|
||||
57
Android/AppBlade/AppBladePlugin.java
Normal file
57
Android/AppBlade/AppBladePlugin.java
Normal file
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package com.phonegap.helloworld;
|
||||
|
||||
import org.apache.cordova.api.PluginResult;
|
||||
import org.json.JSONArray;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.phonegap.api.Plugin;
|
||||
|
||||
import android.app.Activity;
|
||||
|
||||
import com.appblade.framework.AppBlade;
|
||||
|
||||
/**
|
||||
* @author micheletitolo
|
||||
*
|
||||
*/
|
||||
public class AppBladePlugin extends Plugin {
|
||||
public static final String SETUP="setupAppBlade";
|
||||
public static final String CHECKAPPROVAL="checkAuthentication";
|
||||
/* (non-Javadoc)
|
||||
* @see org.apache.cordova.api.Plugin#execute(java.lang.String, org.json.JSONArray, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public PluginResult execute(String action, JSONArray data, String callbackId) {
|
||||
PluginResult result = null;
|
||||
if (SETUP.equals(action)) {
|
||||
String token = data.optString(2);
|
||||
String secret = data.optString(1);
|
||||
String uuid = data.optString(0);
|
||||
String issuance = data.optString(3);
|
||||
|
||||
AppBlade.register(this.ctx.getApplicationContext(), token, secret, uuid, issuance);
|
||||
result = new PluginResult(PluginResult.Status.OK);
|
||||
}
|
||||
else if (CHECKAPPROVAL.equals(action))
|
||||
{
|
||||
// PhoneGap runs on its own thread. So we need one to display an alert and do our UI on.
|
||||
this.ctx.runOnUiThread(new Runnable() {
|
||||
|
||||
public void run() {
|
||||
AppBlade.authorize((Activity) AppBladePlugin.this.ctx);
|
||||
}
|
||||
});
|
||||
result = new PluginResult(PluginResult.Status.OK);
|
||||
}
|
||||
else {
|
||||
result = new PluginResult(PluginResult.Status.INVALID_ACTION);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
19
Android/AppBlade/README.md
Normal file
19
Android/AppBlade/README.md
Normal file
@@ -0,0 +1,19 @@
|
||||
AppBladeSDK PhoneGap Plugin
|
||||
===================
|
||||
|
||||
Plugin for PhoneGap that uses the AppBlade SDK.
|
||||
|
||||
##Installation - Android
|
||||
|
||||
1. Copy `AppBlade.js` into your `www` directory.
|
||||
2. Add `AppBladePlugin.java` to your project.
|
||||
3. Follow directions for [adding plugins to your Android project](http://wiki.phonegap.com/w/page/43708611/How%20to%20Install%20a%20PhoneGap%20Plugin%20for%20Android).
|
||||
3. Follow directions for [adding the AppBlade SDK to your project](http://github.com/AppBlade/SDK), but do not do the last 2 steps where you edit your main activity file.
|
||||
3. In your `index.html`, register for the `"deviceready"` eventListener, and call the setup method with your SDK keys in this order: project, token, secret, issued timestamp.
|
||||
|
||||
See the Example project included for examples using the other functions of the SDK.
|
||||
|
||||
|
||||
##Resources:
|
||||
###[AppBlade.com](https://appblade.com/)
|
||||
###[License and Terms](https://appblade.com/terms_of_use)
|
||||
105
Android/AppPreferences/README.md
Normal file
105
Android/AppPreferences/README.md
Normal file
@@ -0,0 +1,105 @@
|
||||
# Application Preferences plugin for Phonegap #
|
||||
Originally 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/plugins.xml file add the following line:
|
||||
|
||||
`<plugin name="applicationPreferences" value="com.simonmacdonald.prefs.AppPreferences"/>`
|
||||
|
||||
## Using the plugin ##
|
||||
The plugin creates the object `window.plugins.applicationPreferences`
|
||||
|
||||
### 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:
|
||||
|
||||
window.plugins.applicationPreference.get("key", success, fail);
|
||||
|
||||
### 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:
|
||||
|
||||
window.plugins.applicationPreference.set("key", "value", success, fail);
|
||||
|
||||
### 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:
|
||||
|
||||
window.plugins.applicationPreference.load(success, fail);
|
||||
|
||||
### 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:
|
||||
|
||||
window.plugins.applicationPreference.show("com.simonmacdonald.prefs.PreferenceActivity", success, fail);
|
||||
|
||||
## 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.
|
||||
29
Android/AppPreferences/assets/www/applicationPreferences.js
Normal file
29
Android/AppPreferences/assets/www/applicationPreferences.js
Normal file
@@ -0,0 +1,29 @@
|
||||
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]);
|
||||
};
|
||||
|
||||
cordova.addConstructor(function() {
|
||||
cordova.addPlugin("applicationPreferences", new AppPreferences());
|
||||
});
|
||||
@@ -0,0 +1,87 @@
|
||||
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.ctx.getContext());
|
||||
|
||||
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);
|
||||
if (sharedPrefs.contains(key)) {
|
||||
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 {
|
||||
return createErrorObj(NO_PROPERTY, "No such property called " + key);
|
||||
}
|
||||
} 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.ctx.getContext(), activityName);
|
||||
try {
|
||||
this.ctx.startActivity(intent);
|
||||
} catch (ActivityNotFoundException e) {
|
||||
return createErrorObj(NO_PREFERENCE_ACTIVITY, "No preferences activity called " + activityName);
|
||||
}
|
||||
}
|
||||
} 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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -44,10 +44,6 @@ versionName is 2.31, 2.4, or 3.0. -->
|
||||
android:configChanges="orientation|keyboardHidden"
|
||||
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
|
||||
android:windowSoftInputMode="stateAlwaysHidden">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="com.google.zxing.client.android.SCAN"/>
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
|
||||
@@ -10,11 +10,13 @@ package com.phonegap.plugins.childBrowser;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.apache.cordova.api.CordovaInterface;
|
||||
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.R;
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
@@ -22,22 +24,25 @@ import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.net.Uri;
|
||||
import android.text.InputType;
|
||||
import android.util.Log;
|
||||
import android.util.TypedValue;
|
||||
import android.view.Gravity;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.view.WindowManager.LayoutParams;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.webkit.WebChromeClient;
|
||||
import android.webkit.WebSettings;
|
||||
import android.webkit.WebView;
|
||||
import android.webkit.WebViewClient;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import com.phonegap.api.PhonegapActivity;
|
||||
import com.phonegap.api.Plugin;
|
||||
import com.phonegap.api.PluginResult;
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
public class ChildBrowser extends Plugin {
|
||||
|
||||
@@ -179,10 +184,11 @@ public class ChildBrowser extends Plugin {
|
||||
InputMethodManager imm = (InputMethodManager)this.ctx.getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
imm.hideSoftInputFromWindow(edittext.getWindowToken(), 0);
|
||||
|
||||
if (!url.startsWith("http")) {
|
||||
this.webview.loadUrl("http://" + url);
|
||||
if (!url.startsWith("http") && !url.startsWith("file:")) {
|
||||
this.webview.loadUrl("http://" + url);
|
||||
} else {
|
||||
this.webview.loadUrl(url);
|
||||
}
|
||||
this.webview.loadUrl(url);
|
||||
this.webview.requestFocus();
|
||||
}
|
||||
|
||||
@@ -210,9 +216,24 @@ public class ChildBrowser extends Plugin {
|
||||
|
||||
// Create dialog in new thread
|
||||
Runnable runnable = new Runnable() {
|
||||
/**
|
||||
* Convert our DIP units to Pixels
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private int dpToPixels(int dipValue) {
|
||||
int value = (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP,
|
||||
(float) dipValue,
|
||||
ctx.getContext().getResources().getDisplayMetrics()
|
||||
);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
dialog = new Dialog(ctx.getContext(), android.R.style.Theme_Translucent_NoTitleBar);
|
||||
|
||||
// Let's create the main dialog
|
||||
dialog = new Dialog(ctx.getContext(), android.R.style.Theme_NoTitleBar);
|
||||
dialog.getWindow().getAttributes().windowAnimations = android.R.style.Animation_Dialog;
|
||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
dialog.setCancelable(true);
|
||||
dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
|
||||
@@ -227,48 +248,73 @@ public class ChildBrowser extends Plugin {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
LinearLayout.LayoutParams backParams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
|
||||
LinearLayout.LayoutParams forwardParams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
|
||||
LinearLayout.LayoutParams editParams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT, 1.0f);
|
||||
LinearLayout.LayoutParams closeParams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
|
||||
LinearLayout.LayoutParams wvParams = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
|
||||
|
||||
// Main container layout
|
||||
LinearLayout main = new LinearLayout(ctx.getContext());
|
||||
main.setOrientation(LinearLayout.VERTICAL);
|
||||
|
||||
LinearLayout toolbar = new LinearLayout(ctx.getContext());
|
||||
toolbar.setOrientation(LinearLayout.HORIZONTAL);
|
||||
// Toolbar layout
|
||||
RelativeLayout toolbar = new RelativeLayout(ctx.getContext());
|
||||
toolbar.setLayoutParams(new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT, this.dpToPixels(44)));
|
||||
toolbar.setPadding(this.dpToPixels(2), this.dpToPixels(2), this.dpToPixels(2), this.dpToPixels(2));
|
||||
toolbar.setHorizontalGravity(Gravity.LEFT);
|
||||
toolbar.setVerticalGravity(Gravity.TOP);
|
||||
|
||||
// Action Button Container layout
|
||||
RelativeLayout actionButtonContainer = new RelativeLayout(ctx.getContext());
|
||||
actionButtonContainer.setLayoutParams(new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
|
||||
actionButtonContainer.setHorizontalGravity(Gravity.LEFT);
|
||||
actionButtonContainer.setVerticalGravity(Gravity.CENTER_VERTICAL);
|
||||
actionButtonContainer.setId(1);
|
||||
|
||||
// Back button
|
||||
ImageButton back = new ImageButton(ctx.getContext());
|
||||
back.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
goBack();
|
||||
}
|
||||
});
|
||||
back.setId(1);
|
||||
RelativeLayout.LayoutParams backLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.FILL_PARENT);
|
||||
backLayoutParams.addRule(RelativeLayout.ALIGN_LEFT);
|
||||
back.setLayoutParams(backLayoutParams);
|
||||
back.setContentDescription("Back Button");
|
||||
back.setId(2);
|
||||
try {
|
||||
back.setImageBitmap(loadDrawable("www/childbrowser/icon_arrow_left.png"));
|
||||
} catch (IOException e) {
|
||||
Log.e(LOG_TAG, e.getMessage(), e);
|
||||
}
|
||||
back.setLayoutParams(backParams);
|
||||
back.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
goBack();
|
||||
}
|
||||
});
|
||||
|
||||
// Forward button
|
||||
ImageButton forward = new ImageButton(ctx.getContext());
|
||||
RelativeLayout.LayoutParams forwardLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.FILL_PARENT);
|
||||
forwardLayoutParams.addRule(RelativeLayout.RIGHT_OF, 2);
|
||||
forward.setLayoutParams(forwardLayoutParams);
|
||||
forward.setContentDescription("Forward Button");
|
||||
forward.setId(3);
|
||||
try {
|
||||
forward.setImageBitmap(loadDrawable("www/childbrowser/icon_arrow_right.png"));
|
||||
} catch (IOException e) {
|
||||
Log.e(LOG_TAG, e.getMessage(), e);
|
||||
}
|
||||
forward.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
goForward();
|
||||
}
|
||||
});
|
||||
forward.setId(2);
|
||||
try {
|
||||
forward.setImageBitmap(loadDrawable("www/childbrowser/icon_arrow_right.png"));
|
||||
} catch (IOException e) {
|
||||
Log.e(LOG_TAG, e.getMessage(), e);
|
||||
}
|
||||
forward.setLayoutParams(forwardParams);
|
||||
|
||||
// Edit Text Box
|
||||
edittext = new EditText(ctx.getContext());
|
||||
RelativeLayout.LayoutParams textLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
|
||||
textLayoutParams.addRule(RelativeLayout.RIGHT_OF, 1);
|
||||
textLayoutParams.addRule(RelativeLayout.LEFT_OF, 5);
|
||||
edittext.setLayoutParams(textLayoutParams);
|
||||
edittext.setId(4);
|
||||
edittext.setSingleLine(true);
|
||||
edittext.setText(url);
|
||||
edittext.setInputType(InputType.TYPE_TEXT_VARIATION_URI);
|
||||
edittext.setImeOptions(EditorInfo.IME_ACTION_GO);
|
||||
edittext.setInputType(InputType.TYPE_NULL); // Will not except input... Makes the text NON-EDITABLE
|
||||
edittext.setOnKeyListener(new View.OnKeyListener() {
|
||||
public boolean onKey(View v, int keyCode, KeyEvent event) {
|
||||
// If the event is a key-down event on the "enter" button
|
||||
@@ -279,46 +325,60 @@ public class ChildBrowser extends Plugin {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
edittext.setId(3);
|
||||
edittext.setSingleLine(true);
|
||||
edittext.setText(url);
|
||||
edittext.setLayoutParams(editParams);
|
||||
|
||||
ImageButton close = new ImageButton((Context) ctx);
|
||||
// Close button
|
||||
ImageButton close = new ImageButton(ctx.getContext());
|
||||
RelativeLayout.LayoutParams closeLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.FILL_PARENT);
|
||||
closeLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
|
||||
close.setLayoutParams(closeLayoutParams);
|
||||
forward.setContentDescription("Close Button");
|
||||
close.setId(5);
|
||||
try {
|
||||
close.setImageBitmap(loadDrawable("www/childbrowser/icon_close.png"));
|
||||
} catch (IOException e) {
|
||||
Log.e(LOG_TAG, e.getMessage(), e);
|
||||
}
|
||||
close.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
closeDialog();
|
||||
}
|
||||
});
|
||||
close.setId(4);
|
||||
try {
|
||||
close.setImageBitmap(loadDrawable("www/childbrowser/icon_close.png"));
|
||||
} catch (IOException e) {
|
||||
Log.e(LOG_TAG, e.getMessage(), e);
|
||||
}
|
||||
close.setLayoutParams(closeParams);
|
||||
|
||||
|
||||
// WebView
|
||||
webview = new WebView(ctx.getContext());
|
||||
webview.getSettings().setJavaScriptEnabled(true);
|
||||
webview.getSettings().setBuiltInZoomControls(true);
|
||||
webview.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
|
||||
webview.setWebChromeClient(new WebChromeClient());
|
||||
WebViewClient client = new ChildBrowserClient(edittext);
|
||||
webview.setWebViewClient(client);
|
||||
webview.setWebViewClient(client);
|
||||
WebSettings settings = webview.getSettings();
|
||||
settings.setJavaScriptEnabled(true);
|
||||
settings.setJavaScriptCanOpenWindowsAutomatically(true);
|
||||
settings.setBuiltInZoomControls(true);
|
||||
settings.setPluginsEnabled(true);
|
||||
settings.setDomStorageEnabled(true);
|
||||
webview.loadUrl(url);
|
||||
webview.setId(5);
|
||||
webview.setInitialScale(0);
|
||||
webview.setLayoutParams(wvParams);
|
||||
webview.setId(6);
|
||||
webview.getSettings().setLoadWithOverviewMode(true);
|
||||
webview.getSettings().setUseWideViewPort(true);
|
||||
webview.requestFocus();
|
||||
webview.requestFocusFromTouch();
|
||||
webview.requestFocusFromTouch();
|
||||
|
||||
// Add the back and forward buttons to our action button container layout
|
||||
actionButtonContainer.addView(back);
|
||||
actionButtonContainer.addView(forward);
|
||||
|
||||
toolbar.addView(back);
|
||||
toolbar.addView(forward);
|
||||
// Add the views to our toolbar
|
||||
toolbar.addView(actionButtonContainer);
|
||||
toolbar.addView(edittext);
|
||||
toolbar.addView(close);
|
||||
|
||||
// Don't add the toolbar if its been disabled
|
||||
if (getShowLocationBar()) {
|
||||
// Add our toolbar to our main view/layout
|
||||
main.addView(toolbar);
|
||||
}
|
||||
|
||||
// Add our webview to our main view/layout
|
||||
main.addView(webview);
|
||||
|
||||
WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
|
||||
@@ -330,11 +390,11 @@ public class ChildBrowser extends Plugin {
|
||||
dialog.show();
|
||||
dialog.getWindow().setAttributes(lp);
|
||||
}
|
||||
|
||||
private Bitmap loadDrawable(String filename) throws java.io.IOException {
|
||||
InputStream input = ctx.getAssets().open(filename);
|
||||
return BitmapFactory.decodeStream(input);
|
||||
}
|
||||
|
||||
private Bitmap loadDrawable(String filename) throws java.io.IOException {
|
||||
InputStream input = ctx.getAssets().open(filename);
|
||||
return BitmapFactory.decodeStream(input);
|
||||
}
|
||||
};
|
||||
this.ctx.runOnUiThread(runnable);
|
||||
return "";
|
||||
@@ -379,7 +439,7 @@ public class ChildBrowser extends Plugin {
|
||||
public void onPageStarted(WebView view, String url, Bitmap favicon) {
|
||||
super.onPageStarted(view, url, favicon);
|
||||
String newloc;
|
||||
if (url.startsWith("http:") || url.startsWith("https:")) {
|
||||
if (url.startsWith("http:") || url.startsWith("https:") || url.startsWith("file:")) {
|
||||
newloc = url;
|
||||
} else {
|
||||
newloc = "http://" + url;
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
3. Copy the .java file into this package
|
||||
4. Update your res/xml/plugins.xml file with the following line:
|
||||
|
||||
<plugin name="DatePickerPlugin" value="com.phonegap.plugin.DatePickerPlugin"/>
|
||||
`<plugin name="DatePickerPlugin" value="com.phonegap.plugin.DatePickerPlugin"/>`
|
||||
|
||||
5. Add a class="nativedatepicker" to your <input> element for which you want the native datepicker
|
||||
6. Add the following jQuery fragment to handle the click on these input elements:
|
||||
|
||||
|
||||
```
|
||||
$('.nativedatepicker').click(function(event) {
|
||||
var currentField = $(this);
|
||||
var myNewDate = Date.parse(currentField.val()) || new Date();
|
||||
@@ -42,5 +42,6 @@
|
||||
currentField.val(newDate.toString("HH:mm"));
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
7. It is recommended to prefil these input fields and make these fields read only with a standard date format, preferably with three letter month so it can always be parsed.
|
||||
262
Android/Diagnostic/README.md
Normal file
262
Android/Diagnostic/README.md
Normal file
@@ -0,0 +1,262 @@
|
||||
# Diagnostic plugin for PhoneGap #
|
||||
|
||||
The diagnostic plugin allows you to check different device settings in your PhoneGap application.
|
||||
|
||||
A simple use case would be:
|
||||
|
||||
- Your app require geolocation and you want check if the location services are enabled in device settings.
|
||||
- Your app require the Wi-Fi enabled for the wireless network location and you want check if the Wi-Fi is enabled in device settings.
|
||||
- Your app require the bluetooth enabled and you want check if the bluetooth is enabled in device settings.
|
||||
- You want that the user enable the location services, Wi-Fi or bluetooth in device settings.
|
||||
|
||||
## Adding the Plugin to your project ##
|
||||
|
||||
Using this plugin requires a PhoneGap project for Android: [Get Started Guide](http://phonegap.com/start#android).
|
||||
|
||||
1. To install the plugin, move _diagnostic.js_ to your project's _www_ folder and include a reference to it in your _html_ file after _cordova.js_:
|
||||
|
||||
<pre>
|
||||
<script type="text/javascript" charset="utf-8" src="cordova-X.X.X.js"></script>
|
||||
<script type="text/javascript" charset="utf-8" src="diagnostic.js"></script>
|
||||
</pre>
|
||||
|
||||
2. Create a directory within your project called _src/net/avantic/diagnosticPlugin_ and move _Diagnostic.java_ into it.
|
||||
3. In your _res/xml/plugins.xml_ file add the following line:
|
||||
|
||||
<pre>
|
||||
<plugin name="Diagnostic" value="net.avantic.diagnosticPlugin.Diagnostic" />
|
||||
</pre>
|
||||
|
||||
4. And in the _AndroidManifest.xml_ add:
|
||||
<pre>
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH" />
|
||||
</pre>
|
||||
|
||||
|
||||
## Using the plugin ##
|
||||
|
||||
The plugin creates the object:
|
||||
|
||||
<pre>
|
||||
window.plugins.diagnostic
|
||||
</pre>
|
||||
To use, call one of the following, available methods:
|
||||
|
||||
|
||||
- isLocationEnabled:
|
||||
|
||||
<pre>
|
||||
/**
|
||||
* Checks device settings for location.
|
||||
*
|
||||
* @param successCallback The callback which will be called when diagnostic of location is successful.
|
||||
* This callback function have a boolean param with the diagnostic result.
|
||||
* @param errorCallback The callback which will be called when diagnostic of location encounters an error.
|
||||
* This callback function have a string param with the error.
|
||||
*/
|
||||
isLocationEnabled()
|
||||
</pre>
|
||||
|
||||
Usage:
|
||||
|
||||
<pre>
|
||||
window.plugins.diagnostic.isLocationEnabled(locationEnabledSuccessCallback, locationEnabledErrorCallback);
|
||||
|
||||
function locationEnabledSuccessCallback(result) {
|
||||
if (result)
|
||||
alert("Location ON");
|
||||
else
|
||||
alert("Location OFF");
|
||||
}
|
||||
|
||||
function locationEnabledErrorCallback(error) {
|
||||
console.log(error);
|
||||
}
|
||||
</pre>
|
||||
|
||||
- switchToLocationSettings:
|
||||
|
||||
<pre>
|
||||
/**
|
||||
* Requests that the user enable the location services in device settings.
|
||||
*/
|
||||
switchToLocationSettings()
|
||||
</pre>
|
||||
|
||||
Usage:
|
||||
|
||||
<pre>
|
||||
alert("You must enable the location services in device settings.");
|
||||
window.plugins.diagnostic.switchToLocationSettings();
|
||||
</pre>
|
||||
|
||||
- isGpsEnabled:
|
||||
|
||||
<pre>
|
||||
/**
|
||||
* Checks device settings for GPS.
|
||||
*
|
||||
* @param successCallback The callback which will be called when diagnostic of GPS is successful.
|
||||
* This callback function have a boolean param with the diagnostic result.
|
||||
* @param errorCallback The callback which will be called when diagnostic of GPS encounters an error.
|
||||
* This callback function have a string param with the error.
|
||||
*/
|
||||
isGpsEnabled()
|
||||
</pre>
|
||||
|
||||
Usage:
|
||||
|
||||
<pre>
|
||||
window.plugins.diagnostic.isGpsEnabled(gpsEnabledSuccessCallback, gpsEnabledErrorCallback);
|
||||
|
||||
function gpsEnabledSuccessCallback(result) {
|
||||
if (result)
|
||||
alert("GPS ON");
|
||||
else
|
||||
alert("GPS OFF");
|
||||
}
|
||||
|
||||
function gpsEnabledErrorCallback(error) {
|
||||
console.log(error);
|
||||
}
|
||||
</pre>
|
||||
|
||||
- isWirelessNetworkLocationEnabled:
|
||||
|
||||
<pre>
|
||||
/**
|
||||
* Checks device settings for wireless network location (Wi-Fi and/or mobile networks).
|
||||
*
|
||||
* @param successCallback The callback which will be called when diagnostic of wireless network location is successful.
|
||||
* This callback function have a boolean param with the diagnostic result.
|
||||
* @param errorCallback The callback which will be called when diagnostic of wireless network location encounters an error.
|
||||
* This callback function have a string param with the error.
|
||||
*/
|
||||
isWirelessNetworkLocationEnabled()
|
||||
</pre>
|
||||
|
||||
Usage:
|
||||
|
||||
<pre>
|
||||
window.plugins.diagnostic.isWirelessNetworkLocationEnabled(wirelessNetworkLocationEnabledSuccessCallback, wirelessNetworkLocationEnabledErrorCallback);
|
||||
|
||||
function wirelessNetworkLocationEnabledSuccessCallback(result) {
|
||||
if (result)
|
||||
alert("Wireless network location ON");
|
||||
else
|
||||
alert("Wireless network location OFF");
|
||||
}
|
||||
|
||||
function wirelessNetworkLocationEnabledErrorCallback(error) {
|
||||
console.log(error);
|
||||
}
|
||||
</pre>
|
||||
|
||||
- isWifiEnabled:
|
||||
|
||||
<pre>
|
||||
/**
|
||||
* Checks device settings for Wi-Fi.
|
||||
*
|
||||
* @param successCallback The callback which will be called when diagnostic of Wi-Fi is successful.
|
||||
* This callback function have a boolean param with the diagnostic result.
|
||||
* @param errorCallback The callback which will be called when diagnostic of Wi-Fi encounters an error.
|
||||
* This callback function have a string param with the error.
|
||||
*/
|
||||
isWifiEnabled()
|
||||
</pre>
|
||||
|
||||
Usage:
|
||||
|
||||
<pre>
|
||||
window.plugins.diagnostic.isWifiEnabled(wifiEnabledSuccessCallback, wifiEnabledErrorCallback);
|
||||
|
||||
function wifiEnabledSuccessCallback(result) {
|
||||
if (result)
|
||||
alert("Wi-Fi ON");
|
||||
else
|
||||
alert("Wi-Fi OFF");
|
||||
}
|
||||
|
||||
function wifiEnabledErrorCallback(error) {
|
||||
console.log(error);
|
||||
}
|
||||
</pre>
|
||||
|
||||
- switchToWifiSettings:
|
||||
|
||||
<pre>
|
||||
/**
|
||||
* Requests that the user enable the Wi-Fi in device settings.
|
||||
*/
|
||||
switchToWifiSettings()
|
||||
</pre>
|
||||
|
||||
Usage:
|
||||
|
||||
<pre>
|
||||
alert("You must enable the Wi-Fi in device settings.");
|
||||
window.plugins.diagnostic.switchToWifiSettings();
|
||||
</pre>
|
||||
|
||||
- isBluetoothEnabled:
|
||||
|
||||
<pre>
|
||||
/**
|
||||
* Checks device settings for bluetooth.
|
||||
*
|
||||
* @param successCallback The callback which will be called when diagnostic of bluetooth is successful.
|
||||
* This callback function have a boolean param with the diagnostic result.
|
||||
* @param errorCallback The callback which will be called when diagnostic of bluetooth encounters an error.
|
||||
* This callback function have a string param with the error.
|
||||
*/
|
||||
isBluetoothEnabled()
|
||||
</pre>
|
||||
|
||||
Usage:
|
||||
|
||||
<pre>
|
||||
window.plugins.diagnostic.isBluetoothEnabled(bluetoothEnabledSuccessCallback, bluetoothEnabledErrorCallback);
|
||||
|
||||
function bluetoothEnabledSuccessCallback(result) {
|
||||
if (result)
|
||||
alert("Bluetooth ON");
|
||||
else
|
||||
alert("Bluetooth OFF");
|
||||
}
|
||||
|
||||
function bluetoothEnabledErrorCallback(error) {
|
||||
console.log(error);
|
||||
}
|
||||
</pre>
|
||||
|
||||
- switchToBluetoothSettings:
|
||||
|
||||
<pre>
|
||||
/**
|
||||
* Requests that the user enable the bluetooth in device settings.
|
||||
*/
|
||||
switchToBluetoothSettings()
|
||||
</pre>
|
||||
|
||||
Usage:
|
||||
|
||||
<pre>
|
||||
alert("You must enable the Bluetooth in device settings.");
|
||||
window.plugins.diagnostic.switchToBluetoothSettings();
|
||||
</pre>
|
||||
|
||||
|
||||
|
||||
## LICENSE ##
|
||||
|
||||
Copyright (c) 2012 AVANTIC ESTUDIO DE INGENIEROS
|
||||
|
||||
The MIT License
|
||||
|
||||
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,150 @@
|
||||
/**
|
||||
* Plugin diagnostic
|
||||
*
|
||||
* Copyright (c) 2012 AVANTIC ESTUDIO DE INGENIEROS
|
||||
*
|
||||
**/
|
||||
|
||||
package net.avantic.diagnosticPlugin;
|
||||
|
||||
import org.apache.cordova.api.PluginResult.Status;
|
||||
import org.json.JSONArray;
|
||||
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.location.LocationManager;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.Looper;
|
||||
import android.provider.Settings;
|
||||
import android.util.Log;
|
||||
|
||||
import com.phonegap.api.Plugin;
|
||||
import com.phonegap.api.PluginResult;
|
||||
|
||||
public class Diagnostic extends Plugin {
|
||||
|
||||
private static final String LOG_TAG = "Diagnostic";
|
||||
|
||||
|
||||
@Override
|
||||
public PluginResult execute(String action, JSONArray args, String callbackId) {
|
||||
Log.d(LOG_TAG, "Executing Diagnostic Plugin");
|
||||
if ("isLocationEnabled".equals(action))
|
||||
return new PluginResult(Status.OK, isLocationEnabled());
|
||||
else if ("switchToLocationSettings".equals(action)) {
|
||||
switchToLocationSettings();
|
||||
return new PluginResult(Status.OK);
|
||||
} else if ("isGpsEnabled".equals(action))
|
||||
return new PluginResult(Status.OK, isGpsEnabled());
|
||||
else if ("isWirelessNetworkLocationEnabled".equals(action))
|
||||
return new PluginResult(Status.OK, isWirelessNetworkLocationEnabled());
|
||||
else if ("isWifiEnabled".equals(action))
|
||||
return new PluginResult(Status.OK, isWifiEnabled());
|
||||
else if ("switchToWifiSettings".equals(action)) {
|
||||
switchToWifiSettings();
|
||||
return new PluginResult(Status.OK);
|
||||
} else if ("isBluetoothEnabled".equals(action))
|
||||
return new PluginResult(Status.OK, isBluetoothEnabled());
|
||||
else if ("switchToBluetoothSettings".equals(action)) {
|
||||
switchToBluetoothSettings();
|
||||
return new PluginResult(Status.OK);
|
||||
} else {
|
||||
Log.d(LOG_TAG, "Invalid action");
|
||||
return new PluginResult(Status.INVALID_ACTION);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check device settings for location.
|
||||
*
|
||||
* @returns {boolean} The status of location services in device settings.
|
||||
*/
|
||||
public boolean isLocationEnabled() {
|
||||
boolean result = (isGpsEnabled() || isWirelessNetworkLocationEnabled());
|
||||
Log.d(LOG_TAG, "Location enabled: " + result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests that the user enable the location in device settings.
|
||||
*/
|
||||
public void switchToLocationSettings() {
|
||||
Log.d(LOG_TAG, "Switch to Location Settings");
|
||||
Intent settingsIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
|
||||
ctx.startActivity(settingsIntent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check device settings for GPS.
|
||||
*
|
||||
* @returns {boolean} The status of GPS in device settings.
|
||||
*/
|
||||
public boolean isGpsEnabled() {
|
||||
boolean result = isLocationProviderEnabled(LocationManager.GPS_PROVIDER);
|
||||
Log.d(LOG_TAG, "GPS enabled: " + result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check device settings for wireless network location (Wi-Fi and/or mobile
|
||||
* networks).
|
||||
*
|
||||
* @returns {boolean} The status of wireless network location in device
|
||||
* settings.
|
||||
*/
|
||||
public boolean isWirelessNetworkLocationEnabled() {
|
||||
boolean result = isLocationProviderEnabled(LocationManager.NETWORK_PROVIDER);
|
||||
Log.d(LOG_TAG, "Wireless Network Location enabled: " + result);
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean isLocationProviderEnabled(String provider) {
|
||||
LocationManager locationManager = (LocationManager) ctx.getSystemService(Context.LOCATION_SERVICE);
|
||||
return locationManager.isProviderEnabled(provider);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check device settings for Wi-Fi.
|
||||
*
|
||||
* @returns {boolean} The status of Wi-Fi in device settings.
|
||||
*/
|
||||
public boolean isWifiEnabled() {
|
||||
WifiManager wifiManager = (WifiManager) ctx.getSystemService(Context.WIFI_SERVICE);
|
||||
boolean result = wifiManager.isWifiEnabled();
|
||||
Log.d(LOG_TAG, "Wifi enabled: " + result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests that the user enable the Wi-Fi in device settings.
|
||||
*/
|
||||
public void switchToWifiSettings() {
|
||||
Log.d(LOG_TAG, "Switch to Wifi Settings");
|
||||
Intent settingsIntent = new Intent(Settings.ACTION_WIFI_SETTINGS);
|
||||
ctx.startActivity(settingsIntent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check device settings for Bluetooth.
|
||||
*
|
||||
* @returns {boolean} The status of Bluetooth in device settings.
|
||||
*/
|
||||
public boolean isBluetoothEnabled() {
|
||||
Looper.prepare();
|
||||
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
|
||||
boolean result = bluetoothAdapter.isEnabled();
|
||||
Log.d(LOG_TAG, "Bluetooth enabled: " + result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests that the user enable the Bluetooth in device settings.
|
||||
*/
|
||||
public void switchToBluetoothSettings() {
|
||||
Log.d(LOG_TAG, "Switch to Bluetooth Settings");
|
||||
Intent settingsIntent = new Intent(Settings.ACTION_BLUETOOTH_SETTINGS);
|
||||
ctx.startActivity(settingsIntent);
|
||||
}
|
||||
}
|
||||
129
Android/Diagnostic/www/diagnostic.js
Normal file
129
Android/Diagnostic/www/diagnostic.js
Normal file
@@ -0,0 +1,129 @@
|
||||
/**
|
||||
* Plugin diagnostic
|
||||
*
|
||||
* Copyright (c) 2012 AVANTIC ESTUDIO DE INGENIEROS
|
||||
*
|
||||
**/
|
||||
|
||||
|
||||
var Diagnostic = function() {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Checks device settings for location.
|
||||
*
|
||||
* @param successCallback The callback which will be called when diagnostic of location is successful.
|
||||
* This callback function have a boolean param with the diagnostic result.
|
||||
* @param errorCallback The callback which will be called when diagnostic of location encounters an error.
|
||||
* This callback function have a string param with the error.
|
||||
*/
|
||||
Diagnostic.prototype.isLocationEnabled = function(successCallback, errorCallback) {
|
||||
return cordova.exec(successCallback,
|
||||
errorCallback,
|
||||
'Diagnostic',
|
||||
'isLocationEnabled',
|
||||
[]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Requests that the user enable the location services in device settings.
|
||||
*/
|
||||
Diagnostic.prototype.switchToLocationSettings = function() {
|
||||
return cordova.exec(null,
|
||||
null,
|
||||
'Diagnostic',
|
||||
'switchToLocationSettings',
|
||||
[]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks device settings for GPS.
|
||||
*
|
||||
* @param successCallback The callback which will be called when diagnostic of GPS is successful.
|
||||
* This callback function have a boolean param with the diagnostic result.
|
||||
* @param errorCallback The callback which will be called when diagnostic of GPS encounters an error.
|
||||
* This callback function have a string param with the error.
|
||||
*/
|
||||
Diagnostic.prototype.isGpsEnabled = function(successCallback, errorCallback) {
|
||||
return cordova.exec(successCallback,
|
||||
errorCallback,
|
||||
'Diagnostic',
|
||||
'isGpsEnabled',
|
||||
[]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks device settings for wireless network location (Wi-Fi and/or mobile networks).
|
||||
*
|
||||
* @param successCallback The callback which will be called when diagnostic of wireless network location is successful.
|
||||
* This callback function have a boolean param with the diagnostic result.
|
||||
* @param errorCallback The callback which will be called when diagnostic of wireless network location encounters an error.
|
||||
* This callback function have a string param with the error.
|
||||
*/
|
||||
Diagnostic.prototype.isWirelessNetworkLocationEnabled = function(successCallback, errorCallback) {
|
||||
return cordova.exec(successCallback,
|
||||
errorCallback,
|
||||
'Diagnostic',
|
||||
'isWirelessNetworkLocationEnabled',
|
||||
[]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks device settings for Wi-Fi.
|
||||
*
|
||||
* @param successCallback The callback which will be called when diagnostic of Wi-Fi is successful.
|
||||
* This callback function have a boolean param with the diagnostic result.
|
||||
* @param errorCallback The callback which will be called when diagnostic of Wi-Fi encounters an error.
|
||||
* This callback function have a string param with the error.
|
||||
*/
|
||||
Diagnostic.prototype.isWifiEnabled = function(successCallback, errorCallback) {
|
||||
return cordova.exec(successCallback,
|
||||
errorCallback,
|
||||
'Diagnostic',
|
||||
'isWifiEnabled',
|
||||
[]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Requests that the user enable the Wi-Fi in device settings.
|
||||
*/
|
||||
Diagnostic.prototype.switchToWifiSettings = function() {
|
||||
return cordova.exec(null,
|
||||
null,
|
||||
'Diagnostic',
|
||||
'switchToWifiSettings',
|
||||
[]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks device settings for bluetooth.
|
||||
*
|
||||
* @param successCallback The callback which will be called when diagnostic of bluetooth is successful.
|
||||
* This callback function have a boolean param with the diagnostic result.
|
||||
* @param errorCallback The callback which will be called when diagnostic of bluetooth encounters an error.
|
||||
* This callback function have a string param with the error.
|
||||
*/
|
||||
Diagnostic.prototype.isBluetoothEnabled = function(successCallback, errorCallback) {
|
||||
return cordova.exec(successCallback,
|
||||
errorCallback,
|
||||
'Diagnostic',
|
||||
'isBluetoothEnabled',
|
||||
[]);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Requests that the user enable the bluetooth in device settings.
|
||||
*/
|
||||
Diagnostic.prototype.switchToBluetoothSettings = function() {
|
||||
return cordova.exec(null,
|
||||
null,
|
||||
'Diagnostic',
|
||||
'switchToBluetoothSettings',
|
||||
[]);
|
||||
};
|
||||
|
||||
cordova.addConstructor(function() {
|
||||
cordova.addPlugin("diagnostic", new Diagnostic());
|
||||
});
|
||||
@@ -1,153 +1,155 @@
|
||||
package com.phonegap.plugins.downloader;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.phonegap.api.Plugin;
|
||||
import com.phonegap.api.PluginResult;
|
||||
|
||||
public class Downloader extends Plugin {
|
||||
|
||||
@Override
|
||||
public PluginResult execute(String action, JSONArray args, String callbackId) {
|
||||
|
||||
if (!action.equals("downloadFile"))
|
||||
return new PluginResult(PluginResult.Status.INVALID_ACTION);
|
||||
|
||||
try {
|
||||
|
||||
String fileUrl = args.getString(0);
|
||||
JSONObject params = args.getJSONObject(1);
|
||||
|
||||
String fileName = params.has("fileName") ?
|
||||
params.getString("fileName"):
|
||||
fileUrl.substring(fileUrl.lastIndexOf("/")+1);
|
||||
|
||||
String dirName = params.has("dirName") ?
|
||||
params.getString("dirName"):
|
||||
"sdcard/download";
|
||||
|
||||
Boolean overwrite = params.has("overwrite") ? params.getBoolean("overwrite") : false;
|
||||
|
||||
return this.downloadUrl(fileUrl, dirName, fileName, overwrite, callbackId);
|
||||
|
||||
} catch (JSONException e) {
|
||||
|
||||
e.printStackTrace();
|
||||
return new PluginResult(PluginResult.Status.JSON_EXCEPTION, e.getMessage());
|
||||
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
return new PluginResult(PluginResult.Status.ERROR, e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private PluginResult downloadUrl(String fileUrl, String dirName, String fileName, Boolean overwrite, String callbackId) throws InterruptedException, JSONException {
|
||||
|
||||
try {
|
||||
|
||||
Log.d("PhoneGapLog", "Downloading "+fileUrl + " into " + dirName + "/" + fileName);
|
||||
|
||||
File dir = new File(dirName);
|
||||
if (!dir.exists()) {
|
||||
Log.d("PhoneGapLog", "directory " + dirName + " created");
|
||||
dir.mkdirs();
|
||||
}
|
||||
|
||||
File file = new File(dirName, fileName);
|
||||
|
||||
if (!overwrite && file.exists()) {
|
||||
Log.d("DownloaderPlugin", "File already exist");
|
||||
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("status", 1);
|
||||
obj.put("total", 0);
|
||||
obj.put("file", fileName);
|
||||
obj.put("progress", 100);
|
||||
|
||||
return new PluginResult(PluginResult.Status.OK, obj);
|
||||
}
|
||||
|
||||
URL url = new URL(fileUrl);
|
||||
HttpURLConnection ucon = (HttpURLConnection) url.openConnection();
|
||||
ucon.setRequestMethod("GET");
|
||||
ucon.setDoOutput(true);
|
||||
ucon.connect();
|
||||
|
||||
Log.d("PhoneGapLog", "Download start");
|
||||
|
||||
InputStream is = ucon.getInputStream();
|
||||
byte[] buffer = new byte[1024];
|
||||
int readed = 0,
|
||||
progress = 0,
|
||||
totalReaded = 0,
|
||||
fileSize = ucon.getContentLength();
|
||||
|
||||
FileOutputStream fos = new FileOutputStream(file);
|
||||
|
||||
while ((readed = is.read(buffer)) > 0) {
|
||||
|
||||
fos.write(buffer, 0, readed);
|
||||
totalReaded += readed;
|
||||
|
||||
int newProgress = (int) (totalReaded*100/fileSize);
|
||||
if (newProgress != progress)
|
||||
progress = informProgress(fileSize, newProgress, fileName, callbackId);
|
||||
|
||||
}
|
||||
|
||||
fos.close();
|
||||
|
||||
Log.d("PhoneGapLog", "Download finished");
|
||||
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("status", 1);
|
||||
obj.put("total", fileSize);
|
||||
obj.put("file", fileName);
|
||||
obj.put("progress", progress);
|
||||
|
||||
return new PluginResult(PluginResult.Status.OK, obj);
|
||||
|
||||
}
|
||||
catch (FileNotFoundException e) {
|
||||
Log.d("PhoneGapLog", "File Not Found: " + e);
|
||||
return new PluginResult(PluginResult.Status.ERROR, 404);
|
||||
}
|
||||
catch (IOException e) {
|
||||
Log.d("PhoneGapLog", "Error: " + e);
|
||||
return new PluginResult(PluginResult.Status.ERROR, e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private int informProgress(int fileSize, int progress, String fileName, String callbackId) throws InterruptedException, JSONException {
|
||||
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("status", 0);
|
||||
obj.put("total", fileSize);
|
||||
obj.put("file", fileName);
|
||||
obj.put("progress", progress);
|
||||
|
||||
PluginResult res = new PluginResult(PluginResult.Status.OK, obj);
|
||||
res.setKeepCallback(true);
|
||||
success(res, callbackId);
|
||||
|
||||
//Give a chance for the progress to be sent to javascript
|
||||
Thread.sleep(100);
|
||||
|
||||
return progress;
|
||||
}
|
||||
|
||||
package com.phonegap.plugins.downloader;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.phonegap.api.Plugin;
|
||||
import com.phonegap.api.PluginResult;
|
||||
|
||||
public class Downloader extends Plugin {
|
||||
|
||||
@Override
|
||||
public PluginResult execute(String action, JSONArray args, String callbackId) {
|
||||
|
||||
if (!action.equals("downloadFile"))
|
||||
return new PluginResult(PluginResult.Status.INVALID_ACTION);
|
||||
|
||||
try {
|
||||
|
||||
String fileUrl = args.getString(0);
|
||||
JSONObject params = args.getJSONObject(1);
|
||||
|
||||
String fileName = params.has("fileName") ?
|
||||
params.getString("fileName"):
|
||||
fileUrl.substring(fileUrl.lastIndexOf("/")+1);
|
||||
|
||||
String dirName = params.has("dirName") ?
|
||||
params.getString("dirName"):
|
||||
Environment.getExternalStorageDirectory().getPath() + "/download";
|
||||
|
||||
Boolean overwrite = params.has("overwrite") ? params.getBoolean("overwrite") : false;
|
||||
|
||||
return this.downloadUrl(fileUrl, dirName, fileName, overwrite, callbackId);
|
||||
|
||||
} catch (JSONException e) {
|
||||
|
||||
e.printStackTrace();
|
||||
return new PluginResult(PluginResult.Status.JSON_EXCEPTION, e.getMessage());
|
||||
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
return new PluginResult(PluginResult.Status.ERROR, e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private PluginResult downloadUrl(String fileUrl, String dirName, String fileName, Boolean overwrite, String callbackId) throws InterruptedException, JSONException {
|
||||
|
||||
try {
|
||||
|
||||
Log.d("PhoneGapLog", "Downloading "+fileUrl + " into " + dirName + "/" + fileName);
|
||||
|
||||
File dir = new File(dirName);
|
||||
if (!dir.exists()) {
|
||||
Log.d("PhoneGapLog", "directory " + dirName + " created");
|
||||
dir.mkdirs();
|
||||
}
|
||||
|
||||
File file = new File(dirName, fileName);
|
||||
|
||||
if (!overwrite && file.exists()) {
|
||||
Log.d("DownloaderPlugin", "File already exist");
|
||||
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("status", 1);
|
||||
obj.put("total", 0);
|
||||
obj.put("file", fileName);
|
||||
obj.put("dir", dirName);
|
||||
obj.put("progress", 100);
|
||||
|
||||
return new PluginResult(PluginResult.Status.OK, obj);
|
||||
}
|
||||
|
||||
URL url = new URL(fileUrl);
|
||||
HttpURLConnection ucon = (HttpURLConnection) url.openConnection();
|
||||
ucon.setRequestMethod("GET");
|
||||
ucon.setDoOutput(true);
|
||||
ucon.connect();
|
||||
|
||||
Log.d("PhoneGapLog", "Download start");
|
||||
|
||||
InputStream is = ucon.getInputStream();
|
||||
byte[] buffer = new byte[1024];
|
||||
int readed = 0,
|
||||
progress = 0,
|
||||
totalReaded = 0,
|
||||
fileSize = ucon.getContentLength();
|
||||
|
||||
FileOutputStream fos = new FileOutputStream(file);
|
||||
|
||||
while ((readed = is.read(buffer)) > 0) {
|
||||
|
||||
fos.write(buffer, 0, readed);
|
||||
totalReaded += readed;
|
||||
|
||||
int newProgress = (int) (totalReaded*100/fileSize);
|
||||
if (newProgress != progress)
|
||||
progress = informProgress(fileSize, newProgress, dirName, fileName, callbackId);
|
||||
|
||||
}
|
||||
|
||||
fos.close();
|
||||
|
||||
Log.d("PhoneGapLog", "Download finished");
|
||||
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("status", 1);
|
||||
obj.put("total", fileSize);
|
||||
obj.put("file", fileName);
|
||||
obj.put("progress", progress);
|
||||
|
||||
return new PluginResult(PluginResult.Status.OK, obj);
|
||||
|
||||
}
|
||||
catch (FileNotFoundException e) {
|
||||
Log.d("PhoneGapLog", "File Not Found: " + e);
|
||||
return new PluginResult(PluginResult.Status.ERROR, 404);
|
||||
}
|
||||
catch (IOException e) {
|
||||
Log.d("PhoneGapLog", "Error: " + e);
|
||||
return new PluginResult(PluginResult.Status.ERROR, e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private int informProgress(int fileSize, int progress, String dirName, String fileName, String callbackId) throws InterruptedException, JSONException {
|
||||
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("status", 0);
|
||||
obj.put("total", fileSize);
|
||||
obj.put("file", fileName);
|
||||
obj.put("dir", dirName);
|
||||
obj.put("progress", progress);
|
||||
|
||||
PluginResult res = new PluginResult(PluginResult.Status.OK, obj);
|
||||
res.setKeepCallback(true);
|
||||
success(res, callbackId);
|
||||
|
||||
//Give a chance for the progress to be sent to javascript
|
||||
Thread.sleep(100);
|
||||
|
||||
return progress;
|
||||
}
|
||||
|
||||
}
|
||||
31
Android/MacAddress/MacAddress.js
Normal file
31
Android/MacAddress/MacAddress.js
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* MacAddress
|
||||
* Implements the javascript access to the cordova plugin for retrieving the device mac address. Returns 0 if not running on Android
|
||||
* @author Olivier Brand
|
||||
*/
|
||||
|
||||
/**
|
||||
* @return the mac address class instance
|
||||
*/
|
||||
var MacAddress = function() {
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the mac address of the device. Return a 00:00:00:00:00:00 for
|
||||
* emulator based runtime or just PC web
|
||||
*
|
||||
* @param successCallback
|
||||
* The callback which will be called when directory listing is
|
||||
* successful
|
||||
* @param failureCallback
|
||||
* The callback which will be called when directory listing encouters
|
||||
* an error
|
||||
*/
|
||||
MacAddress.prototype.getMacAddress = function(successCallback, failureCallback) {
|
||||
return cordova.exec(successCallback, failureCallback, 'MacAddress',
|
||||
'getMacAddress', [], false);
|
||||
};
|
||||
|
||||
cordova.addConstructor(function() {
|
||||
cordova.addPlugin('macaddress', new MacAddress());
|
||||
});
|
||||
69
Android/MacAddress/MacAddressPlugin.java
Normal file
69
Android/MacAddress/MacAddressPlugin.java
Normal file
@@ -0,0 +1,69 @@
|
||||
package com.phonegap.plugin.macaddress;
|
||||
|
||||
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.Context;
|
||||
import android.net.wifi.WifiManager;
|
||||
|
||||
/**
|
||||
* The Class MacAddressPlugin.
|
||||
*/
|
||||
public class MacAddressPlugin extends Plugin {
|
||||
|
||||
@Override
|
||||
public boolean isSynch(String action) {
|
||||
if (action.equals("getMacAddress")) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.apache.cordova.api.Plugin#execute(java.lang.String, org.json.JSONArray, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public PluginResult execute(String action, JSONArray args, String callbackId) {
|
||||
PluginResult result = null;
|
||||
|
||||
|
||||
if (action.equals("getMacAddress")) {
|
||||
|
||||
String macAddress = this.getMacAddress();
|
||||
|
||||
if (macAddress != null) {
|
||||
JSONObject JSONresult = new JSONObject();
|
||||
try {
|
||||
JSONresult.put("mac", macAddress);
|
||||
result = new PluginResult(PluginResult.Status.OK, JSONresult);
|
||||
} catch (JSONException jsonEx) {
|
||||
|
||||
result = new PluginResult(PluginResult.Status.JSON_EXCEPTION);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the mac address.
|
||||
*
|
||||
* @return the mac address
|
||||
*/
|
||||
private String getMacAddress() {
|
||||
String macAddress = null;
|
||||
WifiManager wm = (WifiManager) this.ctx.getSystemService(Context.WIFI_SERVICE);
|
||||
macAddress = wm.getConnectionInfo().getMacAddress();
|
||||
|
||||
if (macAddress == null || macAddress.length() == 0) {
|
||||
macAddress = "00:00:00:00:00:00";
|
||||
}
|
||||
|
||||
return macAddress;
|
||||
}
|
||||
}
|
||||
40
Android/MacAddress/README.md
Normal file
40
Android/MacAddress/README.md
Normal file
@@ -0,0 +1,40 @@
|
||||
# MacAddress plugin for Phonegap (Android) #
|
||||
By Olivier Brand
|
||||
|
||||
## Adding the Plugin to your project ##
|
||||
1. To install the plugin, move `MacAddress.js` to your project's www folder and include a reference to it
|
||||
in your html files.
|
||||
|
||||
<script src="MacAddress.js"></script>
|
||||
|
||||
2. Create a folder called 'com/phonegap/plugin/macaddress' within your project's src folder.
|
||||
3. And copy the java file into that new folder.
|
||||
|
||||
|
||||
<pre>
|
||||
mkdir -p <your_project>/src/com/phonegap/plugin/macaddress
|
||||
cp ./ResourcesPlugin.java <your_project>/src/com/phonegap/plugin/macaddress
|
||||
</pre>
|
||||
|
||||
4. Set the permissions into the Android Manifest for accessing the mac address.
|
||||
|
||||
<pre>
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||
</pre>
|
||||
|
||||
5. Add a plugin line to `res/xml/plugins.xml`
|
||||
|
||||
<plugin name="MacAddress" value="com.phonegap.plugin.macaddress.MacAddressPlugin" />
|
||||
|
||||
## Using the plugin ##
|
||||
|
||||
<pre>
|
||||
|
||||
var networkInterface = {};
|
||||
// Get network interface
|
||||
networkInterface = window.plugins.macaddress.getMacAddress();
|
||||
|
||||
|
||||
console.log(networkInterface.mac);
|
||||
|
||||
</pre>
|
||||
36
Android/RemoteSound/README.md
Normal file
36
Android/RemoteSound/README.md
Normal file
@@ -0,0 +1,36 @@
|
||||
# RemoteSound plugin for Phonegap (Android) #
|
||||
By Olivier Brand
|
||||
|
||||
## Adding the Plugin to your project ##
|
||||
1. To install the plugin, move `RemoteSound.js` to your project's www folder and include a reference to it
|
||||
in your html files.
|
||||
|
||||
<script src="RemoteSound.js"></script>
|
||||
|
||||
2. Create a folder called 'com/phonegap/plugin/remotesound' within your project's src folder.
|
||||
3. And copy the java file into that new folder.
|
||||
|
||||
<pre>
|
||||
mkdir -p <your_project>/src/com/phonegap/plugin/remotesound
|
||||
cp ./RemoteSoundPlugin.java <your_project>/src/com/phonegap/plugin/remotesound
|
||||
</pre>
|
||||
|
||||
4. Add a plugin line to `res/xml/plugins.xml`
|
||||
|
||||
<plugin name="RemoteSound" value="com.phonegap.plugin.remotesound.RemoteSoundPlugin" />
|
||||
|
||||
## Using the plugin ##
|
||||
|
||||
<pre>
|
||||
|
||||
<!-- Play a sound -->
|
||||
window.plugins.remotesound.playRemoteSound({
|
||||
'soundURL': 'http://myserver/sounds/mysound.wav'
|
||||
});
|
||||
|
||||
<!-- Load remote sounds -->
|
||||
window.plugins.remotesound.playRemoteSound({
|
||||
'soundURLs': ['http://myserver/sounds/mysound.wav', 'http://myserver/sounds/mysound2.wav']
|
||||
});
|
||||
|
||||
</pre>
|
||||
48
Android/RemoteSound/RemoteSound.js
Normal file
48
Android/RemoteSound/RemoteSound.js
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* RemoteSound
|
||||
* Implements the javascript access to the phonegap plugin for playing and loading remote sounds
|
||||
* @author Olivier Brand
|
||||
*/
|
||||
|
||||
/**
|
||||
* @return the deviceInfo class instance
|
||||
*/
|
||||
var RemoteSound = function() {
|
||||
};
|
||||
|
||||
/**
|
||||
* Play a sound. Parameter is a URI called "soundName"
|
||||
*
|
||||
* @param successCallback
|
||||
* The callback which will be called when directory listing is
|
||||
* successful
|
||||
* @param failureCallback
|
||||
* The callback which will be called when directory listing encouters
|
||||
* an error
|
||||
*/
|
||||
RemoteSound.prototype.playRemoteSound = function(params, successCallback,
|
||||
failureCallback) {
|
||||
return cordova.exec(successCallback, failureCallback, 'RemoteSound',
|
||||
'playRemoteSound', [ params ], true);
|
||||
};
|
||||
|
||||
/**
|
||||
* Load and cache remote sounds. Parameter is a JSON Array of URLs pointing to sound assets
|
||||
*
|
||||
* @param successCallback
|
||||
* The callback which will be called when directory listing is
|
||||
* successful
|
||||
* @param failureCallback
|
||||
* The callback which will be called when directory listing encouters
|
||||
* an error
|
||||
*/
|
||||
RemoteSound.prototype.loadRemoteSounds = function(params, successCallback,
|
||||
failureCallback) {
|
||||
return cordova.exec(successCallback, failureCallback, 'RemoteSound',
|
||||
'loadRemoteSounds', [ params ], true);
|
||||
};
|
||||
|
||||
|
||||
cordova.addConstructor(function() {
|
||||
cordova.addPlugin('remotesound', new RemoteSound());
|
||||
});
|
||||
250
Android/RemoteSound/RemoteSoundPlugin.java
Normal file
250
Android/RemoteSound/RemoteSoundPlugin.java
Normal file
@@ -0,0 +1,250 @@
|
||||
package com.phonegap.plugin.remotesound;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
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 org.json.JSONObject;
|
||||
|
||||
import android.content.Context;
|
||||
import android.media.MediaPlayer;
|
||||
import android.media.MediaPlayer.OnCompletionListener;
|
||||
import android.media.MediaPlayer.OnPreparedListener;
|
||||
|
||||
/**
|
||||
* The Class RemoteSoundPlugin allows to perform 2 separate actions: 1- play a
|
||||
* remote sound given a URL 2- load and cache sounds given some URLs
|
||||
*
|
||||
* A usage where load/cache sounds is valuable is when lots of sounds, possibly
|
||||
* large, needs to be pre-loaded Play sound is first checking that no other
|
||||
* sound with the same name has been cached. If not, it remotely downloads it
|
||||
* and cache it on the file system
|
||||
*/
|
||||
public class RemoteSoundPlugin extends Plugin implements OnPreparedListener, OnCompletionListener {
|
||||
|
||||
private MediaPlayer mp = null;
|
||||
private static final int BUFFER_SIZE = 1024 * 2;
|
||||
|
||||
@Override
|
||||
public PluginResult execute(String action, JSONArray args, String callbackId) {
|
||||
PluginResult result = null;
|
||||
|
||||
if (action.equals("playRemoteSound")) {
|
||||
|
||||
JSONObject obj = null;
|
||||
try {
|
||||
obj = args.getJSONObject(0);
|
||||
String soundURL = obj.has("soundURL") ? obj.getString("soundURL") : null;
|
||||
|
||||
if (soundURL != null) {
|
||||
this.playSound(soundURL);
|
||||
}
|
||||
} catch (JSONException jsonEx) {
|
||||
|
||||
result = new PluginResult(Status.JSON_EXCEPTION);
|
||||
}
|
||||
}
|
||||
|
||||
if (action.equals("loadRemoteSounds")) {
|
||||
|
||||
JSONArray resourceNames = null;
|
||||
JSONObject obj = null;
|
||||
|
||||
try {
|
||||
obj = args.getJSONObject(0);
|
||||
resourceNames = obj.has("soundURLs") ? obj.getJSONArray("soundURLs") : null;
|
||||
|
||||
if (resourceNames != null && resourceNames.length() > 0) {
|
||||
Set<URL> resources = new HashSet<URL>(resourceNames.length());
|
||||
for (int nbElem = 0; nbElem < resourceNames.length(); nbElem++) {
|
||||
try {
|
||||
resources.add(new URL(resourceNames.getString(nbElem)));
|
||||
} catch (MalformedURLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (!resources.isEmpty()) {
|
||||
downloadResources(ctx.getContext(), resources);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (JSONException jsonEx) {
|
||||
|
||||
result = new PluginResult(Status.JSON_EXCEPTION);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* android.media.MediaPlayer.OnPreparedListener#onPrepared(android.media
|
||||
* .MediaPlayer)
|
||||
*/
|
||||
public void onPrepared(MediaPlayer mediaplayer) {
|
||||
if (mp != null) {
|
||||
mp.start();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* android.media.MediaPlayer.OnCompletionListener#onCompletion(android.media
|
||||
* .MediaPlayer)
|
||||
*/
|
||||
public void onCompletion(MediaPlayer mediaplayer) {
|
||||
Timer endSound = new Timer();
|
||||
endSound.schedule(new TimerTask() {
|
||||
public void run() {
|
||||
if (mp != null) {
|
||||
mp.stop();
|
||||
mp.release();
|
||||
mp = null;
|
||||
}
|
||||
}
|
||||
}, 200);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Play sound, either locally (from assets) or remotely via URL.
|
||||
*
|
||||
* @param soundUri
|
||||
* the sound uri
|
||||
*/
|
||||
private void playSound(String soundUri) {
|
||||
|
||||
try {
|
||||
|
||||
mp = new MediaPlayer();
|
||||
|
||||
mp.setOnPreparedListener(this);
|
||||
mp.setOnCompletionListener(this);
|
||||
|
||||
FileInputStream fis = null;
|
||||
String soundName = soundUri.substring(soundUri.lastIndexOf('/') + 1);
|
||||
try {
|
||||
|
||||
fis = ctx.getApplicationContext().openFileInput(soundName);
|
||||
} catch (FileNotFoundException fne) {
|
||||
|
||||
downloadRemoteMedia(ctx.getApplicationContext(), soundUri, soundName);
|
||||
fis = ctx.getApplicationContext().openFileInput(soundName);
|
||||
}
|
||||
|
||||
mp.setDataSource(fis.getFD());
|
||||
|
||||
mp.setVolume(1.0f, 1.0f);
|
||||
mp.prepare();
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Download the url stream to a temporary location and then call the
|
||||
*
|
||||
*
|
||||
* @param context
|
||||
* the context
|
||||
* @param mediaUrl
|
||||
* the media url
|
||||
* @param mediaFileName
|
||||
* the media file name
|
||||
* @return the file
|
||||
* @throws IOException
|
||||
* Signals that an I/O exception has occurred.
|
||||
*/
|
||||
private void downloadRemoteMedia(Context context, String mediaUrl, String mediaFileName)
|
||||
throws IOException {
|
||||
// File downloadingMediaFile = null;
|
||||
HttpURLConnection cn = null;
|
||||
FileOutputStream out = null;
|
||||
InputStream stream = null;
|
||||
|
||||
try {
|
||||
cn = (HttpURLConnection) new URL(mediaUrl).openConnection();
|
||||
stream = new BufferedInputStream(cn.getInputStream(), BUFFER_SIZE);
|
||||
|
||||
// PRIVATE STORAGE. Automatically replace existing files
|
||||
out = context.openFileOutput(mediaFileName, Context.MODE_PRIVATE);
|
||||
|
||||
byte buf[] = new byte[BUFFER_SIZE];
|
||||
int len1 = 0;
|
||||
|
||||
while ((len1 = stream.read(buf)) > 0) {
|
||||
out.write(buf, 0, len1);
|
||||
}
|
||||
|
||||
out.close();
|
||||
stream.close();
|
||||
} finally {
|
||||
if (cn != null) {
|
||||
cn.disconnect();
|
||||
}
|
||||
try {
|
||||
out.close();
|
||||
} catch (IOException e) {
|
||||
|
||||
}
|
||||
try {
|
||||
stream.close();
|
||||
} catch (IOException e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Download given resources.
|
||||
*
|
||||
* @param context
|
||||
* the context
|
||||
* @param resources
|
||||
* the resources
|
||||
* @return the number of loaded resources
|
||||
*/
|
||||
private Integer downloadResources(Context context, Set<URL> resources) {
|
||||
int nbLoaded = 0;
|
||||
|
||||
for (Iterator<URL> iterator = resources.iterator(); iterator.hasNext();) {
|
||||
|
||||
URL url = iterator.next();
|
||||
try {
|
||||
downloadRemoteMedia(context, url.toString(),
|
||||
url.getPath().substring(url.getPath().lastIndexOf('/') + 1));
|
||||
nbLoaded++;
|
||||
} catch (IOException ioex) {
|
||||
ioex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return nbLoaded;
|
||||
}
|
||||
|
||||
}
|
||||
45
Android/Resources/README.md
Normal file
45
Android/Resources/README.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# Resources plugin for Phonegap (Android) #
|
||||
By Olivier Brand
|
||||
|
||||
## Adding the Plugin to your project ##
|
||||
1. To install the plugin, move `Resources.js` to your project's www folder and include a reference to it
|
||||
in your html files.
|
||||
|
||||
<script src="Resources.js"></script>
|
||||
|
||||
2. Create a folder called 'com/phonegap/plugin/resources' within your project's src folder.
|
||||
3. And copy the java file into that new folder.
|
||||
|
||||
<pre>
|
||||
mkdir -p <your_project>/src/com/phonegap/plugin/resources
|
||||
cp ./ResourcesPlugin.java <your_project>/src/com/phonegap/plugin/resources
|
||||
</pre>
|
||||
|
||||
4. Add a plugin line to `res/xml/plugins.xml`
|
||||
|
||||
<plugin name="Resources" value="com.phonegap.plugin.resources.ResourcesPlugin" />
|
||||
|
||||
## Using the plugin ##
|
||||
|
||||
<pre>
|
||||
|
||||
res/values/strings.xml
|
||||
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="login">mylogin</string>
|
||||
<string name="base_uri">/someuri</string>
|
||||
</resources>
|
||||
|
||||
|
||||
|
||||
this.resources = window.plugins.resources.getStringResources({
|
||||
'resources': [
|
||||
'base_uri', 'login'
|
||||
],
|
||||
'package': 'com.androidapp.app'
|
||||
});
|
||||
|
||||
console.log(this.resources.base_uri);
|
||||
|
||||
</pre>
|
||||
34
Android/Resources/Resources.js
Normal file
34
Android/Resources/Resources.js
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Resources
|
||||
* Implements the javascript access to the phonegap plugin for retrieving specific resource information
|
||||
* @author Olivier Brand
|
||||
*/
|
||||
|
||||
/**
|
||||
* @return the Resources class instance
|
||||
*/
|
||||
var Resources = function() {
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the named resources defined in R.strings Note the last parameter,
|
||||
* this method is synchronous
|
||||
*
|
||||
* @param successCallback
|
||||
* The callback which will be called when directory listing is
|
||||
* successful
|
||||
* @param failureCallback
|
||||
* The callback which will be called when directory listing encouters
|
||||
* an error
|
||||
*/
|
||||
Resources.prototype.getStringResources = function(params, successCallback,
|
||||
failureCallback) {
|
||||
return cordova.exec(successCallback, failureCallback, 'Resources',
|
||||
'getStringResources', [ params ], false);
|
||||
};
|
||||
|
||||
|
||||
|
||||
cordova.addConstructor(function() {
|
||||
cordova.addPlugin('resources', new Resources());
|
||||
});
|
||||
93
Android/Resources/ResourcesPlugin.java
Normal file
93
Android/Resources/ResourcesPlugin.java
Normal file
@@ -0,0 +1,93 @@
|
||||
package com.phonegap.plugin.resources;
|
||||
|
||||
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 org.json.JSONObject;
|
||||
|
||||
public class ResourcesPlugin extends Plugin {
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.phonegap.api.Plugin#isSynch(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public boolean isSynch(String action) {
|
||||
if (action.equals("getStringResources")) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.phonegap.api.Plugin#execute(java.lang.String,
|
||||
* org.json.JSONArray, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public PluginResult execute(String action, JSONArray args, String callbackId) {
|
||||
PluginResult result = null;
|
||||
|
||||
if (action.equals("getStringResources")) {
|
||||
|
||||
JSONObject obj = null;
|
||||
JSONArray resourceNames = null;
|
||||
String pkg = null;
|
||||
|
||||
try {
|
||||
obj = args.getJSONObject(0);
|
||||
if (obj != null) {
|
||||
resourceNames = obj.has("resources") ? obj.getJSONArray("resources") : null;
|
||||
pkg = obj.has("package") ? obj.getString("package") : ctx.getPackageName();
|
||||
}
|
||||
|
||||
if (resourceNames != null && resourceNames.length() > 0 && pkg != null) {
|
||||
|
||||
JSONObject JSONresult = new JSONObject();
|
||||
|
||||
JSONObject resources = new JSONObject();
|
||||
|
||||
for (int nbElem = 0; nbElem < resourceNames.length(); nbElem++) {
|
||||
resources.put(resourceNames.getString(nbElem),
|
||||
this.getStringResource(resourceNames.getString(nbElem), pkg));
|
||||
}
|
||||
|
||||
JSONresult.put("resources", resources);
|
||||
|
||||
result = new PluginResult(Status.OK, JSONresult);
|
||||
}
|
||||
|
||||
} catch (JSONException jsonEx) {
|
||||
result = new PluginResult(Status.JSON_EXCEPTION);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the string resource for a given package
|
||||
*
|
||||
* @param name
|
||||
* the name
|
||||
* @param packageName
|
||||
* the package name
|
||||
* @return the string resource
|
||||
*/
|
||||
private String getStringResource(String name, String packageName) {
|
||||
String resource = null;
|
||||
int id = ctx.getResources().getIdentifier(name, "string", packageName);
|
||||
if (id != 0) {
|
||||
resource = ctx.getContext().getString(id);
|
||||
|
||||
}
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -26,6 +26,9 @@ window.plugins.share.show({
|
||||
|
||||
## Release notes
|
||||
|
||||
### 5/29/2012
|
||||
* Updated for Cordova 1.6+ by @devgeeks
|
||||
|
||||
### 8/22/2011
|
||||
* Updated for PhoneGap 1.0
|
||||
|
||||
|
||||
@@ -13,8 +13,8 @@ import org.json.JSONObject;
|
||||
|
||||
import android.content.Intent;
|
||||
|
||||
import com.phonegap.api.Plugin;
|
||||
import com.phonegap.api.PluginResult;
|
||||
import org.apache.cordova.api.Plugin;
|
||||
import org.apache.cordova.api.PluginResult;
|
||||
|
||||
public class Share extends Plugin {
|
||||
|
||||
|
||||
@@ -6,20 +6,15 @@
|
||||
*/
|
||||
|
||||
var Share = function() {};
|
||||
|
||||
|
||||
Share.prototype.show = function(content, success, fail) {
|
||||
return PhoneGap.exec( function(args) {
|
||||
success(args);
|
||||
}, function(args) {
|
||||
fail(args);
|
||||
}, 'Share', '', [content]);
|
||||
return cordova.exec( function(args) {
|
||||
success(args);
|
||||
}, function(args) {
|
||||
fail(args);
|
||||
}, 'Share', '', [content]);
|
||||
};
|
||||
|
||||
PhoneGap.addConstructor(function() {
|
||||
/**
|
||||
* Phonegap version < 1.0
|
||||
* use the following line
|
||||
*/
|
||||
// PhoneGap.addPlugin('share', new Share());
|
||||
PluginManager.addService("Share","com.schaul.plugins.share.Share");
|
||||
cordova.addConstructor(function(){
|
||||
cordova.addPlugin('share', new Share());
|
||||
});
|
||||
@@ -7,141 +7,155 @@
|
||||
|
||||
package com.phonegap.plugins.speech;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import android.content.Context;
|
||||
import android.speech.tts.TextToSpeech;
|
||||
import android.speech.tts.TextToSpeech.OnInitListener;
|
||||
import android.speech.tts.TextToSpeech.OnUtteranceCompletedListener;
|
||||
|
||||
import com.phonegap.api.Plugin;
|
||||
import com.phonegap.api.PluginResult;
|
||||
import org.apache.cordova.api.Plugin;
|
||||
import org.apache.cordova.api.PluginResult;
|
||||
|
||||
public class TTS extends Plugin implements OnInitListener {
|
||||
|
||||
private static final String LOG_TAG = "TTS";
|
||||
private static final int STOPPED = 0;
|
||||
private static final int INITIALIZING = 1;
|
||||
private static final int STARTED = 2;
|
||||
private TextToSpeech mTts = null;
|
||||
private int state = STOPPED;
|
||||
|
||||
private String startupCallbackId = "";
|
||||
|
||||
@Override
|
||||
public PluginResult execute(String action, JSONArray args, String callbackId) {
|
||||
PluginResult.Status status = PluginResult.Status.OK;
|
||||
String result = "";
|
||||
public class TTS extends Plugin implements OnInitListener, OnUtteranceCompletedListener {
|
||||
|
||||
private static final String LOG_TAG = "TTS";
|
||||
private static final int STOPPED = 0;
|
||||
private static final int INITIALIZING = 1;
|
||||
private static final int STARTED = 2;
|
||||
private TextToSpeech mTts = null;
|
||||
private int state = STOPPED;
|
||||
|
||||
private String startupCallbackId = "";
|
||||
|
||||
@Override
|
||||
public PluginResult execute(String action, JSONArray args, String callbackId) {
|
||||
PluginResult.Status status = PluginResult.Status.OK;
|
||||
String result = "";
|
||||
|
||||
try {
|
||||
if (action.equals("speak")) {
|
||||
String text = args.getString(0);
|
||||
if (isReady()) {
|
||||
HashMap<String, String> map = null;
|
||||
map = new HashMap<String, String>();
|
||||
map.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, callbackId);
|
||||
mTts.speak(text, TextToSpeech.QUEUE_ADD, map);
|
||||
PluginResult pr = new PluginResult(PluginResult.Status.NO_RESULT);
|
||||
pr.setKeepCallback(true);
|
||||
return pr;
|
||||
} else {
|
||||
JSONObject error = new JSONObject();
|
||||
error.put("message","TTS service is still initialzing.");
|
||||
error.put("code", TTS.INITIALIZING);
|
||||
return new PluginResult(PluginResult.Status.ERROR, error);
|
||||
}
|
||||
}
|
||||
else if (action.equals("silence")) {
|
||||
if (isReady()) {
|
||||
mTts.playSilence(args.getLong(0), TextToSpeech.QUEUE_ADD, null);
|
||||
return new PluginResult(status, result);
|
||||
} else {
|
||||
JSONObject error = new JSONObject();
|
||||
error.put("message","TTS service is still initialzing.");
|
||||
error.put("code", TTS.INITIALIZING);
|
||||
return new PluginResult(PluginResult.Status.ERROR, error);
|
||||
}
|
||||
}
|
||||
else if (action.equals("startup")) {
|
||||
if (mTts == null) {
|
||||
this.startupCallbackId = callbackId;
|
||||
state = TTS.INITIALIZING;
|
||||
mTts = new TextToSpeech(ctx.getApplicationContext(), this);
|
||||
}
|
||||
PluginResult pluginResult = new PluginResult(status, TTS.INITIALIZING);
|
||||
pluginResult.setKeepCallback(true);
|
||||
return pluginResult;
|
||||
}
|
||||
else if (action.equals("shutdown")) {
|
||||
if (mTts != null) {
|
||||
mTts.shutdown();
|
||||
}
|
||||
return new PluginResult(status, result);
|
||||
}
|
||||
else if (action.equals("getLanguage")) {
|
||||
if (mTts != null) {
|
||||
result = mTts.getLanguage().toString();
|
||||
return new PluginResult(status, result);
|
||||
}
|
||||
}
|
||||
else if (action.equals("isLanguageAvailable")) {
|
||||
if (mTts != null) {
|
||||
Locale loc = new Locale(args.getString(0));
|
||||
int available = mTts.isLanguageAvailable(loc);
|
||||
result = (available < 0) ? "false" : "true";
|
||||
return new PluginResult(status, result);
|
||||
}
|
||||
}
|
||||
else if (action.equals("setLanguage")) {
|
||||
if (mTts != null) {
|
||||
Locale loc = new Locale(args.getString(0));
|
||||
int available = mTts.setLanguage(loc);
|
||||
result = (available < 0) ? "false" : "true";
|
||||
return new PluginResult(status, result);
|
||||
}
|
||||
}
|
||||
return new PluginResult(status, result);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
return new PluginResult(PluginResult.Status.JSON_EXCEPTION);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
if (action.equals("speak")) {
|
||||
String text = args.getString(0);
|
||||
if (isReady()) {
|
||||
mTts.speak(text, TextToSpeech.QUEUE_ADD, null);
|
||||
return new PluginResult(status, result);
|
||||
} else {
|
||||
JSONObject error = new JSONObject();
|
||||
error.put("message","TTS service is still initialzing.");
|
||||
error.put("code", TTS.INITIALIZING);
|
||||
return new PluginResult(PluginResult.Status.ERROR, error);
|
||||
}
|
||||
}
|
||||
else if (action.equals("silence")) {
|
||||
if (isReady()) {
|
||||
mTts.playSilence(args.getLong(0), TextToSpeech.QUEUE_ADD, null);
|
||||
return new PluginResult(status, result);
|
||||
} else {
|
||||
JSONObject error = new JSONObject();
|
||||
error.put("message","TTS service is still initialzing.");
|
||||
error.put("code", TTS.INITIALIZING);
|
||||
return new PluginResult(PluginResult.Status.ERROR, error);
|
||||
}
|
||||
}
|
||||
else if (action.equals("startup")) {
|
||||
if (mTts == null) {
|
||||
this.startupCallbackId = callbackId;
|
||||
state = TTS.INITIALIZING;
|
||||
mTts = new TextToSpeech(ctx.getContext(), this);
|
||||
//mTts.setLanguage(Locale.US);
|
||||
}
|
||||
PluginResult pluginResult = new PluginResult(status, TTS.INITIALIZING);
|
||||
pluginResult.setKeepCallback(true);
|
||||
return pluginResult;
|
||||
}
|
||||
else if (action.equals("shutdown")) {
|
||||
if (mTts != null) {
|
||||
mTts.shutdown();
|
||||
}
|
||||
return new PluginResult(status, result);
|
||||
}
|
||||
else if (action.equals("getLanguage")) {
|
||||
if (mTts != null) {
|
||||
result = mTts.getLanguage().toString();
|
||||
return new PluginResult(status, result);
|
||||
}
|
||||
}
|
||||
else if (action.equals("isLanguageAvailable")) {
|
||||
if (mTts != null) {
|
||||
Locale loc = new Locale(args.getString(0));
|
||||
int available = mTts.isLanguageAvailable(loc);
|
||||
result = (available < 0) ? "false" : "true";
|
||||
return new PluginResult(status, result);
|
||||
}
|
||||
}
|
||||
else if (action.equals("setLanguage")) {
|
||||
if (mTts != null) {
|
||||
Locale loc = new Locale(args.getString(0));
|
||||
int available = mTts.setLanguage(loc);
|
||||
result = (available < 0) ? "false" : "true";
|
||||
return new PluginResult(status, result);
|
||||
}
|
||||
}
|
||||
return new PluginResult(status, result);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
return new PluginResult(PluginResult.Status.JSON_EXCEPTION);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Is the TTS service ready to play yet?
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private boolean isReady() {
|
||||
return (state == TTS.STARTED) ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the TTS service ready to play yet?
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private boolean isReady() {
|
||||
return (state == TTS.STARTED) ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the TTS service is initialized.
|
||||
*
|
||||
* @param status
|
||||
*/
|
||||
public void onInit(int status) {
|
||||
if (status == TextToSpeech.SUCCESS) {
|
||||
/**
|
||||
* Called when the TTS service is initialized.
|
||||
*
|
||||
* @param status
|
||||
*/
|
||||
public void onInit(int status) {
|
||||
if (status == TextToSpeech.SUCCESS) {
|
||||
state = TTS.STARTED;
|
||||
PluginResult result = new PluginResult(PluginResult.Status.OK, TTS.STARTED);
|
||||
result.setKeepCallback(false);
|
||||
this.success(result, this.startupCallbackId);
|
||||
PluginResult result = new PluginResult(PluginResult.Status.OK, TTS.STARTED);
|
||||
result.setKeepCallback(false);
|
||||
this.success(result, this.startupCallbackId);
|
||||
mTts.setOnUtteranceCompletedListener(this);
|
||||
}
|
||||
else if (status == TextToSpeech.ERROR) {
|
||||
state = TTS.STOPPED;
|
||||
PluginResult result = new PluginResult(PluginResult.Status.ERROR, TTS.STOPPED);
|
||||
result.setKeepCallback(false);
|
||||
this.error(result, this.startupCallbackId);
|
||||
PluginResult result = new PluginResult(PluginResult.Status.ERROR, TTS.STOPPED);
|
||||
result.setKeepCallback(false);
|
||||
this.error(result, this.startupCallbackId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up the TTS resources
|
||||
*/
|
||||
public void onDestroy() {
|
||||
if (mTts != null) {
|
||||
mTts.shutdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up the TTS resources
|
||||
*/
|
||||
public void onDestroy() {
|
||||
if (mTts != null) {
|
||||
mTts.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Once the utterance has completely been played call the speak's success callback
|
||||
*/
|
||||
public void onUtteranceCompleted(String utteranceId) {
|
||||
PluginResult result = new PluginResult(PluginResult.Status.OK);
|
||||
result.setKeepCallback(false);
|
||||
this.success(result, utteranceId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,6 +59,18 @@ Gets called when onNewIntent is called for the parent activity. Used in only cer
|
||||
// url is the url that was passed to onNewIntent
|
||||
}
|
||||
});
|
||||
|
||||
### sendBroadcast ###
|
||||
Sends a custom intent passing optional extras
|
||||
|
||||
window.plugins.webintent.sendBroadcast({
|
||||
action: 'com.dummybroadcast.action.triggerthing',
|
||||
extras: {
|
||||
'option': true
|
||||
}
|
||||
}, function() {
|
||||
}, function() {
|
||||
});
|
||||
|
||||
## Licence ##
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.borismus.webintent;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.cordova.DroidGap;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
@@ -16,127 +17,173 @@ import com.phonegap.api.Plugin;
|
||||
import com.phonegap.api.PluginResult;
|
||||
|
||||
/**
|
||||
* WebIntent is a PhoneGap plugin that bridges Android intents and web applications:
|
||||
*
|
||||
* 1. web apps can spawn intents that call native Android applications.
|
||||
* 2. (after setting up correct intent filters for PhoneGap applications), Android
|
||||
* intents can be handled by PhoneGap web applications.
|
||||
* WebIntent is a PhoneGap plugin that bridges Android intents and web
|
||||
* applications:
|
||||
*
|
||||
* 1. web apps can spawn intents that call native Android applications. 2.
|
||||
* (after setting up correct intent filters for PhoneGap applications), Android
|
||||
* intents can be handled by PhoneGap web applications.
|
||||
*
|
||||
* @author boris@borismus.com
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class WebIntent extends Plugin {
|
||||
|
||||
private String onNewIntentCallback = null;
|
||||
/**
|
||||
* Executes the request and returns PluginResult.
|
||||
*
|
||||
* @param action The action to execute.
|
||||
* @param args JSONArray of arguments for the plugin.
|
||||
* @param callbackId The callback id used when calling back into JavaScript.
|
||||
* @return A PluginResult object with a status and message.
|
||||
*/
|
||||
public PluginResult execute(String action, JSONArray args, String callbackId) {
|
||||
try {
|
||||
if (action.equals("startActivity")) {
|
||||
if(args.length() != 1) {
|
||||
return new PluginResult(PluginResult.Status.INVALID_ACTION);
|
||||
}
|
||||
|
||||
// Parse the arguments
|
||||
JSONObject obj = args.getJSONObject(0);
|
||||
String type = obj.has("type") ? obj.getString("type") : null;
|
||||
Uri uri = obj.has("url") ? Uri.parse(obj.getString("url")) : null;
|
||||
JSONObject extras = obj.has("extras") ? obj.getJSONObject("extras") : null;
|
||||
Map<String, String> extrasMap = new HashMap<String, String>();
|
||||
|
||||
// Populate the extras if any exist
|
||||
if (extras != null) {
|
||||
JSONArray extraNames = extras.names();
|
||||
for (int i = 0; i < extraNames.length(); i++) {
|
||||
String key = extraNames.getString(i);
|
||||
String value = extras.getString(key);
|
||||
extrasMap.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
startActivity(obj.getString("action"), uri, type, extrasMap);
|
||||
return new PluginResult(PluginResult.Status.OK);
|
||||
|
||||
} else if (action.equals("hasExtra")) {
|
||||
if (args.length() != 1) {
|
||||
return new PluginResult(PluginResult.Status.INVALID_ACTION);
|
||||
}
|
||||
Intent i = this.ctx.getIntent();
|
||||
String extraName = args.getString(0);
|
||||
return new PluginResult(PluginResult.Status.OK, i.hasExtra(extraName));
|
||||
|
||||
} else if (action.equals("getExtra")) {
|
||||
if (args.length() != 1) {
|
||||
return new PluginResult(PluginResult.Status.INVALID_ACTION);
|
||||
}
|
||||
Intent i = this.ctx.getIntent();
|
||||
String extraName = args.getString(0);
|
||||
if (i.hasExtra(extraName)) {
|
||||
return new PluginResult(PluginResult.Status.OK, i.getStringExtra(extraName));
|
||||
} else {
|
||||
return new PluginResult(PluginResult.Status.ERROR);
|
||||
}
|
||||
} else if (action.equals("getUri")) {
|
||||
if (args.length() != 0) {
|
||||
return new PluginResult(PluginResult.Status.INVALID_ACTION);
|
||||
}
|
||||
private String onNewIntentCallback = null;
|
||||
|
||||
Intent i = this.ctx.getIntent();
|
||||
String uri = i.getDataString();
|
||||
return new PluginResult(PluginResult.Status.OK, uri);
|
||||
} else if (action.equals("onNewIntent")) {
|
||||
if (args.length() != 0) {
|
||||
return new PluginResult(PluginResult.Status.INVALID_ACTION);
|
||||
}
|
||||
|
||||
this.onNewIntentCallback = callbackId;
|
||||
PluginResult result = new PluginResult(PluginResult.Status.NO_RESULT);
|
||||
result.setKeepCallback(true);
|
||||
return result;
|
||||
}
|
||||
return new PluginResult(PluginResult.Status.INVALID_ACTION);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
return new PluginResult(PluginResult.Status.JSON_EXCEPTION);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNewIntent(Intent intent) {
|
||||
if (this.onNewIntentCallback != null) {
|
||||
PluginResult result = new PluginResult(PluginResult.Status.OK, intent.getDataString());
|
||||
result.setKeepCallback(true);
|
||||
this.success(result, this.onNewIntentCallback);
|
||||
}
|
||||
}
|
||||
|
||||
void startActivity(String action, Uri uri, String type, Map<String, String> extras) {
|
||||
Intent i = (uri != null ? new Intent(action, uri) : new Intent(action));
|
||||
if (type != null) {
|
||||
i.setType(type);
|
||||
}
|
||||
for (String key : extras.keySet()) {
|
||||
String value = extras.get(key);
|
||||
//If type is text html, the extra text must sent as HTML
|
||||
if (key.equals(Intent.EXTRA_TEXT) && type.equals("text/html")) {
|
||||
i.putExtra(key, Html.fromHtml(value));
|
||||
} else if(key.equals(Intent.EXTRA_STREAM)) {
|
||||
//allowes sharing of images as attachments.
|
||||
//value in this case should be a URI of a file
|
||||
i.putExtra(key, Uri.parse(value));
|
||||
} else if(key.equals(Intent.EXTRA_EMAIL)){
|
||||
//allows to add the email address of the receiver
|
||||
i.putExtra(Intent.EXTRA_EMAIL, new String[]{value});
|
||||
} else {
|
||||
i.putExtra(key, value);
|
||||
}
|
||||
}
|
||||
this.ctx.startActivity(i);
|
||||
}
|
||||
/**
|
||||
* Executes the request and returns PluginResult.
|
||||
*
|
||||
* @param action
|
||||
* The action to execute.
|
||||
* @param args
|
||||
* JSONArray of arguments for the plugin.
|
||||
* @param callbackId
|
||||
* The callback id used when calling back into JavaScript.
|
||||
* @return A PluginResult object with a status and message.
|
||||
*/
|
||||
public PluginResult execute(String action, JSONArray args, String callbackId) {
|
||||
try {
|
||||
if (action.equals("startActivity")) {
|
||||
if (args.length() != 1) {
|
||||
return new PluginResult(PluginResult.Status.INVALID_ACTION);
|
||||
}
|
||||
|
||||
// Parse the arguments
|
||||
JSONObject obj = args.getJSONObject(0);
|
||||
String type = obj.has("type") ? obj.getString("type") : null;
|
||||
Uri uri = obj.has("url") ? Uri.parse(obj.getString("url")) : null;
|
||||
JSONObject extras = obj.has("extras") ? obj.getJSONObject("extras") : null;
|
||||
Map<String, String> extrasMap = new HashMap<String, String>();
|
||||
|
||||
// Populate the extras if any exist
|
||||
if (extras != null) {
|
||||
JSONArray extraNames = extras.names();
|
||||
for (int i = 0; i < extraNames.length(); i++) {
|
||||
String key = extraNames.getString(i);
|
||||
String value = extras.getString(key);
|
||||
extrasMap.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
startActivity(obj.getString("action"), uri, type, extrasMap);
|
||||
return new PluginResult(PluginResult.Status.OK);
|
||||
|
||||
} else if (action.equals("hasExtra")) {
|
||||
if (args.length() != 1) {
|
||||
return new PluginResult(PluginResult.Status.INVALID_ACTION);
|
||||
}
|
||||
Intent i = ((DroidGap) this.ctx).getIntent();
|
||||
String extraName = args.getString(0);
|
||||
return new PluginResult(PluginResult.Status.OK, i.hasExtra(extraName));
|
||||
|
||||
} else if (action.equals("getExtra")) {
|
||||
if (args.length() != 1) {
|
||||
return new PluginResult(PluginResult.Status.INVALID_ACTION);
|
||||
}
|
||||
Intent i = ((DroidGap) this.ctx).getIntent();
|
||||
String extraName = args.getString(0);
|
||||
if (i.hasExtra(extraName)) {
|
||||
return new PluginResult(PluginResult.Status.OK, i.getStringExtra(extraName));
|
||||
} else {
|
||||
return new PluginResult(PluginResult.Status.ERROR);
|
||||
}
|
||||
} else if (action.equals("getUri")) {
|
||||
if (args.length() != 0) {
|
||||
return new PluginResult(PluginResult.Status.INVALID_ACTION);
|
||||
}
|
||||
|
||||
Intent i = ((DroidGap) this.ctx).getIntent();
|
||||
String uri = i.getDataString();
|
||||
return new PluginResult(PluginResult.Status.OK, uri);
|
||||
} else if (action.equals("onNewIntent")) {
|
||||
if (args.length() != 0) {
|
||||
return new PluginResult(PluginResult.Status.INVALID_ACTION);
|
||||
}
|
||||
|
||||
this.onNewIntentCallback = callbackId;
|
||||
PluginResult result = new PluginResult(PluginResult.Status.NO_RESULT);
|
||||
result.setKeepCallback(true);
|
||||
return result;
|
||||
} else if (action.equals("sendBroadcast"))
|
||||
{
|
||||
if (args.length() != 1) {
|
||||
return new PluginResult(PluginResult.Status.INVALID_ACTION);
|
||||
}
|
||||
|
||||
// Parse the arguments
|
||||
JSONObject obj = args.getJSONObject(0);
|
||||
|
||||
JSONObject extras = obj.has("extras") ? obj.getJSONObject("extras") : null;
|
||||
Map<String, String> extrasMap = new HashMap<String, String>();
|
||||
|
||||
// Populate the extras if any exist
|
||||
if (extras != null) {
|
||||
JSONArray extraNames = extras.names();
|
||||
for (int i = 0; i < extraNames.length(); i++) {
|
||||
String key = extraNames.getString(i);
|
||||
String value = extras.getString(key);
|
||||
extrasMap.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
sendBroadcast(obj.getString("action"), extrasMap);
|
||||
return new PluginResult(PluginResult.Status.OK);
|
||||
}
|
||||
return new PluginResult(PluginResult.Status.INVALID_ACTION);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
return new PluginResult(PluginResult.Status.JSON_EXCEPTION);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNewIntent(Intent intent) {
|
||||
if (this.onNewIntentCallback != null) {
|
||||
PluginResult result = new PluginResult(PluginResult.Status.OK, intent.getDataString());
|
||||
result.setKeepCallback(true);
|
||||
this.success(result, this.onNewIntentCallback);
|
||||
}
|
||||
}
|
||||
|
||||
void startActivity(String action, Uri uri, String type, Map<String, String> extras) {
|
||||
Intent i = (uri != null ? new Intent(action, uri) : new Intent(action));
|
||||
|
||||
if (type != null && uri != null) {
|
||||
i.setDataAndType(type, uri); //Fix the crash problem with android 2.3.6
|
||||
} else {
|
||||
if (type != null) {
|
||||
i.setType(type);
|
||||
}
|
||||
}
|
||||
|
||||
for (String key : extras.keySet()) {
|
||||
String value = extras.get(key);
|
||||
// If type is text html, the extra text must sent as HTML
|
||||
if (key.equals(Intent.EXTRA_TEXT) && type.equals("text/html")) {
|
||||
i.putExtra(key, Html.fromHtml(value));
|
||||
} else if (key.equals(Intent.EXTRA_STREAM)) {
|
||||
// allowes sharing of images as attachments.
|
||||
// value in this case should be a URI of a file
|
||||
i.putExtra(key, Uri.parse(value));
|
||||
} else if (key.equals(Intent.EXTRA_EMAIL)) {
|
||||
// allows to add the email address of the receiver
|
||||
i.putExtra(Intent.EXTRA_EMAIL, new String[] { value });
|
||||
} else {
|
||||
i.putExtra(key, value);
|
||||
}
|
||||
}
|
||||
this.ctx.startActivity(i);
|
||||
}
|
||||
|
||||
void sendBroadcast(String action, Map<String, String> extras) {
|
||||
Intent intent = new Intent();
|
||||
intent.setAction(action);
|
||||
for (String key : extras.keySet()) {
|
||||
String value = extras.get(key);
|
||||
intent.putExtra(key, value);
|
||||
}
|
||||
|
||||
((DroidGap) this.ctx)).sendBroadcast(intent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,6 +54,14 @@ WebIntent.prototype.onNewIntent = function(callback) {
|
||||
}, 'WebIntent', 'onNewIntent', []);
|
||||
};
|
||||
|
||||
WebIntent.prototype.sendBroadcast = function(params, success, fail) {
|
||||
return PhoneGap.exec(function(args) {
|
||||
success(args);
|
||||
}, function(args) {
|
||||
fail(args);
|
||||
}, 'WebIntent', 'sendBroadcast', [params]);
|
||||
};
|
||||
|
||||
PhoneGap.addConstructor(function() {
|
||||
PhoneGap.addPlugin('webintent', new WebIntent());
|
||||
});
|
||||
|
||||
@@ -32,10 +32,9 @@ var ChildBrowser = ChildBrowser || (function() {
|
||||
* An object that specifies additional options
|
||||
*/
|
||||
ChildBrowser.prototype.showWebPage = function(url, options) {
|
||||
if (options === null || options === "undefined") {
|
||||
var options = new Object();
|
||||
options.showLocationBar = true;
|
||||
}
|
||||
options = options || {
|
||||
showLocationBar: true
|
||||
};
|
||||
cordova.exec(this._onEvent, this._onError, "ChildBrowser",
|
||||
"showWebPage", [url, options ]);
|
||||
};
|
||||
|
||||
@@ -77,13 +77,13 @@
|
||||
// landscape
|
||||
case 90:
|
||||
case -90:
|
||||
self.adView.currentContentSizeIdentifier = ADBannerContentSizeIdentifier480x32;
|
||||
self.adView.currentContentSizeIdentifier = ADBannerContentSizeIdentifierLandscape;
|
||||
self.isLandscape = YES;
|
||||
break;
|
||||
// portrait
|
||||
case 0:
|
||||
case 180:
|
||||
self.adView.currentContentSizeIdentifier = ADBannerContentSizeIdentifier320x50;
|
||||
self.adView.currentContentSizeIdentifier = ADBannerContentSizeIdentifierPortrait;
|
||||
self.isLandscape = NO;
|
||||
break;
|
||||
default:
|
||||
@@ -146,11 +146,13 @@
|
||||
|
||||
self.adView = [[ADBannerView alloc] initWithFrame:CGRectMake(0, 0, 320, 50)];
|
||||
// we are still using these constants even though they are deprecated - if it is changed, iOS 4 devices < 4.3 will crash.
|
||||
// will need to do a run-time iOS version check
|
||||
self.adView.requiredContentSizeIdentifiers = [NSSet setWithObjects: ADBannerContentSizeIdentifier320x50, ADBannerContentSizeIdentifier480x32, nil];
|
||||
// will need to do a run-time iOS version check
|
||||
self.adView.requiredContentSizeIdentifiers = [NSSet setWithObjects: ADBannerContentSizeIdentifierPortrait, ADBannerContentSizeIdentifierLandscape, nil];
|
||||
|
||||
self.adView.delegate = self;
|
||||
|
||||
NSString* contentSizeId = (self.isLandscape ? ADBannerContentSizeIdentifier480x32 : ADBannerContentSizeIdentifier320x50);
|
||||
NSString* contentSizeId = (self.isLandscape ? ADBannerContentSizeIdentifierLandscape : ADBannerContentSizeIdentifierPortrait);
|
||||
|
||||
self.adView.currentContentSizeIdentifier = contentSizeId;
|
||||
|
||||
if (atBottom) {
|
||||
|
||||
40
iOS/AppBlade/AppBlade.js
Normal file
40
iOS/AppBlade/AppBlade.js
Normal file
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* AppBlade.js
|
||||
*
|
||||
* Phonegap AppBlade Instance plugin
|
||||
* Copyright (c) AppBlade 2012
|
||||
*
|
||||
*/
|
||||
|
||||
// --------------------------------------------------------
|
||||
|
||||
var AppBlade = function(){};
|
||||
|
||||
// --------------------------------------------------------
|
||||
|
||||
AppBlade.prototype.setupAppBlade = function(project, token, secret, timestamp) {
|
||||
cordova.exec("AppBlade.setupAppBlade", [project, token, secret, timestamp]);
|
||||
};
|
||||
|
||||
AppBlade.prototype.catchAndReportCrashes = function() {
|
||||
cordova.exec("AppBlade.catchAndReportCrashes");
|
||||
};
|
||||
|
||||
AppBlade.prototype.checkAuthentication = function() {
|
||||
cordova.exec("AppBlade.checkAuthentication");
|
||||
};
|
||||
|
||||
AppBlade.prototype.allowFeedbackReporting = function() {
|
||||
cordova.exec("AppBlade.allowFeedbackReporting");
|
||||
};
|
||||
|
||||
// --------------------------------------------------------
|
||||
|
||||
cordova.addConstructor(function() {
|
||||
if (!window.Cordova) {
|
||||
window.Cordova = cordova;
|
||||
};
|
||||
|
||||
if(!window.plugins) window.plugins = {};
|
||||
window.plugins.appBlade = new AppBlade();
|
||||
});
|
||||
19
iOS/AppBlade/AppBladePlugin.h
Normal file
19
iOS/AppBlade/AppBladePlugin.h
Normal file
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// AppBladePlugin.h
|
||||
// HelloWorld
|
||||
//
|
||||
// Created by Michele Titolo on 5/14/12.
|
||||
// Copyright (c) 2012 AppBlade. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Cordova/CDVPlugin.h>
|
||||
|
||||
@interface AppBladePlugin : CDVPlugin
|
||||
|
||||
- (void)setupAppBlade:(NSMutableArray*)args withDict:(NSMutableDictionary*)options;
|
||||
|
||||
- (void)catchAndReportCrashes:(NSMutableArray*)args withDict:(NSMutableDictionary*)options;
|
||||
- (void)allowFeedbackReporting:(NSMutableArray*)args withDict:(NSMutableDictionary*)options;
|
||||
- (void)checkAuthentication:(NSMutableArray*)args withDict:(NSMutableDictionary*)options;
|
||||
|
||||
@end
|
||||
55
iOS/AppBlade/AppBladePlugin.m
Normal file
55
iOS/AppBlade/AppBladePlugin.m
Normal file
@@ -0,0 +1,55 @@
|
||||
//
|
||||
// AppBladePlugin.m
|
||||
// HelloWorld
|
||||
//
|
||||
// Created by Michele Titolo on 5/14/12.
|
||||
// Copyright (c) 2012 AppBlade. All rights reserved.
|
||||
//
|
||||
|
||||
#import "AppBladePlugin.h"
|
||||
#import "AppBlade.h"
|
||||
|
||||
enum {
|
||||
ABProjectID = 0,
|
||||
ABToken,
|
||||
ABSecretKey,
|
||||
ABTimestamp
|
||||
};
|
||||
|
||||
@implementation AppBladePlugin
|
||||
|
||||
- (void)setupAppBlade:(NSMutableArray*)args withDict:(NSMutableDictionary*)options
|
||||
{
|
||||
NSArray* keys = [args objectAtIndex:0];
|
||||
NSLog(@"Setup with stuff: %@", keys);
|
||||
NSString* project = [keys objectAtIndex:ABProjectID];
|
||||
NSString* token = [keys objectAtIndex:ABToken];
|
||||
NSString* secret = [keys objectAtIndex:ABSecretKey];
|
||||
NSString* timestamp = [keys objectAtIndex:ABTimestamp];
|
||||
|
||||
AppBlade *blade = [AppBlade sharedManager];
|
||||
blade.appBladeProjectID = project;
|
||||
blade.appBladeProjectToken = token;
|
||||
blade.appBladeProjectSecret = secret;
|
||||
blade.appBladeProjectIssuedTimestamp = timestamp;
|
||||
}
|
||||
|
||||
- (void)catchAndReportCrashes:(NSMutableArray *)args withDict:(NSMutableDictionary *)options
|
||||
{
|
||||
NSLog(@"Catch and Report Crashes");
|
||||
[[AppBlade sharedManager] catchAndReportCrashes];
|
||||
}
|
||||
|
||||
- (void)checkAuthentication:(NSMutableArray *)args withDict:(NSMutableDictionary *)options
|
||||
{
|
||||
NSLog(@"Check approval");
|
||||
[[AppBlade sharedManager] checkApproval];
|
||||
}
|
||||
|
||||
- (void)allowFeedbackReporting:(NSMutableArray *)args withDict:(NSMutableDictionary *)options
|
||||
{
|
||||
NSLog(@"Allow Feedback");
|
||||
[[AppBlade sharedManager] allowFeedbackReporting];
|
||||
}
|
||||
|
||||
@end
|
||||
20
iOS/AppBlade/README.md
Normal file
20
iOS/AppBlade/README.md
Normal file
@@ -0,0 +1,20 @@
|
||||
AppBladeSDK PhoneGap Plugin
|
||||
===================
|
||||
|
||||
Plugin for PhoneGap that uses the AppBlade SDK.
|
||||
|
||||
|
||||
##Installation - iOS
|
||||
|
||||
1. Copy `AppBlade.js` from into your `www` directory.
|
||||
2. Copy `AppBladePlugin.[hm]` into your Plugins folder.
|
||||
3. Follow directions for [adding plugins to your iOS project](http://wiki.phonegap.com/w/page/43708792/How%20to%20Install%20a%20PhoneGap%20Plugin%20for%20iOS).
|
||||
3. Follow directions for [adding the AppBlade SDK to your project](http://github.com/AppBlade/SDK), but do not edit the `AppDelegate`.
|
||||
4. Add `-all_load` to the `other linker flags` build setting for your target.
|
||||
5. In your `index.html`, register for the `"deviceready"` eventListener, and call the setup method with your SDK keys in this order: project, token, secret, issued timestamp.
|
||||
|
||||
See the Example project included for examples using the other functions of the SDK.
|
||||
|
||||
##Resources:
|
||||
###[AppBlade.com](https://appblade.com/)
|
||||
###[License and Terms](https://appblade.com/terms_of_use)
|
||||
@@ -20,4 +20,5 @@
|
||||
//Significant Event Method
|
||||
|
||||
- (void) sigEvent:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;
|
||||
- (void) foreground:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;
|
||||
@end
|
||||
|
||||
@@ -7,5 +7,9 @@ var AppiraterPlugin = {
|
||||
|
||||
sigEvent: function() {
|
||||
return Cordova.exec("AppiraterPlugin.sigEvent");
|
||||
},
|
||||
foreground: function() {
|
||||
return Cordova.exec("AppiraterPlugin.foreground");
|
||||
}
|
||||
|
||||
};
|
||||
@@ -17,4 +17,9 @@
|
||||
[Appirater userDidSignificantEvent:YES];
|
||||
}
|
||||
|
||||
- (void) foreground:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
|
||||
{
|
||||
[Appirater appEnteredForeground:NO];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
203
iOS/AppiraterPlugin/Classes/Appirater.h
Normal file
203
iOS/AppiraterPlugin/Classes/Appirater.h
Normal file
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
This file is part of Appirater.
|
||||
|
||||
Copyright (c) 2012, Arash Payan
|
||||
All rights reserved.
|
||||
|
||||
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.
|
||||
*/
|
||||
/*
|
||||
* Appirater.h
|
||||
* appirater
|
||||
*
|
||||
* Created by Arash Payan on 9/5/09.
|
||||
* http://arashpayan.com
|
||||
* Copyright 2012 Arash Payan. All rights reserved.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
extern NSString *const kAppiraterFirstUseDate;
|
||||
extern NSString *const kAppiraterUseCount;
|
||||
extern NSString *const kAppiraterSignificantEventCount;
|
||||
extern NSString *const kAppiraterCurrentVersion;
|
||||
extern NSString *const kAppiraterRatedCurrentVersion;
|
||||
extern NSString *const kAppiraterDeclinedToRate;
|
||||
extern NSString *const kAppiraterReminderRequestDate;
|
||||
|
||||
/*
|
||||
Place your Apple generated software id here.
|
||||
*/
|
||||
#define APPIRATER_APP_ID 301377083
|
||||
|
||||
/*
|
||||
Your app's name.
|
||||
*/
|
||||
#define APPIRATER_APP_NAME [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey]
|
||||
|
||||
/*
|
||||
This is the message your users will see once they've passed the day+launches
|
||||
threshold.
|
||||
*/
|
||||
#define APPIRATER_LOCALIZED_MESSAGE NSLocalizedString(@"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!", nil)
|
||||
#define APPIRATER_MESSAGE [NSString stringWithFormat:APPIRATER_LOCALIZED_MESSAGE, APPIRATER_APP_NAME]
|
||||
|
||||
/*
|
||||
This is the title of the message alert that users will see.
|
||||
*/
|
||||
#define APPIRATER_LOCALIZED_MESSAGE_TITLE NSLocalizedString(@"Rate %@", nil)
|
||||
#define APPIRATER_MESSAGE_TITLE [NSString stringWithFormat:APPIRATER_LOCALIZED_MESSAGE_TITLE, APPIRATER_APP_NAME]
|
||||
|
||||
/*
|
||||
The text of the button that rejects reviewing the app.
|
||||
*/
|
||||
#define APPIRATER_CANCEL_BUTTON NSLocalizedString(@"No, Thanks", nil)
|
||||
|
||||
/*
|
||||
Text of button that will send user to app review page.
|
||||
*/
|
||||
#define APPIRATER_LOCALIZED_RATE_BUTTON NSLocalizedString(@"Rate %@", nil)
|
||||
#define APPIRATER_RATE_BUTTON [NSString stringWithFormat:APPIRATER_LOCALIZED_RATE_BUTTON, APPIRATER_APP_NAME]
|
||||
|
||||
/*
|
||||
Text for button to remind the user to review later.
|
||||
*/
|
||||
#define APPIRATER_RATE_LATER NSLocalizedString(@"Remind me later", nil)
|
||||
|
||||
/*
|
||||
Users will need to have the same version of your app installed for this many
|
||||
days before they will be prompted to rate it.
|
||||
*/
|
||||
#define APPIRATER_DAYS_UNTIL_PROMPT 30 // double
|
||||
|
||||
/*
|
||||
An example of a 'use' would be if the user launched the app. Bringing the app
|
||||
into the foreground (on devices that support it) would also be considered
|
||||
a 'use'. You tell Appirater about these events using the two methods:
|
||||
[Appirater appLaunched:]
|
||||
[Appirater appEnteredForeground:]
|
||||
|
||||
Users need to 'use' the same version of the app this many times before
|
||||
before they will be prompted to rate it.
|
||||
*/
|
||||
#define APPIRATER_USES_UNTIL_PROMPT 20 // integer
|
||||
|
||||
/*
|
||||
A significant event can be anything you want to be in your app. In a
|
||||
telephone app, a significant event might be placing or receiving a call.
|
||||
In a game, it might be beating a level or a boss. This is just another
|
||||
layer of filtering that can be used to make sure that only the most
|
||||
loyal of your users are being prompted to rate you on the app store.
|
||||
If you leave this at a value of -1, then this won't be a criteria
|
||||
used for rating. To tell Appirater that the user has performed
|
||||
a significant event, call the method:
|
||||
[Appirater userDidSignificantEvent:];
|
||||
*/
|
||||
#define APPIRATER_SIG_EVENTS_UNTIL_PROMPT -1 // integer
|
||||
|
||||
/*
|
||||
Once the rating alert is presented to the user, they might select
|
||||
'Remind me later'. This value specifies how long (in days) Appirater
|
||||
will wait before reminding them.
|
||||
*/
|
||||
#define APPIRATER_TIME_BEFORE_REMINDING 1 // double
|
||||
|
||||
/*
|
||||
'YES' will show the Appirater alert everytime. Useful for testing how your message
|
||||
looks and making sure the link to your app's review page works.
|
||||
*/
|
||||
#define APPIRATER_DEBUG NO
|
||||
|
||||
@interface Appirater : NSObject <UIAlertViewDelegate> {
|
||||
|
||||
UIAlertView *ratingAlert;
|
||||
}
|
||||
|
||||
@property(nonatomic, retain) UIAlertView *ratingAlert;
|
||||
|
||||
/*
|
||||
DEPRECATED: While still functional, it's better to use
|
||||
appLaunched:(BOOL)canPromptForRating instead.
|
||||
|
||||
Calls [Appirater appLaunched:YES]. See appLaunched: for details of functionality.
|
||||
*/
|
||||
+ (void)appLaunched;
|
||||
|
||||
/*
|
||||
Tells Appirater that the app has launched, and on devices that do NOT
|
||||
support multitasking, the 'uses' count will be incremented. You should
|
||||
call this method at the end of your application delegate's
|
||||
application:didFinishLaunchingWithOptions: method.
|
||||
|
||||
If the app has been used enough to be rated (and enough significant events),
|
||||
you can suppress the rating alert
|
||||
by passing NO for canPromptForRating. The rating alert will simply be postponed
|
||||
until it is called again with YES for canPromptForRating. The rating alert
|
||||
can also be triggered by appEnteredForeground: and userDidSignificantEvent:
|
||||
(as long as you pass YES for canPromptForRating in those methods).
|
||||
*/
|
||||
+ (void)appLaunched:(BOOL)canPromptForRating;
|
||||
|
||||
/*
|
||||
Tells Appirater that the app was brought to the foreground on multitasking
|
||||
devices. You should call this method from the application delegate's
|
||||
applicationWillEnterForeground: method.
|
||||
|
||||
If the app has been used enough to be rated (and enough significant events),
|
||||
you can suppress the rating alert
|
||||
by passing NO for canPromptForRating. The rating alert will simply be postponed
|
||||
until it is called again with YES for canPromptForRating. The rating alert
|
||||
can also be triggered by appLaunched: and userDidSignificantEvent:
|
||||
(as long as you pass YES for canPromptForRating in those methods).
|
||||
*/
|
||||
+ (void)appEnteredForeground:(BOOL)canPromptForRating;
|
||||
|
||||
/*
|
||||
Tells Appirater that the user performed a significant event. A significant
|
||||
event is whatever you want it to be. If you're app is used to make VoIP
|
||||
calls, then you might want to call this method whenever the user places
|
||||
a call. If it's a game, you might want to call this whenever the user
|
||||
beats a level boss.
|
||||
|
||||
If the user has performed enough significant events and used the app enough,
|
||||
you can suppress the rating alert by passing NO for canPromptForRating. The
|
||||
rating alert will simply be postponed until it is called again with YES for
|
||||
canPromptForRating. The rating alert can also be triggered by appLaunched:
|
||||
and appEnteredForeground: (as long as you pass YES for canPromptForRating
|
||||
in those methods).
|
||||
*/
|
||||
+ (void)userDidSignificantEvent:(BOOL)canPromptForRating;
|
||||
|
||||
/*
|
||||
Tells Appirater to open the App Store page where the user can specify a
|
||||
rating for the app. Also records the fact that this has happened, so the
|
||||
user won't be prompted again to rate the app.
|
||||
|
||||
The only case where you should call this directly is if your app has an
|
||||
explicit "Rate this app" command somewhere. In all other cases, don't worry
|
||||
about calling this -- instead, just call the other functions listed above,
|
||||
and let Appirater handle the bookkeeping of deciding when to ask the user
|
||||
whether to rate the app.
|
||||
*/
|
||||
+ (void)rateApp;
|
||||
|
||||
@end
|
||||
376
iOS/AppiraterPlugin/Classes/Appirater.m
Normal file
376
iOS/AppiraterPlugin/Classes/Appirater.m
Normal file
@@ -0,0 +1,376 @@
|
||||
/*
|
||||
This file is part of Appirater.
|
||||
|
||||
Copyright (c) 2010, Arash Payan
|
||||
All rights reserved.
|
||||
|
||||
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.
|
||||
*/
|
||||
/*
|
||||
* Appirater.m
|
||||
* appirater
|
||||
*
|
||||
* Created by Arash Payan on 9/5/09.
|
||||
* http://arashpayan.com
|
||||
* Copyright 2010 Arash Payan. All rights reserved.
|
||||
*/
|
||||
|
||||
#import "Appirater.h"
|
||||
#import <SystemConfiguration/SCNetworkReachability.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
NSString *const kAppiraterFirstUseDate = @"kAppiraterFirstUseDate";
|
||||
NSString *const kAppiraterUseCount = @"kAppiraterUseCount";
|
||||
NSString *const kAppiraterSignificantEventCount = @"kAppiraterSignificantEventCount";
|
||||
NSString *const kAppiraterCurrentVersion = @"kAppiraterCurrentVersion";
|
||||
NSString *const kAppiraterRatedCurrentVersion = @"kAppiraterRatedCurrentVersion";
|
||||
NSString *const kAppiraterDeclinedToRate = @"kAppiraterDeclinedToRate";
|
||||
NSString *const kAppiraterReminderRequestDate = @"kAppiraterReminderRequestDate";
|
||||
|
||||
NSString *templateReviewURL = @"itms-apps://ax.itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?type=Purple+Software&id=APP_ID";
|
||||
|
||||
|
||||
@interface Appirater (hidden)
|
||||
- (BOOL)connectedToNetwork;
|
||||
+ (Appirater*)sharedInstance;
|
||||
- (void)showRatingAlert;
|
||||
- (BOOL)ratingConditionsHaveBeenMet;
|
||||
- (void)incrementUseCount;
|
||||
@end
|
||||
|
||||
@implementation Appirater (hidden)
|
||||
|
||||
- (BOOL)connectedToNetwork {
|
||||
// Create zero addy
|
||||
struct sockaddr_in zeroAddress;
|
||||
bzero(&zeroAddress, sizeof(zeroAddress));
|
||||
zeroAddress.sin_len = sizeof(zeroAddress);
|
||||
zeroAddress.sin_family = AF_INET;
|
||||
|
||||
// Recover reachability flags
|
||||
SCNetworkReachabilityRef defaultRouteReachability = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&zeroAddress);
|
||||
SCNetworkReachabilityFlags flags;
|
||||
|
||||
BOOL didRetrieveFlags = SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags);
|
||||
CFRelease(defaultRouteReachability);
|
||||
|
||||
if (!didRetrieveFlags)
|
||||
{
|
||||
NSLog(@"Error. Could not recover network reachability flags");
|
||||
return NO;
|
||||
}
|
||||
|
||||
BOOL isReachable = flags & kSCNetworkFlagsReachable;
|
||||
BOOL needsConnection = flags & kSCNetworkFlagsConnectionRequired;
|
||||
BOOL nonWiFi = flags & kSCNetworkReachabilityFlagsTransientConnection;
|
||||
|
||||
NSURL *testURL = [NSURL URLWithString:@"http://www.apple.com/"];
|
||||
NSURLRequest *testRequest = [NSURLRequest requestWithURL:testURL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:20.0];
|
||||
NSURLConnection *testConnection = [[NSURLConnection alloc] initWithRequest:testRequest delegate:self];
|
||||
|
||||
return ((isReachable && !needsConnection) || nonWiFi) ? (testConnection ? YES : NO) : NO;
|
||||
}
|
||||
|
||||
+ (Appirater*)sharedInstance {
|
||||
static Appirater *appirater = nil;
|
||||
if (appirater == nil)
|
||||
{
|
||||
@synchronized(self) {
|
||||
if (appirater == nil) {
|
||||
appirater = [[Appirater alloc] init];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appWillResignActive) name:@"UIApplicationWillResignActiveNotification" object:nil];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return appirater;
|
||||
}
|
||||
|
||||
- (void)showRatingAlert {
|
||||
UIAlertView *alertView = [[[UIAlertView alloc] initWithTitle:APPIRATER_MESSAGE_TITLE
|
||||
message:APPIRATER_MESSAGE
|
||||
delegate:self
|
||||
cancelButtonTitle:APPIRATER_CANCEL_BUTTON
|
||||
otherButtonTitles:APPIRATER_RATE_BUTTON, APPIRATER_RATE_LATER, nil] autorelease];
|
||||
self.ratingAlert = alertView;
|
||||
[alertView show];
|
||||
}
|
||||
|
||||
- (BOOL)ratingConditionsHaveBeenMet {
|
||||
if (APPIRATER_DEBUG)
|
||||
return YES;
|
||||
|
||||
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
|
||||
|
||||
NSDate *dateOfFirstLaunch = [NSDate dateWithTimeIntervalSince1970:[userDefaults doubleForKey:kAppiraterFirstUseDate]];
|
||||
NSTimeInterval timeSinceFirstLaunch = [[NSDate date] timeIntervalSinceDate:dateOfFirstLaunch];
|
||||
NSTimeInterval timeUntilRate = 60 * 60 * 24 * APPIRATER_DAYS_UNTIL_PROMPT;
|
||||
if (timeSinceFirstLaunch < timeUntilRate)
|
||||
return NO;
|
||||
|
||||
// check if the app has been used enough
|
||||
int useCount = [userDefaults integerForKey:kAppiraterUseCount];
|
||||
if (useCount <= APPIRATER_USES_UNTIL_PROMPT)
|
||||
return NO;
|
||||
|
||||
// check if the user has done enough significant events
|
||||
int sigEventCount = [userDefaults integerForKey:kAppiraterSignificantEventCount];
|
||||
if (sigEventCount <= APPIRATER_SIG_EVENTS_UNTIL_PROMPT)
|
||||
return NO;
|
||||
|
||||
// has the user previously declined to rate this version of the app?
|
||||
if ([userDefaults boolForKey:kAppiraterDeclinedToRate])
|
||||
return NO;
|
||||
|
||||
// has the user already rated the app?
|
||||
if ([userDefaults boolForKey:kAppiraterRatedCurrentVersion])
|
||||
return NO;
|
||||
|
||||
// if the user wanted to be reminded later, has enough time passed?
|
||||
NSDate *reminderRequestDate = [NSDate dateWithTimeIntervalSince1970:[userDefaults doubleForKey:kAppiraterReminderRequestDate]];
|
||||
NSTimeInterval timeSinceReminderRequest = [[NSDate date] timeIntervalSinceDate:reminderRequestDate];
|
||||
NSTimeInterval timeUntilReminder = 60 * 60 * 24 * APPIRATER_TIME_BEFORE_REMINDING;
|
||||
if (timeSinceReminderRequest < timeUntilReminder)
|
||||
return NO;
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)incrementUseCount {
|
||||
// get the app's version
|
||||
NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleVersionKey];
|
||||
|
||||
// get the version number that we've been tracking
|
||||
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
|
||||
NSString *trackingVersion = [userDefaults stringForKey:kAppiraterCurrentVersion];
|
||||
if (trackingVersion == nil)
|
||||
{
|
||||
trackingVersion = version;
|
||||
[userDefaults setObject:version forKey:kAppiraterCurrentVersion];
|
||||
}
|
||||
|
||||
if (APPIRATER_DEBUG)
|
||||
NSLog(@"APPIRATER Tracking version: %@", trackingVersion);
|
||||
|
||||
if ([trackingVersion isEqualToString:version])
|
||||
{
|
||||
// check if the first use date has been set. if not, set it.
|
||||
NSTimeInterval timeInterval = [userDefaults doubleForKey:kAppiraterFirstUseDate];
|
||||
if (timeInterval == 0)
|
||||
{
|
||||
timeInterval = [[NSDate date] timeIntervalSince1970];
|
||||
[userDefaults setDouble:timeInterval forKey:kAppiraterFirstUseDate];
|
||||
}
|
||||
|
||||
// increment the use count
|
||||
int useCount = [userDefaults integerForKey:kAppiraterUseCount];
|
||||
useCount++;
|
||||
[userDefaults setInteger:useCount forKey:kAppiraterUseCount];
|
||||
if (APPIRATER_DEBUG)
|
||||
NSLog(@"APPIRATER Use count: %d", useCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
// it's a new version of the app, so restart tracking
|
||||
[userDefaults setObject:version forKey:kAppiraterCurrentVersion];
|
||||
[userDefaults setDouble:[[NSDate date] timeIntervalSince1970] forKey:kAppiraterFirstUseDate];
|
||||
[userDefaults setInteger:1 forKey:kAppiraterUseCount];
|
||||
[userDefaults setInteger:0 forKey:kAppiraterSignificantEventCount];
|
||||
[userDefaults setBool:NO forKey:kAppiraterRatedCurrentVersion];
|
||||
[userDefaults setBool:NO forKey:kAppiraterDeclinedToRate];
|
||||
[userDefaults setDouble:0 forKey:kAppiraterReminderRequestDate];
|
||||
}
|
||||
|
||||
[userDefaults synchronize];
|
||||
}
|
||||
|
||||
- (void)incrementSignificantEventCount {
|
||||
// get the app's version
|
||||
NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleVersionKey];
|
||||
|
||||
// get the version number that we've been tracking
|
||||
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
|
||||
NSString *trackingVersion = [userDefaults stringForKey:kAppiraterCurrentVersion];
|
||||
if (trackingVersion == nil)
|
||||
{
|
||||
trackingVersion = version;
|
||||
[userDefaults setObject:version forKey:kAppiraterCurrentVersion];
|
||||
}
|
||||
|
||||
if (APPIRATER_DEBUG)
|
||||
NSLog(@"APPIRATER Tracking version: %@", trackingVersion);
|
||||
|
||||
if ([trackingVersion isEqualToString:version])
|
||||
{
|
||||
// check if the first use date has been set. if not, set it.
|
||||
NSTimeInterval timeInterval = [userDefaults doubleForKey:kAppiraterFirstUseDate];
|
||||
if (timeInterval == 0)
|
||||
{
|
||||
timeInterval = [[NSDate date] timeIntervalSince1970];
|
||||
[userDefaults setDouble:timeInterval forKey:kAppiraterFirstUseDate];
|
||||
}
|
||||
|
||||
// increment the significant event count
|
||||
int sigEventCount = [userDefaults integerForKey:kAppiraterSignificantEventCount];
|
||||
sigEventCount++;
|
||||
[userDefaults setInteger:sigEventCount forKey:kAppiraterSignificantEventCount];
|
||||
if (APPIRATER_DEBUG)
|
||||
NSLog(@"APPIRATER Significant event count: %d", sigEventCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
// it's a new version of the app, so restart tracking
|
||||
[userDefaults setObject:version forKey:kAppiraterCurrentVersion];
|
||||
[userDefaults setDouble:0 forKey:kAppiraterFirstUseDate];
|
||||
[userDefaults setInteger:0 forKey:kAppiraterUseCount];
|
||||
[userDefaults setInteger:1 forKey:kAppiraterSignificantEventCount];
|
||||
[userDefaults setBool:NO forKey:kAppiraterRatedCurrentVersion];
|
||||
[userDefaults setBool:NO forKey:kAppiraterDeclinedToRate];
|
||||
[userDefaults setDouble:0 forKey:kAppiraterReminderRequestDate];
|
||||
}
|
||||
|
||||
[userDefaults synchronize];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@interface Appirater ()
|
||||
- (void)hideRatingAlert;
|
||||
@end
|
||||
|
||||
@implementation Appirater
|
||||
|
||||
@synthesize ratingAlert;
|
||||
|
||||
- (void)incrementAndRate:(NSNumber*)_canPromptForRating {
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
[self incrementUseCount];
|
||||
|
||||
if ([_canPromptForRating boolValue] == YES &&
|
||||
[self ratingConditionsHaveBeenMet] &&
|
||||
[self connectedToNetwork])
|
||||
{
|
||||
[self performSelectorOnMainThread:@selector(showRatingAlert) withObject:nil waitUntilDone:NO];
|
||||
}
|
||||
|
||||
[pool release];
|
||||
}
|
||||
|
||||
- (void)incrementSignificantEventAndRate:(NSNumber*)_canPromptForRating {
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
[self incrementSignificantEventCount];
|
||||
|
||||
if ([_canPromptForRating boolValue] == YES &&
|
||||
[self ratingConditionsHaveBeenMet] &&
|
||||
[self connectedToNetwork])
|
||||
{
|
||||
[self performSelectorOnMainThread:@selector(showRatingAlert) withObject:nil waitUntilDone:NO];
|
||||
}
|
||||
|
||||
[pool release];
|
||||
}
|
||||
|
||||
+ (void)appLaunched {
|
||||
[Appirater appLaunched:YES];
|
||||
}
|
||||
|
||||
+ (void)appLaunched:(BOOL)canPromptForRating {
|
||||
NSNumber *_canPromptForRating = [[NSNumber alloc] initWithBool:canPromptForRating];
|
||||
[NSThread detachNewThreadSelector:@selector(incrementAndRate:)
|
||||
toTarget:[Appirater sharedInstance]
|
||||
withObject:_canPromptForRating];
|
||||
[_canPromptForRating release];
|
||||
}
|
||||
|
||||
- (void)hideRatingAlert {
|
||||
if (self.ratingAlert.visible) {
|
||||
if (APPIRATER_DEBUG)
|
||||
NSLog(@"APPIRATER Hiding Alert");
|
||||
[self.ratingAlert dismissWithClickedButtonIndex:-1 animated:NO];
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)appWillResignActive {
|
||||
if (APPIRATER_DEBUG)
|
||||
NSLog(@"APPIRATER appWillResignActive");
|
||||
[[Appirater sharedInstance] hideRatingAlert];
|
||||
}
|
||||
|
||||
+ (void)appEnteredForeground:(BOOL)canPromptForRating {
|
||||
NSNumber *_canPromptForRating = [[NSNumber alloc] initWithBool:canPromptForRating];
|
||||
[NSThread detachNewThreadSelector:@selector(incrementAndRate:)
|
||||
toTarget:[Appirater sharedInstance]
|
||||
withObject:_canPromptForRating];
|
||||
[_canPromptForRating release];
|
||||
}
|
||||
|
||||
+ (void)userDidSignificantEvent:(BOOL)canPromptForRating {
|
||||
NSNumber *_canPromptForRating = [[NSNumber alloc] initWithBool:canPromptForRating];
|
||||
[NSThread detachNewThreadSelector:@selector(incrementSignificantEventAndRate:)
|
||||
toTarget:[Appirater sharedInstance]
|
||||
withObject:_canPromptForRating];
|
||||
[_canPromptForRating release];
|
||||
}
|
||||
|
||||
+ (void)rateApp {
|
||||
#if TARGET_IPHONE_SIMULATOR
|
||||
NSLog(@"APPIRATER NOTE: iTunes App Store is not supported on the iOS simulator. Unable to open App Store page.");
|
||||
#else
|
||||
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
|
||||
NSString *reviewURL = [templateReviewURL stringByReplacingOccurrencesOfString:@"APP_ID" withString:[NSString stringWithFormat:@"%d", APPIRATER_APP_ID]];
|
||||
[userDefaults setBool:YES forKey:kAppiraterRatedCurrentVersion];
|
||||
[userDefaults synchronize];
|
||||
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:reviewURL]];
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
|
||||
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
|
||||
|
||||
switch (buttonIndex) {
|
||||
case 0:
|
||||
{
|
||||
// they don't want to rate it
|
||||
[userDefaults setBool:YES forKey:kAppiraterDeclinedToRate];
|
||||
[userDefaults synchronize];
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
// they want to rate it
|
||||
[Appirater rateApp];
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
// remind them later
|
||||
[userDefaults setDouble:[[NSDate date] timeIntervalSince1970] forKey:kAppiraterReminderRequestDate];
|
||||
[userDefaults synchronize];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,11 +1,14 @@
|
||||
# AppiraterPlugin #
|
||||
by James Stuckey Weber
|
||||
|
||||
This plugin allows you to call Appirater userDidSignificantEvent: from javascript. The other Appirater functions should be called in the AppDelegate class as specified by the Appirater install log.
|
||||
This plugin allows you to call Appirater userDidSignificantEvent and appEnteredForeground from javascript (sigEvent and foreground correspondingly). The Appirater appLaunched function should be called in the AppDelegate class as specified by the Appirater install log.
|
||||
|
||||
## Adding the Plugin to your Project ##
|
||||
|
||||
1. Install [Appirater](https://github.com/arashpayan/appirater).
|
||||
1a). Add call the Appirater class before return 'YES' of didFinishLaunchingWithOptions function in AppDelegate.m
|
||||
[Appirater appLaunched:YES];
|
||||
1b) If the latest version of Appirater is not working with Phonegap (checked at May 7, 2012). Use the previous version of Appirater from Class folder of the plugin.
|
||||
2. Add the AppiraterPlugin folder to the Plugins folder in XCode, using "Create groups for any added folders".
|
||||
3. Add the 'Appirater.js' file to your www folder and link to it from your html files.
|
||||
4. Add new entry key 'AppiraterPlugin' with value 'AppiraterPlugin' to 'Plugins' in 'PhoneGap.plist/Cordova.plist'
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
|
||||
|
||||
#ifdef CORDOVA_FRAMEWORK
|
||||
#import <CORDOVA/CDVPlugin.h>
|
||||
#import <Cordova/CDVPlugin.h>
|
||||
#else
|
||||
#import "CORDOVA/CDVPlugin.h"
|
||||
#import "Cordova/CDVPlugin.h"
|
||||
#endif
|
||||
#import "ChildBrowserViewController.h"
|
||||
|
||||
|
||||
@@ -19,14 +19,14 @@
|
||||
{
|
||||
if(childBrowser == NULL)
|
||||
{
|
||||
childBrowser = [[ ChildBrowserViewController alloc ] initWithScale:FALSE ];
|
||||
childBrowser.delegate = self;
|
||||
childBrowser = [[ ChildBrowserViewController alloc ] initWithScale:FALSE ];
|
||||
childBrowser.delegate = self;
|
||||
}
|
||||
|
||||
/* // TODO: Work in progress
|
||||
NSString* strOrientations = [ options objectForKey:@"supportedOrientations"];
|
||||
NSArray* supportedOrientations = [strOrientations componentsSeparatedByString:@","];
|
||||
*/
|
||||
/* // TODO: Work in progress
|
||||
NSString* strOrientations = [ options objectForKey:@"supportedOrientations"];
|
||||
NSArray* supportedOrientations = [strOrientations componentsSeparatedByString:@","];
|
||||
*/
|
||||
|
||||
#ifdef CORDOVA_FRAMEWORK
|
||||
CDVViewController* cont = (CDVViewController*)[ super viewController ];
|
||||
@@ -52,13 +52,13 @@
|
||||
|
||||
-(void) onClose
|
||||
{
|
||||
NSString* jsCallback = [NSString stringWithFormat:@"ChildBrowser._onClose();",@""];
|
||||
NSString* jsCallback = [NSString stringWithFormat:@"window.plugins.childBrowser.onClose();",@""];
|
||||
[self.webView stringByEvaluatingJavaScriptFromString:jsCallback];
|
||||
}
|
||||
|
||||
-(void) onOpenInSafari
|
||||
{
|
||||
NSString* jsCallback = [NSString stringWithFormat:@"ChildBrowser._onOpenExternal();",@""];
|
||||
NSString* jsCallback = [NSString stringWithFormat:@"window.plugins.childBrowser.onOpenExternal();",@""];
|
||||
[self.webView stringByEvaluatingJavaScriptFromString:jsCallback];
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
NSString* tempLoc = [NSString stringWithFormat:@"%@",newLoc];
|
||||
NSString* encUrl = [tempLoc stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
|
||||
|
||||
NSString* jsCallback = [NSString stringWithFormat:@"ChildBrowser._onLocationChange('%@');",encUrl];
|
||||
NSString* jsCallback = [NSString stringWithFormat:@"window.plugins.childBrowser.onLocationChange('%@');",encUrl];
|
||||
[self.webView stringByEvaluatingJavaScriptFromString:jsCallback];
|
||||
|
||||
}
|
||||
|
||||
@@ -33,33 +33,29 @@ cordova.exec("ChildBrowserCommand.showWebPage", "http://www.google.com" );
|
||||
###Sample use:
|
||||
|
||||
|
||||
var root = this;
|
||||
function onDeviceReady() {
|
||||
|
||||
/* When this function is called, PhoneGap has been initialized and is ready to roll */
|
||||
function onDeviceReady()
|
||||
{
|
||||
var cb = ChildBrowser.install();
|
||||
if(cb != null)
|
||||
{
|
||||
cb.onLocationChange = function(loc){ root.locChanged(loc); };
|
||||
cb.onClose = function(){root.onCloseBrowser()};
|
||||
cb.onOpenExternal = function(){root.onOpenExternal();};
|
||||
var root = this;
|
||||
cb = window.plugins.childBrowser;
|
||||
|
||||
window.plugins.childBrowser.showWebPage("http://google.com");
|
||||
if(cb != null) {
|
||||
cb.onLocationChange = function(loc){ root.locChanged(loc); };
|
||||
cb.onClose = function(){root.onCloseBrowser(); };
|
||||
cb.onOpenExternal = function(){root.onOpenExternal(); };
|
||||
cb.showWebPage("http://google.com");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onCloseBrowser()
|
||||
{
|
||||
alert("In index.html child browser closed");
|
||||
}
|
||||
function onCloseBrowser() {
|
||||
console.log("onCloseBrowser!");
|
||||
}
|
||||
|
||||
function locChanged(loc) {
|
||||
alert("In index.html new loc = " + loc);
|
||||
}
|
||||
function locChanged(loc) {
|
||||
console.log("locChanged!");
|
||||
}
|
||||
|
||||
function onOpenExternal() {
|
||||
alert("In index.html onOpenExternal");
|
||||
}
|
||||
function onOpenExternal() {
|
||||
alert("onOpenExternal!");
|
||||
}
|
||||
|
||||
|
||||
@@ -1,67 +1,95 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title></title>
|
||||
<head>
|
||||
<title></title>
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no;" />
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no;" />
|
||||
<meta charset="utf-8">
|
||||
|
||||
|
||||
<!-- iPad/iPhone specific css below, add after your main css >
|
||||
<link rel="stylesheet" media="only screen and (max-device-width: 1024px)" href="ipad.css" type="text/css" />
|
||||
<link rel="stylesheet" media="only screen and (max-device-width: 480px)" href="iphone.css" type="text/css" />
|
||||
-->
|
||||
<!-- If your application is targeting iOS BEFORE 4.0 you MUST put json2.js from http://www.JSON.org/json2.js into your www directory and include it here -->
|
||||
<script type="text/javascript" charset="utf-8" src="cordova-1.7.0rc1.js"></script>
|
||||
<script type="text/javascript">
|
||||
<!-- iPad/iPhone specific css below, add after your main css >
|
||||
<link rel="stylesheet" media="only screen and (max-device-width: 1024px)" href="ipad.css" type="text/css" />
|
||||
<link rel="stylesheet" media="only screen and (max-device-width: 480px)" href="iphone.css" type="text/css" />
|
||||
-->
|
||||
<!-- If your application is targeting iOS BEFORE 4.0 you MUST put json2.js from http://www.JSON.org/json2.js into your www directory and include it here -->
|
||||
<script type="text/javascript" charset="utf-8" src="cordova-1.7.0.js"></script>
|
||||
|
||||
<script type="text/javascript" charset="utf-8" src="ChildBrowser.js"></script>
|
||||
|
||||
<script type="text/javascript" charset="utf-8" src="cordova-WebInspector.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
|
||||
// If you want to prevent dragging, uncomment this section
|
||||
/*
|
||||
function preventBehavior(e)
|
||||
{
|
||||
e.preventDefault();
|
||||
};
|
||||
document.addEventListener("touchmove", preventBehavior, false);
|
||||
*/
|
||||
// If you want to prevent dragging, uncomment this section
|
||||
/*
|
||||
function preventBehavior(e)
|
||||
{
|
||||
e.preventDefault();
|
||||
};
|
||||
document.addEventListener("touchmove", preventBehavior, false);
|
||||
*/
|
||||
|
||||
/* If you are supporting your own protocol, the var invokeString will contain any arguments to the app launch.
|
||||
see http://iphonedevelopertips.com/cocoa/launching-your-own-application-via-a-custom-url-scheme.html
|
||||
for more details -jm */
|
||||
/*
|
||||
function handleOpenURL(url)
|
||||
{
|
||||
// TODO: do something with the url passed in.
|
||||
}
|
||||
*/
|
||||
/* If you are supporting your own protocol, the var invokeString will contain any arguments to the app launch.
|
||||
see http://iphonedevelopertips.com/cocoa/launching-your-own-application-via-a-custom-url-scheme.html
|
||||
for more details -jm */
|
||||
/*
|
||||
function handleOpenURL(url)
|
||||
{
|
||||
// TODO: do something with the url passed in.
|
||||
}
|
||||
*/
|
||||
|
||||
function onBodyLoad()
|
||||
{
|
||||
document.addEventListener("deviceready", onDeviceReady, false);
|
||||
}
|
||||
function onBodyLoad()
|
||||
{
|
||||
document.addEventListener("deviceready", onDeviceReady, false);
|
||||
}
|
||||
|
||||
/* When this function is called, Cordova has been initialized and is ready to roll */
|
||||
/* If you are supporting your own protocol, the var invokeString will contain any arguments to the app launch.
|
||||
see http://iphonedevelopertips.com/cocoa/launching-your-own-application-via-a-custom-url-scheme.html
|
||||
for more details -jm */
|
||||
function onDeviceReady() {
|
||||
|
||||
// do your thing!
|
||||
//navigator.notification.alert("Cordova is working")
|
||||
var loc = "https://raw.github.com/phonegap/phonegap-plugins/master/iOS/ChildBrowser/README.md";
|
||||
cordova.exec("ChildBrowserCommand.showWebPage", loc);
|
||||
|
||||
}
|
||||
/* When this function is called, PhoneGap has been initialized and is ready to roll */
|
||||
function onDeviceReady() {
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body onload="onBodyLoad()">
|
||||
<h1>Hey, it's Cordova!</h1>
|
||||
<p>Don't know how to get started? Check out our <em><a target="_blank" href="http://docs.phonegap.com/en/edge/guide_getting-started_ios_index.md.html#Getting%20Started%20with%20iOS">Getting Started Guide</a></em>
|
||||
<br />
|
||||
<ol>
|
||||
<li>Check your console log for any white-list rejection errors.</li>
|
||||
<li>Add your allowed <strong>hosts</strong> in Cordova.plist/ExternalHosts (wildcards OK, don't enter the URL scheme)</li>
|
||||
</ol>
|
||||
</body>
|
||||
var root = this;
|
||||
|
||||
cb = window.plugins.childBrowser;
|
||||
|
||||
if (cb != null) {
|
||||
cb.onLocationChange = function(loc){ root.locChanged(loc); };
|
||||
cb.onClose = function(){root.onCloseBrowser()};
|
||||
cb.onOpenExternal = function(){root.onOpenExternal();};
|
||||
cb.showWebPage("http://google.com");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function onCloseBrowser() {
|
||||
console.log("onCloseBrowser!");
|
||||
}
|
||||
|
||||
function locChanged(loc) {
|
||||
console.log("locChanged!");
|
||||
}
|
||||
|
||||
function onOpenExternal() {
|
||||
console.log("onOpenExternal!");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body onload="onBodyLoad()">
|
||||
<h1>Hey, it's Cordova!</h1>
|
||||
<p>Don't know how to get started? Check out our <em><a target="_blank" href="http://docs.phonegap.com/en/edge/guide_getting-started_ios_index.md.html#Getting%20Started%20with%20iOS">Getting Started Guide</a></em>
|
||||
<br />
|
||||
<ol>
|
||||
<li>Check your console log for any white-list rejection errors.</li>
|
||||
<li>Add your allowed <strong>hosts</strong> in Cordova.plist/ExternalHosts (wildcards OK, don't enter the URL scheme)</li>
|
||||
</ol>
|
||||
|
||||
<button onclick="cb.showWebPage('http://google.com');">Click to open ChildBrowser!</button>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
18
iOS/Diagnostic/Diagnostic.h
Normal file
18
iOS/Diagnostic/Diagnostic.h
Normal file
@@ -0,0 +1,18 @@
|
||||
//
|
||||
// Diagnostic.h
|
||||
// Plugin diagnostic
|
||||
//
|
||||
// Copyright (c) 2012 AVANTIC ESTUDIO DE INGENIEROS
|
||||
//
|
||||
|
||||
#import <Cordova/CDVPlugin.h>
|
||||
|
||||
@interface Diagnostic : CDVPlugin
|
||||
|
||||
- (void) isLocationEnabled: (NSMutableArray*)arguments withDict:(NSMutableDictionary*) options;
|
||||
- (void) isLocationEnabledOnly: (NSMutableArray*)arguments withDict:(NSMutableDictionary*) options;
|
||||
- (void) isLocationAuthorized: (NSMutableArray*)arguments withDict:(NSMutableDictionary*) options;
|
||||
- (void) isWifiEnabled: (NSMutableArray*)arguments withDict:(NSMutableDictionary*) options;
|
||||
- (void) isCameraEnabled: (NSMutableArray*)arguments withDict:(NSMutableDictionary*) options;
|
||||
|
||||
@end
|
||||
209
iOS/Diagnostic/Diagnostic.m
Normal file
209
iOS/Diagnostic/Diagnostic.m
Normal file
@@ -0,0 +1,209 @@
|
||||
//
|
||||
// Diagnostic.m
|
||||
// Plugin diagnostic
|
||||
//
|
||||
// Copyright (c) 2012 AVANTIC ESTUDIO DE INGENIEROS
|
||||
//
|
||||
|
||||
#import "Diagnostic.h"
|
||||
#import <CoreLocation/CoreLocation.h>
|
||||
|
||||
#import <arpa/inet.h> // For AF_INET, etc.
|
||||
#import <ifaddrs.h> // For getifaddrs()
|
||||
#import <net/if.h> // For IFF_LOOPBACK
|
||||
|
||||
@implementation Diagnostic
|
||||
|
||||
|
||||
- (void) isLocationEnabled: (NSMutableArray*)arguments withDict:(NSMutableDictionary*) options
|
||||
{
|
||||
NSString * callbackId = [arguments objectAtIndex:0];
|
||||
NSLog(@"Loading Location status...");
|
||||
CDVPluginResult* pluginResult;
|
||||
if([self isLocationEnabled] && [self isLocationAuthorized])
|
||||
{
|
||||
|
||||
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:1];
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:0];
|
||||
|
||||
}
|
||||
[self writeJavascript: [pluginResult toSuccessCallbackString:callbackId]];
|
||||
|
||||
}
|
||||
|
||||
- (void) isLocationEnabledSetting: (NSMutableArray*)arguments withDict:(NSMutableDictionary*) options
|
||||
{
|
||||
NSString * callbackId = [arguments objectAtIndex:0];
|
||||
NSLog(@"Loading Location status...");
|
||||
CDVPluginResult* pluginResult;
|
||||
if([self isLocationEnabled])
|
||||
{
|
||||
|
||||
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:1];
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:0];
|
||||
|
||||
}
|
||||
[self writeJavascript: [pluginResult toSuccessCallbackString:callbackId]];
|
||||
|
||||
}
|
||||
|
||||
- (void) isLocationAuthorized: (NSMutableArray*)arguments withDict:(NSMutableDictionary*) options
|
||||
{
|
||||
NSString * callbackId = [arguments objectAtIndex:0];
|
||||
NSLog(@"Loading Location authentication...");
|
||||
CDVPluginResult* pluginResult;
|
||||
if([self isLocationAuthorized])
|
||||
{
|
||||
|
||||
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:1];
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:0];
|
||||
|
||||
}
|
||||
[self writeJavascript: [pluginResult toSuccessCallbackString:callbackId]];
|
||||
|
||||
}
|
||||
|
||||
- (BOOL) isLocationEnabled
|
||||
{
|
||||
|
||||
if([CLLocationManager locationServicesEnabled])
|
||||
{
|
||||
NSLog(@"Location is enabled.");
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
NSLog(@"Location is disabled.");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
- (BOOL) isLocationAuthorized
|
||||
{
|
||||
|
||||
if([CLLocationManager authorizationStatus] != kCLAuthorizationStatusDenied)
|
||||
{
|
||||
NSLog(@"This app is authorized to use location.");
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
NSLog(@"This app is not authorized to use location.");
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
- (void) isWifiEnabled: (NSMutableArray*)arguments withDict:(NSMutableDictionary*) options
|
||||
{
|
||||
NSString * callbackId = [arguments objectAtIndex:0];
|
||||
NSLog(@"Loading WiFi status...");
|
||||
CDVPluginResult* pluginResult;
|
||||
if([self connectedToWifi])
|
||||
{
|
||||
|
||||
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:1];
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:0];
|
||||
|
||||
}
|
||||
[self writeJavascript: [pluginResult toSuccessCallbackString:callbackId]];
|
||||
|
||||
}
|
||||
|
||||
- (BOOL) connectedToWifi // Don't work on iOS Simulator, only in the device
|
||||
{
|
||||
struct ifaddrs *addresses;
|
||||
struct ifaddrs *cursor;
|
||||
BOOL wiFiAvailable = NO;
|
||||
|
||||
if (getifaddrs(&addresses) != 0)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
cursor = addresses;
|
||||
|
||||
while (cursor != NULL)
|
||||
{
|
||||
if (cursor -> ifa_addr -> sa_family == AF_INET && !(cursor -> ifa_flags & IFF_LOOPBACK)) // Ignore the loopback address
|
||||
{
|
||||
// Check for WiFi adapter
|
||||
|
||||
if (strcmp(cursor -> ifa_name, "en0") == 0) {
|
||||
|
||||
NSLog(@"Wifi ON");
|
||||
wiFiAvailable = YES;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
cursor = cursor -> ifa_next;
|
||||
}
|
||||
|
||||
freeifaddrs(addresses);
|
||||
return wiFiAvailable;
|
||||
}
|
||||
|
||||
- (void) isCameraEnabled: (NSMutableArray*)arguments withDict:(NSMutableDictionary*) options
|
||||
{
|
||||
NSString * callbackId = [arguments objectAtIndex:0];
|
||||
NSLog(@"Loading camera status...");
|
||||
CDVPluginResult* pluginResult;
|
||||
if([self isCameraEnabled])
|
||||
{
|
||||
|
||||
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:1];
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:0];
|
||||
|
||||
}
|
||||
[self writeJavascript: [pluginResult toSuccessCallbackString:callbackId]];
|
||||
|
||||
}
|
||||
|
||||
|
||||
- (BOOL) isCameraEnabled
|
||||
{
|
||||
|
||||
BOOL cameraAvailable =
|
||||
[UIImagePickerController
|
||||
isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera];
|
||||
if(cameraAvailable)
|
||||
{
|
||||
NSLog(@"Camera enabled");
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
NSLog(@"Camera disabled");
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@end
|
||||
206
iOS/Diagnostic/README.md
Normal file
206
iOS/Diagnostic/README.md
Normal file
@@ -0,0 +1,206 @@
|
||||
# Diagnostic plugin for PhoneGap #
|
||||
|
||||
The diagnostic plugin allows you to check different device settings in your PhoneGap application.
|
||||
|
||||
A simple use case would be:
|
||||
|
||||
- Your app require geolocation and you want check if the location services are enabled in device settings.
|
||||
- Your app require the Wi-Fi enabled for the wireless network location and you want check if the Wi-Fi is enabled in device settings.
|
||||
- Your app require the camera enabled and you want check if the camera is enabled in device settings.
|
||||
|
||||
## Adding the Plugin to your project ##
|
||||
|
||||
Using this plugin requires a PhoneGap project for iOS: [Get Started Guide](http://phonegap.com/start#ios-x4).
|
||||
|
||||
1. To install the plugin, move _diagnostic.js_ to your project's _www_ folder and include a reference to it in your _html_ file after _cordova.js_:
|
||||
|
||||
<pre>
|
||||
<script type="text/javascript" charset="utf-8" src="cordova-X.X.X.js"></script>
|
||||
<script type="text/javascript" charset="utf-8" src="diagnostic.js"></script>
|
||||
</pre>
|
||||
|
||||
2. Move _Diagnostic.h_ and _Diagnostic.m_ files into _Plugins_ folder.
|
||||
3. And edit _Cordova.plist_ creating a new entry in the _Plugins_ section as follows:
|
||||
|
||||
<pre>
|
||||
- Key: Diagnostic
|
||||
- Type: String
|
||||
- Value: Diagnostic
|
||||
</pre>
|
||||
|
||||
## Using the plugin ##
|
||||
|
||||
The plugin creates the object:
|
||||
<pre>
|
||||
window.plugins.diagnostic
|
||||
</pre>
|
||||
To use, call one of the following, available methods:
|
||||
|
||||
|
||||
- isLocationEnabled:
|
||||
|
||||
<pre>
|
||||
/**
|
||||
* Checks if location is enabled (Device setting for location and authorization).
|
||||
*
|
||||
* @param successCallback The callback which will be called when diagnostic of location is successful.
|
||||
* This callback function have a boolean param with the diagnostic result.
|
||||
* @param errorCallback The callback which will be called when diagnostic of location encounters an error.
|
||||
* This callback function have a string param with the error.
|
||||
*/
|
||||
isLocationEnabled()
|
||||
</pre>
|
||||
|
||||
Usage:
|
||||
|
||||
<pre>
|
||||
window.plugins.diagnostic.isLocationEnabled(locationEnabledSuccessCallback, locationEnabledErrorCallback);
|
||||
|
||||
function locationEnabledSuccessCallback(result) {
|
||||
if (result)
|
||||
alert("Location ON");
|
||||
else
|
||||
alert("Location OFF");
|
||||
}
|
||||
|
||||
function locationEnabledErrorCallback(error) {
|
||||
console.log(error);
|
||||
}
|
||||
</pre>
|
||||
|
||||
- isLocationEnabledSetting:
|
||||
|
||||
<pre>
|
||||
/**
|
||||
* Checks device settings for location.
|
||||
*
|
||||
* @param successCallback The callback which will be called when diagnostic of location is successful.
|
||||
* This callback function have a boolean param with the diagnostic result.
|
||||
* @param errorCallback The callback which will be called when diagnostic of location encounters an error.
|
||||
* This callback function have a string param with the error.
|
||||
*/
|
||||
isLocationEnabledSetting()
|
||||
</pre>
|
||||
|
||||
Usage:
|
||||
|
||||
<pre>
|
||||
window.plugins.diagnostic.isLocationEnabledSetting(locationEnabledSettingSuccessCallback, locationEnabledSettingErrorCallback);
|
||||
|
||||
function locationEnabledSettingSuccessCallback(result) {
|
||||
if (result)
|
||||
alert("Location ON");
|
||||
else
|
||||
alert("Location OFF");
|
||||
}
|
||||
|
||||
function locationEnabledSettingErrorCallback(error) {
|
||||
console.log(error);
|
||||
}
|
||||
</pre>
|
||||
|
||||
- isLocationAuthorized:
|
||||
|
||||
<pre>
|
||||
/**
|
||||
* Checks if the application is authorized to use location.
|
||||
*
|
||||
* @param successCallback The callback which will be called when diagnostic of location is successful.
|
||||
* This callback function have a boolean param with the diagnostic result.
|
||||
* @param errorCallback The callback which will be called when diagnostic of location encounters an error.
|
||||
* This callback function have a string param with the error.
|
||||
*/
|
||||
isLocationAuthorized()
|
||||
</pre>
|
||||
|
||||
Usage:
|
||||
|
||||
<pre>
|
||||
window.plugins.diagnostic.isLocationAuthorized(locationAuthorizedSuccessCallback, locationAuthorizedErrorCallback);
|
||||
|
||||
function locationAuthorizedSuccessCallback(result) {
|
||||
if (result)
|
||||
alert("Authorized to use location");
|
||||
else
|
||||
alert("Not authorized to use location");
|
||||
}
|
||||
|
||||
function locationAuthorizedErrorCallback(error) {
|
||||
console.log(error);
|
||||
}
|
||||
</pre>
|
||||
|
||||
- isWifiEnabled:
|
||||
|
||||
<pre>
|
||||
/**
|
||||
* Checks if exists Wi-Fi connection.
|
||||
*
|
||||
* @param successCallback The callback which will be called when diagnostic of Wi-Fi is successful.
|
||||
* This callback function have a boolean param with the diagnostic result.
|
||||
* @param errorCallback The callback which will be called when diagnostic of Wi-Fi encounters an error.
|
||||
* This callback function have a string param with the error.
|
||||
*/
|
||||
isWifiEnabled()
|
||||
</pre>
|
||||
|
||||
Usage:
|
||||
|
||||
<pre>
|
||||
window.plugins.diagnostic.isWifiEnabled(wifiEnabledSuccessCallback, wifiEnabledErrorCallback);
|
||||
|
||||
function wifiEnabledSuccessCallback(result) {
|
||||
if (result)
|
||||
alert("Wi-Fi ON");
|
||||
else
|
||||
alert("Wi-Fi OFF");
|
||||
}
|
||||
|
||||
function wifiEnabledErrorCallback(error) {
|
||||
console.log(error);
|
||||
}
|
||||
</pre>
|
||||
|
||||
- isCameraEnabled:
|
||||
|
||||
<pre>
|
||||
/**
|
||||
* Checks if exists camera.
|
||||
*
|
||||
* @param successCallback The callback which will be called when diagnostic of camera is successful.
|
||||
* This callback function have a boolean param with the diagnostic result.
|
||||
* @param errorCallback The callback which will be called when diagnostic of camera encounters an error.
|
||||
* This callback function have a string param with the error.
|
||||
*/
|
||||
isCameraEnabled()
|
||||
</pre>
|
||||
|
||||
Usage:
|
||||
|
||||
<pre>
|
||||
window.plugins.diagnostic.isCameraEnabled(cameraEnabledSuccessCallback, cameraEnabledErrorCallback);
|
||||
|
||||
function cameraEnabledSuccessCallback(result) {
|
||||
if (result)
|
||||
alert("Camera ON");
|
||||
else
|
||||
alert("Camera OFF");
|
||||
}
|
||||
|
||||
function cameraEnabledErrorCallback(error) {
|
||||
console.log(error);
|
||||
}
|
||||
</pre>
|
||||
|
||||
|
||||
## LICENSE ##
|
||||
|
||||
Copyright (c) 2012 AVANTIC ESTUDIO DE INGENIEROS
|
||||
|
||||
The MIT License
|
||||
|
||||
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.
|
||||
102
iOS/Diagnostic/diagnostic.js
Normal file
102
iOS/Diagnostic/diagnostic.js
Normal file
@@ -0,0 +1,102 @@
|
||||
/**
|
||||
* Plugin diagnostic
|
||||
*
|
||||
* Copyright (c) 2012 AVANTIC ESTUDIO DE INGENIEROS
|
||||
*
|
||||
**/
|
||||
|
||||
|
||||
var Diagnostic = function() {
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if location is enabled (Device setting for location and authorization).
|
||||
*
|
||||
* @param successCallback The callback which will be called when diagnostic of location is successful.
|
||||
* This callback function have a boolean param with the diagnostic result.
|
||||
* @param errorCallback The callback which will be called when diagnostic of location encounters an error.
|
||||
* This callback function have a string param with the error.
|
||||
*/
|
||||
|
||||
Diagnostic.prototype.isLocationEnabled = function(successCallback, errorCallback) {
|
||||
return cordova.exec(successCallback,
|
||||
errorCallback,
|
||||
'Diagnostic',
|
||||
'isLocationEnabled',
|
||||
[]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks device settings for location.
|
||||
*
|
||||
* @param successCallback The callback which will be called when diagnostic of location is successful.
|
||||
* This callback function have a boolean param with the diagnostic result.
|
||||
* @param errorCallback The callback which will be called when diagnostic of location encounters an error.
|
||||
* This callback function have a string param with the error.
|
||||
*/
|
||||
|
||||
Diagnostic.prototype.isLocationEnabledSetting = function(successCallback, errorCallback) {
|
||||
return cordova.exec(successCallback,
|
||||
errorCallback,
|
||||
'Diagnostic',
|
||||
'isLocationEnabledSetting',
|
||||
[]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if the application is authorized to use location.
|
||||
*
|
||||
* @param successCallback The callback which will be called when diagnostic of location is successful.
|
||||
* This callback function have a boolean param with the diagnostic result.
|
||||
* @param errorCallback The callback which will be called when diagnostic of location encounters an error.
|
||||
* This callback function have a string param with the error.
|
||||
*/
|
||||
|
||||
Diagnostic.prototype.isLocationAuthorized = function(successCallback, errorCallback) {
|
||||
return cordova.exec(successCallback,
|
||||
errorCallback,
|
||||
'Diagnostic',
|
||||
'isLocationAuthorized',
|
||||
[]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if exists Wi-Fi connection.
|
||||
*
|
||||
* @param successCallback The callback which will be called when diagnostic of Wi-Fi is successful.
|
||||
* This callback function have a boolean param with the diagnostic result.
|
||||
* @param errorCallback The callback which will be called when diagnostic of Wi-Fi encounters an error.
|
||||
* This callback function have a string param with the error.
|
||||
*/
|
||||
|
||||
Diagnostic.prototype.isWifiEnabled = function(successCallback, errorCallback) {
|
||||
return cordova.exec(successCallback,
|
||||
errorCallback,
|
||||
'Diagnostic',
|
||||
'isWifiEnabled',
|
||||
[]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if exists camera.
|
||||
*
|
||||
* @param successCallback The callback which will be called when diagnostic of camera is successful.
|
||||
* This callback function have a boolean param with the diagnostic result.
|
||||
* @param errorCallback The callback which will be called when diagnostic of camera encounters an error.
|
||||
* This callback function have a string param with the error.
|
||||
*/
|
||||
|
||||
|
||||
Diagnostic.prototype.isCameraEnabled = function(successCallback, errorCallback) {
|
||||
return cordova.exec(successCallback,
|
||||
errorCallback,
|
||||
'Diagnostic',
|
||||
'isCameraEnabled',
|
||||
[]);
|
||||
};
|
||||
|
||||
cordova.addConstructor(function() {
|
||||
if(!window.plugins)
|
||||
window.plugins = {};
|
||||
window.plugins.diagnostic = new Diagnostic();
|
||||
});
|
||||
22
iOS/Diagnostic/example/www/index.html
Normal file
22
iOS/Diagnostic/example/www/index.html
Normal file
@@ -0,0 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title></title>
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no;" />
|
||||
<meta charset="utf-8">
|
||||
|
||||
<script type="text/javascript" charset="utf-8" src="cordova.js"></script>
|
||||
<script type="text/javascript" charset="utf-8" src="diagnostic.js"></script>
|
||||
</head>
|
||||
<body onload="onLoad()">
|
||||
|
||||
<h1>Welcome to my test app.</h1>
|
||||
|
||||
<ul>
|
||||
<li>Checking the diagnostics plugin.</li>
|
||||
<li>Press the button to go to the diagnostics page.</li>
|
||||
</ul>
|
||||
<button type="button" onclick="location.href = 'status.html'" >Diagnostics</button>
|
||||
</body>
|
||||
</html>
|
||||
123
iOS/Diagnostic/example/www/init.js
Normal file
123
iOS/Diagnostic/example/www/init.js
Normal file
@@ -0,0 +1,123 @@
|
||||
|
||||
|
||||
function onLoad() {
|
||||
document.addEventListener("deviceready", onDeviceReady, false);
|
||||
}
|
||||
|
||||
function onDeviceReady() {
|
||||
|
||||
|
||||
|
||||
// To know if the location is turned ON/OFF and if the app is allowed to use it.
|
||||
window.plugins.diagnostic.isLocationEnabled(locationEnabledSuccessCallback, locationEnabledErrorCallback);
|
||||
|
||||
function locationEnabledSuccessCallback(result) {
|
||||
if (result)
|
||||
{
|
||||
//alert("Location ON");
|
||||
document.getElementById('location').innerHTML = 'ON';
|
||||
|
||||
//alert("Location Setting ON");
|
||||
document.getElementById('locationSetting').innerHTML = 'ON';
|
||||
|
||||
//alert("Auth Location ON");
|
||||
document.getElementById('locationAuthorization').innerHTML = 'ON';
|
||||
|
||||
function locationAuthorizedErrorCallback(error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//alert("Location OFF");
|
||||
document.getElementById('location').innerHTML = 'OFF';
|
||||
// To know if the location is turned ON/OFF.
|
||||
window.plugins.diagnostic.isLocationEnabledSetting(locationEnabledSettingSuccessCallback, locationEnabledSettingErrorCallback);
|
||||
|
||||
function locationEnabledSettingSuccessCallback(result) {
|
||||
if (result)
|
||||
{
|
||||
//alert("Location Setting ON");
|
||||
document.getElementById('locationSetting').innerHTML = 'ON';
|
||||
}
|
||||
else
|
||||
{
|
||||
//alert("Location Setting OFF");
|
||||
document.getElementById('locationSetting').innerHTML = 'OFF';
|
||||
}
|
||||
}
|
||||
|
||||
function locationEnabledSettingErrorCallback(error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
// To know if the app is allowed to use it.
|
||||
window.plugins.diagnostic.isLocationAuthorized(locationAuthorizedSuccessCallback, locationAuthorizedErrorCallback);
|
||||
|
||||
function locationAuthorizedSuccessCallback(result) {
|
||||
if (result)
|
||||
{
|
||||
//alert("Auth Location ON");
|
||||
document.getElementById('locationAuthorization').innerHTML = 'ON';
|
||||
}
|
||||
else
|
||||
{
|
||||
//alert("Auth Location OFF");
|
||||
document.getElementById('locationAuthorization').innerHTML = 'OFF';
|
||||
}
|
||||
}
|
||||
|
||||
function locationAuthorizedErrorCallback(error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function locationEnabledErrorCallback(error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
|
||||
// To know if the WiFi is turned ON/OFF.
|
||||
window.plugins.diagnostic.isWifiEnabled(wifiEnabledSuccessCallback, wifiEnabledErrorCallback);
|
||||
|
||||
function wifiEnabledSuccessCallback(result) {
|
||||
if (result)
|
||||
{
|
||||
//alert("WiFi ON");
|
||||
document.getElementById('wifi').innerHTML = 'ON';
|
||||
}
|
||||
else
|
||||
{
|
||||
//alert("WiFi OFF");
|
||||
document.getElementById('wifi').innerHTML = 'OFF';
|
||||
}
|
||||
}
|
||||
|
||||
function wifiEnabledErrorCallback(error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
// To know if the camera is enabled.
|
||||
window.plugins.diagnostic.isCameraEnabled(cameraEnabledSuccessCallback, cameraEnabledErrorCallback);
|
||||
|
||||
function cameraEnabledSuccessCallback(result) {
|
||||
if (result)
|
||||
{
|
||||
//alert("Camera ON");
|
||||
document.getElementById('camera').innerHTML = 'ON';
|
||||
}
|
||||
else
|
||||
{
|
||||
//alert("Camera OFF");
|
||||
document.getElementById('camera').innerHTML = 'OFF';
|
||||
}
|
||||
}
|
||||
|
||||
function cameraEnabledErrorCallback(error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
31
iOS/Diagnostic/example/www/status.html
Normal file
31
iOS/Diagnostic/example/www/status.html
Normal file
@@ -0,0 +1,31 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title></title>
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no;" />
|
||||
<meta charset="utf-8">
|
||||
|
||||
<script type="text/javascript" charset="utf-8" src="cordova-1.7.0rc1.js"></script>
|
||||
<script type="text/javascript" charset="utf-8" src="diagnostic.js"></script>
|
||||
<script type="text/javascript" charset="utf-8" src="init.js"></script>
|
||||
</head>
|
||||
|
||||
<body onload="onLoad()">
|
||||
|
||||
<h1>Diagnostics.</h1>
|
||||
<p>
|
||||
The diagnostic of the iPhone's settings.
|
||||
</p>
|
||||
<ul>
|
||||
<li >Location: <span id="location"></span></li>
|
||||
<ul>
|
||||
<li >Location setting: <span id="locationSetting"></span></li>
|
||||
<li >Location authorization: <span id="locationAuthorization"></span></li>
|
||||
</ul>
|
||||
<li>WiFi Connection: <span id="wifi"></span></li>
|
||||
<li>Camera: <span id="camera"></span></li>
|
||||
</ul>
|
||||
<button type="button" onclick="location.href = 'status.html'" >Refresh</button>
|
||||
</body>
|
||||
</html>
|
||||
@@ -35,7 +35,7 @@ var notification = {
|
||||
// This will fire after 60 seconds
|
||||
local_min:function(){
|
||||
var d = new Date();
|
||||
d = d.getTime() + 3*1000; //60 seconds from now
|
||||
d = d.getTime() + 60*1000; //60 seconds from now
|
||||
d = new Date(d);
|
||||
plugins.localNotification.add({
|
||||
date: d,
|
||||
@@ -43,10 +43,10 @@ var notification = {
|
||||
message: 'This just fired after a minute!',
|
||||
hasAction: true,
|
||||
badge: 1,
|
||||
id: '123',
|
||||
id: '1',
|
||||
sound:'horn.caf',
|
||||
background:'app.background()',
|
||||
foreground:'app.running()'
|
||||
background:'app.background',
|
||||
foreground:'app.running'
|
||||
});
|
||||
},
|
||||
|
||||
@@ -74,10 +74,10 @@ var notification = {
|
||||
message: 'This went off just as expected!',
|
||||
hasAction: true,
|
||||
badge: 1,
|
||||
id: '123',
|
||||
id: '2',
|
||||
sound:'horn.caf',
|
||||
background:'app.background()',
|
||||
foreground:'app.running()'
|
||||
background:'app.background',
|
||||
foreground:'app.running'
|
||||
});
|
||||
},
|
||||
clear:function(){
|
||||
@@ -103,10 +103,10 @@ var notification = {
|
||||
message: 'This went off just as expected!',
|
||||
hasAction: true,
|
||||
badge: 1,
|
||||
id: '123',
|
||||
id: '3',
|
||||
sound:'horn.caf',
|
||||
background:'app.background()',
|
||||
foreground:'app.running()'
|
||||
background:'app.background',
|
||||
foreground:'app.running'
|
||||
});
|
||||
}
|
||||
|
||||
@@ -123,10 +123,10 @@ var app = {
|
||||
init:function(){
|
||||
|
||||
},
|
||||
background:function(){
|
||||
console.log("I was in the background but i'm back now!");
|
||||
background:function(id){
|
||||
console.log("I was in the background but i'm back now! ID="+id);
|
||||
},
|
||||
running:function(){
|
||||
console.log("I am currently running, what should I do?");
|
||||
running:function(id){
|
||||
console.log("I am currently running, what should I do? ID="+id);
|
||||
}
|
||||
};
|
||||
@@ -47,7 +47,7 @@
|
||||
notif.userInfo = userDict;
|
||||
|
||||
[[UIApplication sharedApplication] scheduleLocalNotification:notif];
|
||||
NSLog(@"Notification Set: %@ (ID: %@, Badge: %i, sound: %@,callback: %@)", date, notificationId, badge, sound,bg);
|
||||
NSLog(@"Notification Set: %@ (ID: %@, Badge: %i, sound: %@,background: %@, foreground: %@)", date, notificationId, badge, sound,bg,fg);
|
||||
//[notif release];
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
@@ -136,29 +136,31 @@
|
||||
{
|
||||
|
||||
UIApplicationState state = [application applicationState];
|
||||
if (state == UIApplicationStateInactive) {
|
||||
if (state == UIApplicationStateActive) {
|
||||
// WAS RUNNING
|
||||
NSLog(@"I was currently active");
|
||||
|
||||
NSString *notCB = [notification.userInfo objectForKey:@"foreground"];
|
||||
NSString *notID = [notification.userInfo objectForKey:@"notificationId"];
|
||||
|
||||
NSString * jsCallBack = [NSString
|
||||
stringWithFormat:@"%@(%@)", notCB,notID];
|
||||
|
||||
[self.viewController.webView stringByEvaluatingJavaScriptFromString:jsCallBack];
|
||||
|
||||
application.applicationIconBadgeNumber = 0;
|
||||
}
|
||||
else {
|
||||
// WAS IN BG
|
||||
NSLog(@"I was in the background");
|
||||
|
||||
NSString *notCB = [notification.userInfo objectForKey:@"background"];
|
||||
NSString *notID = [notification.userInfo objectForKey:@"notificationId"];
|
||||
|
||||
NSString * jsCallBack = [NSString
|
||||
stringWithFormat:@"%@", notCB];
|
||||
stringWithFormat:@"%@(%@)", notCB,notID];
|
||||
[self.viewController.webView stringByEvaluatingJavaScriptFromString:jsCallBack];
|
||||
|
||||
application.applicationIconBadgeNumber = 0;
|
||||
|
||||
}
|
||||
else {
|
||||
// WAS RUNNING
|
||||
NSLog(@"I was currently active");
|
||||
|
||||
NSString *notCB = [notification.userInfo objectForKey:@"forground"];
|
||||
NSString * jsCallBack = [NSString
|
||||
stringWithFormat:@"%@", notCB];
|
||||
|
||||
|
||||
[self.viewController.webView stringByEvaluatingJavaScriptFromString:jsCallBack];
|
||||
|
||||
application.applicationIconBadgeNumber = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,12 +42,12 @@
|
||||
notif.soundName = sound;
|
||||
notif.applicationIconBadgeNumber = badge;
|
||||
|
||||
NSDictionary *userDict = [NSDictionary dictionaryWithObjectsAndKeys:notificationId,@"notificationId",bg,@"background",fg,@"forground",nil];
|
||||
NSDictionary *userDict = [NSDictionary dictionaryWithObjectsAndKeys:notificationId,@"notificationId",bg,@"background",fg,@"foreground",nil];
|
||||
|
||||
notif.userInfo = userDict;
|
||||
|
||||
[[UIApplication sharedApplication] scheduleLocalNotification:notif];
|
||||
NSLog(@"Notification Set: %@ (ID: %@, Badge: %i, sound: %@,callback: %@)", date, notificationId, badge, sound,bg);
|
||||
NSLog(@"Notification Set: %@ (ID: %@, Badge: %i, sound: %@,BACKGROUND: %@, FOREGROUND: %@)", date, notificationId, badge, sound,bg,fg);
|
||||
//[notif release];
|
||||
}
|
||||
|
||||
|
||||
@@ -18,8 +18,6 @@ The ability to set repeating notifications has been added!
|
||||
- weekly
|
||||
- monthly
|
||||
- yearly
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
@@ -43,10 +41,10 @@ var notification = {
|
||||
message: 'This just fired after a minute!',
|
||||
hasAction: true,
|
||||
badge: 1,
|
||||
id: '123',
|
||||
id: '1',
|
||||
sound:'horn.caf',
|
||||
background:'app.background()',
|
||||
foreground:'app.running()'
|
||||
background:'app.background',
|
||||
foreground:'app.running'
|
||||
});
|
||||
},
|
||||
|
||||
@@ -74,10 +72,10 @@ var notification = {
|
||||
message: 'This went off just as expected!',
|
||||
hasAction: true,
|
||||
badge: 1,
|
||||
id: '123',
|
||||
id: '2',
|
||||
sound:'horn.caf',
|
||||
background:'app.background()',
|
||||
foreground:'app.running()'
|
||||
background:'app.background',
|
||||
foreground:'app.running'
|
||||
});
|
||||
},
|
||||
clear:function(){
|
||||
@@ -103,10 +101,10 @@ var notification = {
|
||||
message: 'This went off just as expected!',
|
||||
hasAction: true,
|
||||
badge: 1,
|
||||
id: '123',
|
||||
id: '3',
|
||||
sound:'horn.caf',
|
||||
background:'app.background()',
|
||||
foreground:'app.running()'
|
||||
background:'app.background',
|
||||
foreground:'app.running'
|
||||
});
|
||||
}
|
||||
|
||||
@@ -123,10 +121,10 @@ var app = {
|
||||
init:function(){
|
||||
|
||||
},
|
||||
background:function(){
|
||||
console.log("I was in the background but i'm back now!");
|
||||
background:function(id){
|
||||
console.log("I was in the background but i'm back now! ID="+id);
|
||||
},
|
||||
running:function(){
|
||||
console.log("I am currently running, what should I do?");
|
||||
running:function(id){
|
||||
console.log("I am currently running, what should I do? ID="+id);
|
||||
}
|
||||
};
|
||||
@@ -6,7 +6,7 @@ This example goes through in detail how to set a timer for the future based on h
|
||||
It also explains how to create a callback to your app when it is launched from that notification.
|
||||
|
||||
the full write up is here:<br>
|
||||
http://www.drewdahlman.com/meusLabs/?p=84
|
||||
http://www.drewdahlman.com/meusLabs/?p=117
|
||||
|
||||
|
||||
<b>NOTES</b>:<br>
|
||||
@@ -21,34 +21,77 @@ A breakdown of options - <br>
|
||||
|
||||
<b>ADJUSTING AppDelegate</b><br>
|
||||
After you've added LocalNotifications to your plugins you need to make a minor addition to AppDelegate.m
|
||||
|
||||
<b>Cordova 1.7+</b>
|
||||
<pre>
|
||||
// ADD OUR NOTIFICATION CODE
|
||||
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
|
||||
{
|
||||
|
||||
UIApplicationState state = [application applicationState];
|
||||
if (state == UIApplicationStateInactive) {
|
||||
if (state == UIApplicationStateActive) {
|
||||
// WAS RUNNING
|
||||
NSLog(@"I was currently active");
|
||||
|
||||
NSString *notCB = [notification.userInfo objectForKey:@"foreground"];
|
||||
NSString *notID = [notification.userInfo objectForKey:@"notificationId"];
|
||||
|
||||
NSString * jsCallBack = [NSString
|
||||
stringWithFormat:@"%@(%@)", notCB,notID];
|
||||
|
||||
|
||||
[self.viewController.webView stringByEvaluatingJavaScriptFromString:jsCallBack];
|
||||
|
||||
application.applicationIconBadgeNumber = 0;
|
||||
}
|
||||
else {
|
||||
// WAS IN BG
|
||||
NSLog(@"I was in the background");
|
||||
|
||||
NSString *notCB = [notification.userInfo objectForKey:@"background"];
|
||||
NSString * jsCallBack = [NSString
|
||||
stringWithFormat:@"%@", notCB];
|
||||
NSString *notID = [notification.userInfo objectForKey:@"notificationId"];
|
||||
|
||||
NSString * jsCallBack = [NSString
|
||||
stringWithFormat:@"%@(%@)", notCB,notID];
|
||||
[self.viewController.webView stringByEvaluatingJavaScriptFromString:jsCallBack];
|
||||
|
||||
application.applicationIconBadgeNumber = 0;
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
<b>Phonegap</b>
|
||||
<pre>
|
||||
// ADD OUR NOTIFICATION CODE
|
||||
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
|
||||
{
|
||||
|
||||
UIApplicationState state = [application applicationState];
|
||||
if (state == UIApplicationStateActive) {
|
||||
// WAS RUNNING
|
||||
NSLog(@"I was currently active");
|
||||
|
||||
NSString *notCB = [notification.userInfo objectForKey:@"foreground"];
|
||||
NSString *notID = [notification.userInfo objectForKey:@"notificationId"];
|
||||
|
||||
NSString * jsCallBack = [NSString
|
||||
stringWithFormat:@"%@(%@)", notCB,notID];
|
||||
|
||||
|
||||
[self.webView stringByEvaluatingJavaScriptFromString:jsCallBack];
|
||||
|
||||
application.applicationIconBadgeNumber = 0;
|
||||
}
|
||||
else {
|
||||
// WAS RUNNING
|
||||
NSLog(@"I was currently active");
|
||||
// WAS IN BG
|
||||
NSLog(@"I was in the background");
|
||||
|
||||
NSString *notCB = [notification.userInfo objectForKey:@"forground"];
|
||||
NSString * jsCallBack = [NSString
|
||||
stringWithFormat:@"%@", notCB];
|
||||
NSString *notCB = [notification.userInfo objectForKey:@"background"];
|
||||
NSString *notID = [notification.userInfo objectForKey:@"notificationId"];
|
||||
|
||||
NSString * jsCallBack = [NSString
|
||||
stringWithFormat:@"%@(%@)", notCB,notID];
|
||||
|
||||
[self.viewController.webView stringByEvaluatingJavaScriptFromString:jsCallBack];
|
||||
[self.webView stringByEvaluatingJavaScriptFromString:jsCallBack];
|
||||
|
||||
application.applicationIconBadgeNumber = 0;
|
||||
}
|
||||
@@ -58,15 +101,33 @@ Add this code to the end of your AppDelegate.m file in order for the callback fu
|
||||
|
||||
<b>EXAMPLE</b><br>
|
||||
<pre>
|
||||
var d = new Date();
|
||||
d = d.getTime() + 60*1000; //60 seconds from now
|
||||
d = new Date(d);
|
||||
|
||||
window.plugins.localNotification.add({
|
||||
date: d, // your set date object
|
||||
message: 'Hello world!',
|
||||
repeat: 'weekly', // will fire every week on this day
|
||||
badge: 1,
|
||||
foreground:'app.foreground',
|
||||
background:'app.background',
|
||||
foreground:'foreground',
|
||||
background:'background',
|
||||
sound:'sub.caf'
|
||||
});
|
||||
|
||||
function foreground(id){
|
||||
console.log("I WAS RUNNING ID="+id);
|
||||
}
|
||||
function background(id){
|
||||
console.log("I WAS IN THE BACKGROUND ID="+id)
|
||||
}
|
||||
|
||||
</pre>
|
||||
<br>
|
||||
|
||||
<b>UPDATES:</b>
|
||||
<i>5.16.2012</i>
|
||||
- Added Notification ID's to callback.
|
||||
- Fixed spelling error for 'foreground'
|
||||
- Notice that you no longer have to call your background or foreground functions with the (). This is now added by the plugin on the objective-c side of things.
|
||||
|
||||
|
||||
90
iOS/LowLatencyAudio/README.txt
Normal file
90
iOS/LowLatencyAudio/README.txt
Normal file
@@ -0,0 +1,90 @@
|
||||
LowLatencyAudio plugin for PhoneGap/Apache Cordova
|
||||
Developed by Andrew Trice - http://tricedesigns.com
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY ANDREW TRICE "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 ANDREW TRICE 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.
|
||||
|
||||
You can read more about this plugin at:
|
||||
http://www.tricedesigns.com/2012/01/25/low-latency-polyphonic-audio-in-phonegap/
|
||||
|
||||
The low latency audio plugin is designed to enable low latency and polyphonic audio from PhoneGap applications, using a very simple and basic API.
|
||||
|
||||
Getting started:
|
||||
Add the following files to your PhoneGap Plugins directory (and add to XCode Project):
|
||||
LowLatencyAudio.h
|
||||
LowLatencyAudio.m
|
||||
LowLatencyAudioAsset.h
|
||||
LowLatencyAudioAsset.m
|
||||
|
||||
Add the following file to your www directory, and add to index.html:
|
||||
LowLatencyAudio.js
|
||||
|
||||
Add an entry to your PhoneGap.plist file under plugins:
|
||||
Key: LowLatencyAudio
|
||||
Type: String
|
||||
Value: LowLatencyAudio
|
||||
|
||||
Note: If you are using automated reference counting (ARC), you may need to remove retain/release statements.
|
||||
|
||||
Usage:
|
||||
1) Preload the audio asset
|
||||
Note: Make sure to wait for phonegap deviceready event before atteptimpting to load assets
|
||||
2) Play the audio asset
|
||||
3) When done, unload the audio asset
|
||||
|
||||
API methods:
|
||||
preloadFX: function ( id, assetPath, success, fail)
|
||||
params: ID - string unique ID for the audio file
|
||||
assetPath - the relative path to the audio asset within the www directory
|
||||
success - success callback function
|
||||
fail - error/fail callback function
|
||||
detail:
|
||||
The preloadFX function loads an audio file into memory. Assets that are loaded using preloadFX are managed/played using AudioServices methods from the AudioToolbox framework. These are very low-level audio methods and have minimal overhead. Audio loaded using this function is played using AudioServicesPlaySystemSound. These assets should be short, and are not intended to be looped or stopped. They are fully concurrent and polyphonic.
|
||||
|
||||
preloadAudio: function ( id, assetPath, voices, success, fail)
|
||||
params: ID - string unique ID for the audio file
|
||||
assetPath - the relative path to the audio asset within the www directory
|
||||
voices - the number of polyphonic voices available
|
||||
success - success callback function
|
||||
fail - error/fail callback function
|
||||
detail:
|
||||
The preloadAudio function loads an audio file into memory. Assets that are loaded using preloadAudio are managed/played using AVAudioPlayer. These have more overhead than assets laoded via preloadFX, and can be looped/stopped. By default, there is a single "voice" - only one instance that will be stopped & restarted when you hit play. If there are multiple voices (number greater than 0), it will cycle through voices to play overlapping audio.
|
||||
|
||||
play: function (id, success, fail)
|
||||
params: ID - string unique ID for the audio file
|
||||
success - success callback function
|
||||
fail - error/fail callback function
|
||||
detail:
|
||||
Plays an audio asset
|
||||
|
||||
loop: function (id, success, fail)
|
||||
params: ID - string unique ID for the audio file
|
||||
success - success callback function
|
||||
fail - error/fail callback function
|
||||
detail:
|
||||
Loops an audio asset infinitely - this only works for assets loaded via preloadAudio
|
||||
|
||||
stop: function (id, success, fail)
|
||||
params: ID - string unique ID for the audio file
|
||||
success - success callback function
|
||||
fail - error/fail callback function
|
||||
detail:
|
||||
Stops an audio file - this only works for assets loaded via preloadAudio
|
||||
|
||||
unload: function (id, success, fail)
|
||||
params: ID - string unique ID for the audio file
|
||||
success - success callback function
|
||||
fail - error/fail callback function
|
||||
detail:
|
||||
Unloads an audio file from memory
|
||||
|
||||
|
||||
|
||||
BIN
iOS/LowLatencyAudio/examples/basic/assets/cymbal.mp3
Normal file
BIN
iOS/LowLatencyAudio/examples/basic/assets/cymbal.mp3
Normal file
Binary file not shown.
BIN
iOS/LowLatencyAudio/examples/basic/assets/drum.mp3
Normal file
BIN
iOS/LowLatencyAudio/examples/basic/assets/drum.mp3
Normal file
Binary file not shown.
79
iOS/LowLatencyAudio/examples/basic/index.html
Normal file
79
iOS/LowLatencyAudio/examples/basic/index.html
Normal file
@@ -0,0 +1,79 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title></title>
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no;" />
|
||||
<meta charset="utf-8">
|
||||
|
||||
|
||||
<script type="text/javascript" charset="utf-8" src="cordova-1.7.0.js"></script>
|
||||
<script type="text/javascript" charset="utf-8" src="LowLatencyAudio.js"></script>
|
||||
<script type="text/javascript">
|
||||
|
||||
|
||||
function onBodyLoad()
|
||||
{
|
||||
document.addEventListener("deviceready", onDeviceReady, false);
|
||||
}
|
||||
|
||||
function onDeviceReady()
|
||||
{
|
||||
// do your thing!
|
||||
}
|
||||
|
||||
function overlap()
|
||||
{
|
||||
setTimeout( function() {LowLatencyAudio.play('cymbal');}, 300 );
|
||||
setTimeout( function() {LowLatencyAudio.play('drum');}, 600 );
|
||||
setTimeout( function() {LowLatencyAudio.play('cymbal');}, 900 );
|
||||
setTimeout( function() {LowLatencyAudio.play('drum');}, 900 );
|
||||
setTimeout( function() {LowLatencyAudio.play('drum');}, 950 );
|
||||
setTimeout( function() {LowLatencyAudio.play('drum');}, 2000 );
|
||||
setTimeout( function() {LowLatencyAudio.play('cymbal');}, 2000 );
|
||||
}
|
||||
|
||||
function successHandler (result) {
|
||||
alert( result );
|
||||
}
|
||||
|
||||
function errorHandler (error) {
|
||||
alert( error );
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
* {
|
||||
-webkit-overflow-scrolling: none;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color:#FFF;
|
||||
background-image: url('assets/carbonFiber.png');
|
||||
font-size: 40px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body onload="onBodyLoad()">
|
||||
<h1>Hey, it's PhoneGap!</h1>
|
||||
|
||||
<br />
|
||||
<ol>
|
||||
<li><a href="javascript:LowLatencyAudio.preloadAudio('cymbal', 'assets/cymbal.mp3', 3, successHandler, errorHandler);">preload cymbal</a></li>
|
||||
<li><a href="javascript:LowLatencyAudio.preloadFX('drum', 'assets/drum.mp3', successHandler, errorHandler);">preload drum</a></li>
|
||||
<li><a href="javascript:LowLatencyAudio.play('cymbal', successHandler, errorHandler);">play cymbal</a></li>
|
||||
<li><a href="javascript:LowLatencyAudio.play('drum', successHandler, errorHandler);">play drum</a></li>
|
||||
<li><a href="javascript:LowLatencyAudio.unload('cymbal', successHandler, errorHandler);">unload cymbal</a></li>
|
||||
<li><a href="javascript:LowLatencyAudio.unload('drum', successHandler, errorHandler);">unload drum</a></li>
|
||||
<li><a href="javascript:overlap();">overlap</a></li>
|
||||
<li><a href="javascript:LowLatencyAudio.loop('cymbal', successHandler, errorHandler);">loop</a></li>
|
||||
<li><a href="javascript:LowLatencyAudio.stop('cymbal', successHandler, errorHandler);">stop cymbal</a></li>
|
||||
</ol>
|
||||
<ol>
|
||||
<li><a href="javascript:LowLatencyAudio.preloadAudio('cymbal123', 'assets/cymbal123.mp3', 3, successHandler, errorHandler);">error - missing Audio asset</a></li>
|
||||
<li><a href="javascript:LowLatencyAudio.preloadFX('drum123', 'assets/drum123.mp3', successHandler, errorHandler);">error - missing Fx asset</a></li>
|
||||
</ol>
|
||||
</body>
|
||||
</html>
|
||||
41
iOS/LowLatencyAudio/src/LowLatencyAudio.h
Normal file
41
iOS/LowLatencyAudio/src/LowLatencyAudio.h
Normal file
@@ -0,0 +1,41 @@
|
||||
//
|
||||
// PGAudio.h
|
||||
// PGAudio
|
||||
//
|
||||
// Created by Andrew Trice on 1/19/12.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY ANDREW TRICE "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 ANDREW TRICE 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.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <CORDOVA/CDVPlugin.h>
|
||||
#import <AVFoundation/AVAudioPlayer.h>
|
||||
#import "LowLatencyAudioAsset.h"
|
||||
#import <AudioToolbox/AudioToolbox.h>
|
||||
|
||||
@interface LowLatencyAudio : CDVPlugin {
|
||||
NSMutableDictionary* audioMapping;
|
||||
}
|
||||
|
||||
//Public Instance Methods (visible in phonegap API)
|
||||
- (void) preloadFX:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;
|
||||
- (void) preloadAudio:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;
|
||||
- (void) play:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;
|
||||
- (void) stop:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;
|
||||
- (void) loop:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;
|
||||
- (void) unload:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;
|
||||
|
||||
|
||||
//Instance Methods
|
||||
|
||||
|
||||
@end
|
||||
28
iOS/LowLatencyAudio/src/LowLatencyAudio.js
Normal file
28
iOS/LowLatencyAudio/src/LowLatencyAudio.js
Normal file
@@ -0,0 +1,28 @@
|
||||
var LowLatencyAudio = {
|
||||
|
||||
preloadFX: function ( id, assetPath, success, fail) {
|
||||
return cordova.exec(success, fail, "LowLatencyAudio", "preloadFX", [id, assetPath]);
|
||||
},
|
||||
|
||||
preloadAudio: function ( id, assetPath, voices, success, fail) {
|
||||
return cordova.exec(success, fail, "LowLatencyAudio", "preloadAudio", [id, assetPath, voices]);
|
||||
},
|
||||
|
||||
play: function (id, success, fail) {
|
||||
return cordova.exec(success, fail, "LowLatencyAudio", "play", [id]);
|
||||
},
|
||||
|
||||
stop: function (id, success, fail) {
|
||||
return cordova.exec(success, fail, "LowLatencyAudio", "stop", [id]);
|
||||
},
|
||||
|
||||
loop: function (id, success, fail) {
|
||||
return cordova.exec(success, fail, "LowLatencyAudio", "loop", [id]);
|
||||
},
|
||||
|
||||
unload: function (id, success, fail) {
|
||||
return cordova.exec(success, fail, "LowLatencyAudio", "unload", [id]);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
304
iOS/LowLatencyAudio/src/LowLatencyAudio.m
Normal file
304
iOS/LowLatencyAudio/src/LowLatencyAudio.m
Normal file
@@ -0,0 +1,304 @@
|
||||
//
|
||||
// PGAudio.m
|
||||
// PGAudio
|
||||
//
|
||||
// Created by Andrew Trice on 1/19/12.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY ANDREW TRICE "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 ANDREW TRICE 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.
|
||||
//
|
||||
|
||||
#import "LowLatencyAudio.h"
|
||||
|
||||
@implementation LowLatencyAudio
|
||||
|
||||
NSString* ERROR_NOT_FOUND = @"file not found";
|
||||
NSString* WARN_EXISTING_REFERENCE = @"a reference to the audio ID already exists";
|
||||
NSString* ERROR_MISSING_REFERENCE = @"a reference to the audio ID does not exist";
|
||||
NSString* CONTENT_LOAD_REQUESTED = @"content has been requested";
|
||||
NSString* PLAY_REQUESTED = @"PLAY REQUESTED";
|
||||
NSString* STOP_REQUESTED = @"STOP REQUESTED";
|
||||
NSString* UNLOAD_REQUESTED = @"UNLOAD REQUESTED";
|
||||
NSString* RESTRICTED = @"ACTION RESTRICTED FOR FX AUDIO";
|
||||
|
||||
|
||||
- (void) preloadFX:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
|
||||
{
|
||||
CDVPluginResult* pluginResult;
|
||||
NSString* callbackID = [arguments pop];
|
||||
[callbackID retain];
|
||||
|
||||
NSString *audioID = [arguments objectAtIndex:0];
|
||||
[audioID retain];
|
||||
|
||||
NSString *assetPath = [arguments objectAtIndex:1];
|
||||
[assetPath retain];
|
||||
|
||||
if(audioMapping == nil)
|
||||
{
|
||||
audioMapping = [NSMutableDictionary dictionary];
|
||||
[audioMapping retain];
|
||||
}
|
||||
|
||||
NSNumber* existingReference = [audioMapping objectForKey: audioID];
|
||||
if (existingReference == nil)
|
||||
{
|
||||
NSString* basePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"www"];
|
||||
[basePath retain];
|
||||
|
||||
NSString* path = [NSString stringWithFormat:@"%@/%@", basePath, assetPath];
|
||||
[path retain];
|
||||
|
||||
if ([[NSFileManager defaultManager] fileExistsAtPath : path])
|
||||
{
|
||||
NSURL *pathURL = [NSURL fileURLWithPath : path];
|
||||
SystemSoundID soundID;
|
||||
AudioServicesCreateSystemSoundID((CFURLRef) pathURL, & soundID);
|
||||
[audioMapping setObject:[NSNumber numberWithInt:soundID] forKey: audioID];
|
||||
|
||||
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString: CONTENT_LOAD_REQUESTED];
|
||||
[self writeJavascript: [pluginResult toSuccessCallbackString:callbackID]];
|
||||
}
|
||||
else
|
||||
{
|
||||
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString: ERROR_NOT_FOUND];
|
||||
[self writeJavascript: [pluginResult toErrorCallbackString:callbackID]];
|
||||
}
|
||||
|
||||
[basePath release];
|
||||
[path release];
|
||||
}
|
||||
else
|
||||
{
|
||||
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString: WARN_EXISTING_REFERENCE];
|
||||
[self writeJavascript: [pluginResult toSuccessCallbackString:callbackID]];
|
||||
}
|
||||
|
||||
[callbackID release];
|
||||
[audioID release];
|
||||
[assetPath release];
|
||||
}
|
||||
|
||||
- (void) preloadAudio:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
|
||||
{
|
||||
CDVPluginResult* pluginResult;
|
||||
NSString* callbackID = [arguments pop];
|
||||
[callbackID retain];
|
||||
|
||||
NSString *audioID = [arguments objectAtIndex:0];
|
||||
[audioID retain];
|
||||
|
||||
NSString *assetPath = [arguments objectAtIndex:1];
|
||||
[assetPath retain];
|
||||
|
||||
NSNumber *voices;
|
||||
if ( [arguments count] > 2 )
|
||||
{
|
||||
voices = [arguments objectAtIndex:2];
|
||||
}
|
||||
else
|
||||
{
|
||||
voices = [NSNumber numberWithInt:1];
|
||||
}
|
||||
[voices retain];
|
||||
|
||||
if(audioMapping == nil)
|
||||
{
|
||||
audioMapping = [NSMutableDictionary dictionary];
|
||||
[audioMapping retain];
|
||||
}
|
||||
|
||||
NSNumber* existingReference = [audioMapping objectForKey: audioID];
|
||||
if (existingReference == nil)
|
||||
{
|
||||
NSString* basePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"www"];
|
||||
[basePath retain];
|
||||
|
||||
NSString* path = [NSString stringWithFormat:@"%@/%@", basePath, assetPath];
|
||||
[path retain];
|
||||
|
||||
if ([[NSFileManager defaultManager] fileExistsAtPath : path])
|
||||
{
|
||||
LowLatencyAudioAsset* asset = [[LowLatencyAudioAsset alloc] initWithPath:path withVoices:voices];
|
||||
[asset retain];
|
||||
[audioMapping setObject:asset forKey: audioID];
|
||||
|
||||
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString: CONTENT_LOAD_REQUESTED];
|
||||
[self writeJavascript: [pluginResult toSuccessCallbackString:callbackID]];
|
||||
}
|
||||
else
|
||||
{
|
||||
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString: ERROR_NOT_FOUND];
|
||||
[self writeJavascript: [pluginResult toErrorCallbackString:callbackID]];
|
||||
}
|
||||
|
||||
[basePath release];
|
||||
[path release];
|
||||
}
|
||||
else
|
||||
{
|
||||
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString: WARN_EXISTING_REFERENCE];
|
||||
[self writeJavascript: [pluginResult toSuccessCallbackString:callbackID]];
|
||||
}
|
||||
|
||||
[callbackID release];
|
||||
[audioID release];
|
||||
[assetPath release];
|
||||
[voices release];
|
||||
}
|
||||
|
||||
- (void) play:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
|
||||
{
|
||||
CDVPluginResult* pluginResult;
|
||||
NSString* callbackID = [arguments pop];
|
||||
[callbackID retain];
|
||||
|
||||
NSString *audioID = [arguments objectAtIndex:0];
|
||||
[audioID retain];
|
||||
|
||||
if ( audioMapping )
|
||||
{
|
||||
NSObject* asset = [audioMapping objectForKey: audioID];
|
||||
if ([asset isKindOfClass:[LowLatencyAudioAsset class]])
|
||||
{
|
||||
LowLatencyAudioAsset *_asset = (LowLatencyAudioAsset*) asset;
|
||||
[_asset play];
|
||||
}
|
||||
else if ( [asset isKindOfClass:[NSNumber class]] )
|
||||
{
|
||||
NSNumber *_asset = (NSNumber*) asset;
|
||||
AudioServicesPlaySystemSound([_asset intValue]);
|
||||
}
|
||||
|
||||
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString: PLAY_REQUESTED];
|
||||
[self writeJavascript: [pluginResult toSuccessCallbackString:callbackID]];
|
||||
}
|
||||
else
|
||||
{
|
||||
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString: ERROR_MISSING_REFERENCE];
|
||||
[self writeJavascript: [pluginResult toErrorCallbackString:callbackID]];
|
||||
}
|
||||
|
||||
[callbackID release];
|
||||
[audioID release];
|
||||
}
|
||||
|
||||
- (void) stop:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
|
||||
{
|
||||
CDVPluginResult* pluginResult;
|
||||
NSString* callbackID = [arguments pop];
|
||||
[callbackID retain];
|
||||
|
||||
NSString *audioID = [arguments objectAtIndex:0];
|
||||
[audioID retain];
|
||||
|
||||
if ( audioMapping )
|
||||
{
|
||||
NSObject* asset = [audioMapping objectForKey: audioID];
|
||||
if ([asset isKindOfClass:[LowLatencyAudioAsset class]])
|
||||
{
|
||||
LowLatencyAudioAsset *_asset = (LowLatencyAudioAsset*) asset;
|
||||
[_asset stop];
|
||||
|
||||
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString: STOP_REQUESTED];
|
||||
[self writeJavascript: [pluginResult toSuccessCallbackString:callbackID]];
|
||||
}
|
||||
else if ( [asset isKindOfClass:[NSNumber class]] )
|
||||
{
|
||||
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString: RESTRICTED];
|
||||
[self writeJavascript: [pluginResult toErrorCallbackString:callbackID]];
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString: ERROR_MISSING_REFERENCE];
|
||||
[self writeJavascript: [pluginResult toErrorCallbackString:callbackID]];
|
||||
}
|
||||
|
||||
[callbackID release];
|
||||
[audioID release];
|
||||
}
|
||||
|
||||
- (void) loop:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
|
||||
{
|
||||
CDVPluginResult* pluginResult;
|
||||
NSString* callbackID = [arguments pop];
|
||||
[callbackID retain];
|
||||
|
||||
NSString *audioID = [arguments objectAtIndex:0];
|
||||
[audioID retain];
|
||||
|
||||
if ( audioMapping )
|
||||
{
|
||||
NSObject* asset = [audioMapping objectForKey: audioID];
|
||||
if ([asset isKindOfClass:[LowLatencyAudioAsset class]])
|
||||
{
|
||||
LowLatencyAudioAsset *_asset = (LowLatencyAudioAsset*) asset;
|
||||
[_asset loop];
|
||||
|
||||
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString: STOP_REQUESTED];
|
||||
[self writeJavascript: [pluginResult toSuccessCallbackString:callbackID]];
|
||||
}
|
||||
else if ( [asset isKindOfClass:[NSNumber class]] )
|
||||
{
|
||||
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString: RESTRICTED];
|
||||
[self writeJavascript: [pluginResult toErrorCallbackString:callbackID]];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString: ERROR_MISSING_REFERENCE];
|
||||
[self writeJavascript: [pluginResult toErrorCallbackString:callbackID]];
|
||||
}
|
||||
|
||||
[callbackID release];
|
||||
[audioID release];
|
||||
}
|
||||
|
||||
- (void) unload:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
|
||||
{
|
||||
CDVPluginResult* pluginResult;
|
||||
NSString* callbackID = [arguments pop];
|
||||
[callbackID retain];
|
||||
|
||||
NSString *audioID = [arguments objectAtIndex:0];
|
||||
[audioID retain];
|
||||
|
||||
if ( audioMapping )
|
||||
{
|
||||
NSObject* asset = [audioMapping objectForKey: audioID];
|
||||
if ([asset isKindOfClass:[LowLatencyAudioAsset class]])
|
||||
{
|
||||
LowLatencyAudioAsset *_asset = (LowLatencyAudioAsset*) asset;
|
||||
[_asset unload];
|
||||
}
|
||||
else if ( [asset isKindOfClass:[NSNumber class]] )
|
||||
{
|
||||
NSNumber *_asset = (NSNumber*) asset;
|
||||
AudioServicesDisposeSystemSoundID([_asset intValue]);
|
||||
}
|
||||
|
||||
[audioMapping removeObjectForKey: audioID];
|
||||
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString: UNLOAD_REQUESTED];
|
||||
[self writeJavascript: [pluginResult toSuccessCallbackString:callbackID]];
|
||||
}
|
||||
else
|
||||
{
|
||||
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString: ERROR_MISSING_REFERENCE];
|
||||
[self writeJavascript: [pluginResult toErrorCallbackString:callbackID]];
|
||||
}
|
||||
|
||||
[callbackID release];
|
||||
[audioID release];
|
||||
}
|
||||
|
||||
@end
|
||||
34
iOS/LowLatencyAudio/src/LowLatencyAudioAsset.h
Normal file
34
iOS/LowLatencyAudio/src/LowLatencyAudioAsset.h
Normal file
@@ -0,0 +1,34 @@
|
||||
//
|
||||
// PGAudioAsset.h
|
||||
// PGAudio
|
||||
//
|
||||
// Created by Andrew Trice on 1/23/12.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY ANDREW TRICE "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 ANDREW TRICE 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.
|
||||
//
|
||||
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <AVFoundation/AVAudioPlayer.h>
|
||||
|
||||
|
||||
@interface LowLatencyAudioAsset : NSObject {
|
||||
NSMutableArray* voices;
|
||||
int playIndex;
|
||||
}
|
||||
|
||||
-(id) initWithPath:(NSString*) path withVoices:(NSNumber*) numVoices;
|
||||
- (void) play;
|
||||
- (void) stop;
|
||||
- (void) loop;
|
||||
- (void) unload;
|
||||
@end
|
||||
90
iOS/LowLatencyAudio/src/LowLatencyAudioAsset.m
Normal file
90
iOS/LowLatencyAudio/src/LowLatencyAudioAsset.m
Normal file
@@ -0,0 +1,90 @@
|
||||
//
|
||||
// PGAudioAsset.m
|
||||
// PGAudio
|
||||
//
|
||||
// Created by Andrew Trice on 1/23/12.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY ANDREW TRICE "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 ANDREW TRICE 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.
|
||||
//
|
||||
|
||||
#import "LowLatencyAudioAsset.h"
|
||||
|
||||
@implementation LowLatencyAudioAsset
|
||||
|
||||
|
||||
|
||||
-(id) initWithPath:(NSString*) path withVoices:(NSNumber*) numVoices
|
||||
{
|
||||
self = [super init];
|
||||
if(self)
|
||||
{
|
||||
voices = [[NSMutableArray alloc] init];
|
||||
[voices retain];
|
||||
|
||||
NSURL *pathURL = [NSURL fileURLWithPath : path];
|
||||
|
||||
for (int x = 0; x < [numVoices intValue]; x++)
|
||||
{
|
||||
AVAudioPlayer *player;
|
||||
player = [[AVAudioPlayer alloc] initWithContentsOfURL:pathURL error: NULL];
|
||||
[player retain];
|
||||
[player prepareToPlay];
|
||||
[voices addObject:player];
|
||||
}
|
||||
|
||||
playIndex = 0;
|
||||
}
|
||||
return(self);
|
||||
}
|
||||
|
||||
- (void) play
|
||||
{
|
||||
AVAudioPlayer * player = [voices objectAtIndex:playIndex];
|
||||
[player setCurrentTime:0.0];
|
||||
player.numberOfLoops = 0;
|
||||
[player play];
|
||||
playIndex += 1;
|
||||
playIndex = playIndex % [voices count];
|
||||
}
|
||||
|
||||
- (void) stop
|
||||
{
|
||||
for (int x = 0; x < [voices count]; x++)
|
||||
{
|
||||
AVAudioPlayer * player = [voices objectAtIndex:x];
|
||||
[player stop];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) loop
|
||||
{
|
||||
[self stop];
|
||||
AVAudioPlayer * player = [voices objectAtIndex:playIndex];
|
||||
[player setCurrentTime:0.0];
|
||||
player.numberOfLoops = -1;
|
||||
[player play];
|
||||
playIndex += 1;
|
||||
playIndex = playIndex % [voices count];
|
||||
}
|
||||
|
||||
- (void) unload
|
||||
{
|
||||
[self stop];
|
||||
for (int x = 0; x < [voices count]; x++)
|
||||
{
|
||||
AVAudioPlayer * player = [voices objectAtIndex:x];
|
||||
[player release];
|
||||
}
|
||||
[voices release];
|
||||
}
|
||||
|
||||
@end
|
||||
27
iOS/MapKit/AsyncImageView.h
Executable file
27
iOS/MapKit/AsyncImageView.h
Executable file
@@ -0,0 +1,27 @@
|
||||
//
|
||||
// AsyncImage.h
|
||||
// SabreHotels
|
||||
//
|
||||
// Created by Brett Rudd on 19/03/2010.
|
||||
// Copyright 2010 __MyCompanyName__. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
|
||||
@interface AsyncImageView : UIView {
|
||||
//could instead be a subclass of UIImageView instead of UIView, depending on what other features you want to
|
||||
// to build into this class?
|
||||
|
||||
NSURLConnection* connection; //keep a reference to the connection so we can cancel download in dealloc
|
||||
NSMutableData* data; //keep reference to the data so we can collect it as it downloads
|
||||
//but where is the UIImage reference? We keep it in self.subviews - no need to re-code what we have in the parent class
|
||||
|
||||
}
|
||||
|
||||
- (void)loadImageFromURL:(NSURL*)url;
|
||||
- (void)loadDefaultImage;
|
||||
- (UIImage*) image;
|
||||
|
||||
@end
|
||||
|
||||
94
iOS/MapKit/AsyncImageView.m
Executable file
94
iOS/MapKit/AsyncImageView.m
Executable file
@@ -0,0 +1,94 @@
|
||||
//
|
||||
// AsyncImageView.m
|
||||
// Postcard
|
||||
//
|
||||
// Created by markj on 2/18/09.
|
||||
// Copyright 2009 Mark Johnson. You have permission to copy parts of this code into your own projects for any use.
|
||||
// www.markj.net
|
||||
//
|
||||
|
||||
#import "AsyncImageView.h"
|
||||
|
||||
|
||||
// This class demonstrates how the URL loading system can be used to make a UIView subclass
|
||||
// that can download and display an image asynchronously so that the app doesn't block or freeze
|
||||
// while the image is downloading. It works fine in a UITableView or other cases where there
|
||||
// are multiple images being downloaded and displayed all at the same time.
|
||||
|
||||
@implementation AsyncImageView
|
||||
|
||||
- (void)dealloc {
|
||||
[connection cancel]; //in case the URL is still downloading
|
||||
[connection release];
|
||||
[data release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
||||
- (void)loadImageFromURL:(NSURL*)url {
|
||||
if (connection!=nil) { [connection release]; } //in case we are downloading a 2nd image
|
||||
if (data!=nil) { [data release]; }
|
||||
|
||||
NSURLRequest* request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
|
||||
connection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; //notice how delegate set to self object
|
||||
//TODO error handling, what if connection is nil?
|
||||
}
|
||||
|
||||
|
||||
//the URL connection calls this repeatedly as data arrives
|
||||
- (void)connection:(NSURLConnection *)theConnection didReceiveData:(NSData *)incrementalData {
|
||||
if (data==nil) { data = [[NSMutableData alloc] initWithCapacity:2048]; }
|
||||
[data appendData:incrementalData];
|
||||
}
|
||||
|
||||
//the URL connection calls this once all the data has downloaded
|
||||
- (void)connectionDidFinishLoading:(NSURLConnection*)theConnection {
|
||||
//so self data now has the complete image
|
||||
[connection release];
|
||||
connection=nil;
|
||||
if ([[self subviews] count]>0) {
|
||||
//then this must be another image, the old one is still in subviews
|
||||
[[[self subviews] objectAtIndex:0] removeFromSuperview]; //so remove it (releases it also)
|
||||
}
|
||||
|
||||
//make an image view for the image
|
||||
UIImageView* imageView = [[[UIImageView alloc] initWithImage:[UIImage imageWithData:data]] autorelease];
|
||||
//make sizing choices based on your needs, experiment with these. maybe not all the calls below are needed.
|
||||
imageView.contentMode = UIViewContentModeScaleAspectFit;
|
||||
imageView.autoresizingMask = ( UIViewAutoresizingFlexibleWidth || UIViewAutoresizingFlexibleHeight );
|
||||
[self addSubview:imageView];
|
||||
imageView.frame = self.bounds;
|
||||
[imageView setNeedsLayout];
|
||||
[self setNeedsLayout];
|
||||
|
||||
[data release]; //don't need this any more, its in the UIImageView now
|
||||
data=nil;
|
||||
}
|
||||
|
||||
//in case we want a local image
|
||||
- (void)loadDefaultImage {
|
||||
|
||||
if ([[self subviews] count]>0) {
|
||||
//then this must be another image, the old one is still in subviews
|
||||
[[[self subviews] objectAtIndex:0] removeFromSuperview]; //so remove it (releases it also)
|
||||
}
|
||||
|
||||
//make an image view for the image
|
||||
UIImageView* imageView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"icon.png"]] autorelease];
|
||||
//make sizing choices based on your needs, experiment with these. maybe not all the calls below are needed.
|
||||
imageView.contentMode = UIViewContentModeScaleAspectFit;
|
||||
imageView.autoresizingMask = ( UIViewAutoresizingFlexibleWidth || UIViewAutoresizingFlexibleHeight );
|
||||
[self addSubview:imageView];
|
||||
imageView.frame = self.bounds;
|
||||
[imageView setNeedsLayout];
|
||||
[self setNeedsLayout];
|
||||
|
||||
}
|
||||
|
||||
//just in case you want to get the image directly, here it is in subviews
|
||||
- (UIImage*) image {
|
||||
UIImageView* iv = [[self subviews] objectAtIndex:0];
|
||||
return [iv image];
|
||||
}
|
||||
|
||||
@end
|
||||
38
iOS/MapKit/CDVAnnotation.h
Executable file
38
iOS/MapKit/CDVAnnotation.h
Executable file
@@ -0,0 +1,38 @@
|
||||
//
|
||||
// CDVAnnotation.h
|
||||
// Cordova
|
||||
//
|
||||
// Created by Brett Rudd on 17/03/2010.
|
||||
// Copyright 2010 __MyCompanyName__. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <MapKit/MapKit.h>
|
||||
|
||||
@interface CDVAnnotation : NSObject <MKAnnotation> {
|
||||
@private
|
||||
CLLocationCoordinate2D _coordinate;
|
||||
NSString *_title;
|
||||
NSString *_subTitle;
|
||||
NSString *_imageURL;
|
||||
NSInteger _index;
|
||||
MKPlacemark *_placemark;
|
||||
NSString *pinColor;
|
||||
BOOL selected;
|
||||
}
|
||||
|
||||
@property (nonatomic, copy) NSString *title;
|
||||
@property (nonatomic, copy) NSString *subTitle;
|
||||
@property (nonatomic, copy) NSString *imageURL;
|
||||
@property (nonatomic, assign) NSInteger index;
|
||||
@property (nonatomic, retain) MKPlacemark *placemark;
|
||||
@property (nonatomic, assign) CLLocationCoordinate2D coordinate;
|
||||
@property (nonatomic, copy) NSString *pinColor;
|
||||
@property (nonatomic, assign) BOOL selected;
|
||||
|
||||
- (void)notifyCalloutInfo:(MKPlacemark *)placemark;
|
||||
- (id)initWithCoordinate:(CLLocationCoordinate2D)coordinate index:(NSInteger)index title:(NSString*)title subTitle:(NSString*)subTitle imageURL:(NSString*)imageURL;
|
||||
|
||||
@end
|
||||
|
||||
50
iOS/MapKit/CDVAnnotation.m
Executable file
50
iOS/MapKit/CDVAnnotation.m
Executable file
@@ -0,0 +1,50 @@
|
||||
//
|
||||
// PHAnnotation.m
|
||||
// PhoneGapLib
|
||||
//
|
||||
// Created by Brett Rudd on 17/03/2010.
|
||||
// Copyright 2010 __MyCompanyName__. All rights reserved.
|
||||
//
|
||||
|
||||
#import "CDVAnnotation.h"
|
||||
|
||||
@implementation CDVAnnotation
|
||||
|
||||
@synthesize title = _title;
|
||||
@synthesize subTitle = _subTitle;
|
||||
@synthesize index = _index;
|
||||
@synthesize placemark = _placemark;
|
||||
@synthesize imageURL = _imageURL;
|
||||
@synthesize coordinate = _coordinate;
|
||||
@synthesize pinColor;
|
||||
@synthesize selected;
|
||||
|
||||
- (id)initWithCoordinate:(CLLocationCoordinate2D)coordinate index:(NSInteger)index title:(NSString*)title subTitle:(NSString*)subTitle imageURL:(NSString*)imageURL {
|
||||
if ((self = [super init])) {
|
||||
_coordinate=coordinate;
|
||||
_title = [title retain];
|
||||
_subTitle = [subTitle retain];
|
||||
_index=index;
|
||||
_imageURL=[imageURL retain];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSString *)title {
|
||||
return _title;
|
||||
}
|
||||
|
||||
- (NSString *)subtitle {
|
||||
return _subTitle;
|
||||
}
|
||||
|
||||
- (void)notifyCalloutInfo:(MKPlacemark *)newPlacemark {
|
||||
[[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:@"MKAnnotationCalloutInfoDidChangeNotification" object:self]];
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[_title release], _title = nil;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@end
|
||||
42
iOS/MapKit/MapKit.h
Normal file
42
iOS/MapKit/MapKit.h
Normal file
@@ -0,0 +1,42 @@
|
||||
//
|
||||
// UIControls.h
|
||||
// Cordova
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <MapKit/MapKit.h>
|
||||
|
||||
#ifdef CORDOVA_FRAMEWORK
|
||||
#import <Cordova/CDVPlugin.h>
|
||||
#else
|
||||
#import "CDVPlugin.h"
|
||||
#endif
|
||||
|
||||
|
||||
@interface MapKitView : CDVPlugin <MKMapViewDelegate>
|
||||
{
|
||||
}
|
||||
|
||||
@property (nonatomic, copy) NSString *buttonCallback;
|
||||
@property (nonatomic, retain) UIView* childView;
|
||||
@property (nonatomic, retain) MKMapView* mapView;
|
||||
@property (nonatomic, retain) UIButton* imageButton;
|
||||
|
||||
- (void)createView;
|
||||
|
||||
- (void)showMap:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;
|
||||
|
||||
- (void)hideMap:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;
|
||||
|
||||
- (void)destroyMap:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;
|
||||
|
||||
- (void)clearMapPins:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;
|
||||
|
||||
- (void)addMapPins:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;
|
||||
|
||||
- (void)setMapData:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;
|
||||
|
||||
- (void) closeButton:(id)button;
|
||||
|
||||
@end
|
||||
73
iOS/MapKit/MapKit.js
Normal file
73
iOS/MapKit/MapKit.js
Normal file
@@ -0,0 +1,73 @@
|
||||
(function(window) {
|
||||
|
||||
/*
|
||||
* 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) 2005-2010, Nitobi Software Inc., Brett Rudd, Jesse MacFadyen
|
||||
*/
|
||||
|
||||
var cordovaRef = window.PhoneGap || window.Cordova || window.cordova;
|
||||
|
||||
var MapKit = function() {
|
||||
this.options = {
|
||||
buttonCallback: 'window.plugins.mapKit.onMapCallback',
|
||||
height: 460,
|
||||
diameter: 1000,
|
||||
atBottom: true,
|
||||
lat: 49.281468,
|
||||
lon: -123.104446
|
||||
};
|
||||
}
|
||||
|
||||
MapKit.prototype = {
|
||||
|
||||
onMapCallback: function(pindex) {
|
||||
alert('You selected pin : ' + pindex);
|
||||
},
|
||||
|
||||
showMap: function() {
|
||||
cordovaRef.exec('MapKitView.showMap');
|
||||
},
|
||||
|
||||
setMapData: function(options) {
|
||||
/*
|
||||
buttonCallback: String, string callback function
|
||||
height: Number, - pixels
|
||||
diameter: Number, - meters
|
||||
atBottom: Bool,
|
||||
lat: Number,
|
||||
lon: Number
|
||||
*/
|
||||
for (var v in options) {
|
||||
if (options.hasOwnProperty(v)) {
|
||||
this.options[v] = options[v];
|
||||
}
|
||||
}
|
||||
cordovaRef.exec('MapKitView.setMapData', this.options);
|
||||
},
|
||||
|
||||
addMapPins: function(pins) {
|
||||
var pinStr = '[]';
|
||||
if (pins) {
|
||||
pinStr = JSON.stringify(pins);
|
||||
}
|
||||
cordovaRef.exec('MapKitView.addMapPins', pinStr);
|
||||
},
|
||||
|
||||
clearMapPins: function() {
|
||||
cordovaRef.exec('MapKitView.clearMapPins');
|
||||
},
|
||||
|
||||
hideMap: function() {
|
||||
cordovaRef.exec('MapKitView.hideMap', {});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
cordovaRef.addConstructor(function() {
|
||||
window.plugins = window.plugins || {};
|
||||
window.plugins.mapKit = new MapKit();
|
||||
});
|
||||
|
||||
}(window));
|
||||
303
iOS/MapKit/MapKit.m
Normal file
303
iOS/MapKit/MapKit.m
Normal file
@@ -0,0 +1,303 @@
|
||||
//
|
||||
// Cordova
|
||||
//
|
||||
//
|
||||
|
||||
#import "MapKit.h"
|
||||
#import "CDVAnnotation.h"
|
||||
#import "AsyncImageView.h"
|
||||
|
||||
#ifdef CORDOVA_FRAMEWORK
|
||||
// PhoneGap >= 1.2.0
|
||||
#import <Cordova/JSONKit.h>
|
||||
#else
|
||||
// https://github.com/johnezang/JSONKit
|
||||
#import "JSONKit.h"
|
||||
#endif
|
||||
|
||||
@implementation MapKitView
|
||||
|
||||
@synthesize buttonCallback;
|
||||
@synthesize childView;
|
||||
@synthesize mapView;
|
||||
@synthesize imageButton;
|
||||
|
||||
|
||||
-(CDVPlugin*) initWithWebView:(UIWebView*)theWebView
|
||||
{
|
||||
self = (MapKitView*)[super initWithWebView:theWebView];
|
||||
return self;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a native map view
|
||||
*/
|
||||
- (void)createView
|
||||
{
|
||||
self.childView = [[UIView alloc] init];
|
||||
self.mapView = [[MKMapView alloc] init];
|
||||
[self.mapView sizeToFit];
|
||||
self.mapView.delegate = self;
|
||||
self.mapView.multipleTouchEnabled = YES;
|
||||
self.mapView.autoresizesSubviews = YES;
|
||||
self.mapView.userInteractionEnabled = YES;
|
||||
self.mapView.showsUserLocation = YES;
|
||||
self.mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
||||
self.childView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
||||
|
||||
self.imageButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||
|
||||
[self.childView addSubview:self.mapView];
|
||||
[self.childView addSubview:self.imageButton];
|
||||
|
||||
[ [ [ self viewController ] view ] addSubview:self.childView];
|
||||
}
|
||||
|
||||
- (void)mapView:(MKMapView *)theMapView regionDidChangeAnimated: (BOOL)animated
|
||||
{
|
||||
float currentLat = theMapView.region.center.latitude;
|
||||
float currentLon = theMapView.region.center.longitude;
|
||||
float latitudeDelta = theMapView.region.span.latitudeDelta;
|
||||
float longitudeDelta = theMapView.region.span.longitudeDelta;
|
||||
|
||||
NSString* jsString = nil;
|
||||
jsString = [[NSString alloc] initWithFormat:@"geo.onMapMove(\'%f','%f','%f','%f\');", currentLat,currentLon,latitudeDelta,longitudeDelta];
|
||||
[self.webView stringByEvaluatingJavaScriptFromString:jsString];
|
||||
[jsString autorelease];
|
||||
}
|
||||
|
||||
- (void)destroyMap:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
|
||||
{
|
||||
if (self.mapView)
|
||||
{
|
||||
[ self.mapView removeAnnotations:mapView.annotations];
|
||||
[ self.mapView removeFromSuperview];
|
||||
|
||||
mapView = nil;
|
||||
}
|
||||
if(self.imageButton)
|
||||
{
|
||||
[ self.imageButton removeFromSuperview];
|
||||
[ self.imageButton removeTarget:self action:@selector(closeButton:) forControlEvents:UIControlEventTouchUpInside];
|
||||
self.imageButton = nil;
|
||||
|
||||
}
|
||||
if(self.childView)
|
||||
{
|
||||
[ self.childView removeFromSuperview];
|
||||
self.childView = nil;
|
||||
}
|
||||
self.buttonCallback = nil;
|
||||
}
|
||||
|
||||
- (void)clearMapPins:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;
|
||||
{
|
||||
[self.mapView removeAnnotations:self.mapView.annotations];
|
||||
}
|
||||
|
||||
- (void)addMapPins:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;
|
||||
{
|
||||
|
||||
NSArray *pins = [[arguments objectAtIndex:0] objectFromJSONString];
|
||||
|
||||
for (int y = 0; y < pins.count; y++)
|
||||
{
|
||||
NSDictionary *pinData = [pins objectAtIndex:y];
|
||||
CLLocationCoordinate2D pinCoord = { [[pinData objectForKey:@"lat"] floatValue] , [[pinData objectForKey:@"lon"] floatValue] };
|
||||
NSString *title=[[pinData valueForKey:@"title"] description];
|
||||
NSString *subTitle=[[pinData valueForKey:@"subTitle"] description];
|
||||
NSString *imageURL=[[pinData valueForKey:@"imageURL"] description];
|
||||
NSString *pinColor=[[pinData valueForKey:@"pinColor"] description];
|
||||
NSInteger index=[[pinData valueForKey:@"index"] integerValue];
|
||||
BOOL selected = [[pinData valueForKey:@"selected"] boolValue];
|
||||
|
||||
CDVAnnotation *annotation = [[CDVAnnotation alloc] initWithCoordinate:pinCoord index:index title:title subTitle:subTitle imageURL:imageURL];
|
||||
annotation.pinColor=pinColor;
|
||||
annotation.selected = selected;
|
||||
|
||||
[self.mapView addAnnotation:annotation];
|
||||
[annotation release];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set annotations and mapview settings
|
||||
*/
|
||||
- (void)setMapData:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;\
|
||||
{
|
||||
if (!self.mapView)
|
||||
{
|
||||
[self createView];
|
||||
}
|
||||
|
||||
// defaults
|
||||
CGFloat height = 480.0f;
|
||||
CGFloat offsetTop = 0.0f;
|
||||
|
||||
if ([options objectForKey:@"height"])
|
||||
{
|
||||
height=[[options objectForKey:@"height"] floatValue];
|
||||
}
|
||||
if ([options objectForKey:@"offsetTop"])
|
||||
{
|
||||
offsetTop=[[options objectForKey:@"offsetTop"] floatValue];
|
||||
}
|
||||
if ([options objectForKey:@"buttonCallback"])
|
||||
{
|
||||
self.buttonCallback=[[options objectForKey:@"buttonCallback"] description];
|
||||
}
|
||||
|
||||
CLLocationCoordinate2D centerCoord = { [[options objectForKey:@"lat"] floatValue] , [[options objectForKey:@"lon"] floatValue] };
|
||||
CLLocationDistance diameter = [[options objectForKey:@"diameter"] floatValue];
|
||||
|
||||
CGRect webViewBounds = self.webView.bounds;
|
||||
|
||||
CGRect mapBounds;
|
||||
mapBounds = CGRectMake(
|
||||
webViewBounds.origin.x,
|
||||
webViewBounds.origin.y + (offsetTop / 2),
|
||||
webViewBounds.size.width,
|
||||
webViewBounds.origin.y + height
|
||||
);
|
||||
|
||||
[self.childView setFrame:mapBounds];
|
||||
[self.mapView setFrame:mapBounds];
|
||||
|
||||
MKCoordinateRegion region=[ self.mapView regionThatFits: MKCoordinateRegionMakeWithDistance(centerCoord,
|
||||
diameter*(height / webViewBounds.size.width),
|
||||
diameter*(height / webViewBounds.size.width))];
|
||||
[self.mapView setRegion:region animated:YES];
|
||||
|
||||
CGRect frame = CGRectMake(285.0,12.0, 29.0, 29.0);
|
||||
|
||||
[ self.imageButton setImage:[UIImage imageNamed:@"www/map-close-button.png"] forState:UIControlStateNormal];
|
||||
[ self.imageButton setFrame:frame];
|
||||
[ self.imageButton addTarget:self action:@selector(closeButton:) forControlEvents:UIControlEventTouchUpInside];
|
||||
}
|
||||
|
||||
- (void) closeButton:(id)button
|
||||
{
|
||||
[ self hideMap:NULL withDict:NULL];
|
||||
NSString* jsString = [NSString stringWithFormat:@"%@(\"%i\");", self.buttonCallback,-1];
|
||||
[self.webView stringByEvaluatingJavaScriptFromString:jsString];
|
||||
}
|
||||
|
||||
- (void)showMap:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
|
||||
{
|
||||
if (!self.mapView)
|
||||
{
|
||||
[self createView];
|
||||
}
|
||||
self.childView.hidden = NO;
|
||||
self.mapView.showsUserLocation = YES;
|
||||
}
|
||||
|
||||
|
||||
- (void)hideMap:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
|
||||
{
|
||||
if (!self.mapView || self.childView.hidden==YES)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// disable location services, if we no longer need it.
|
||||
self.mapView.showsUserLocation = NO;
|
||||
self.childView.hidden = YES;
|
||||
}
|
||||
|
||||
- (MKAnnotationView *) mapView:(MKMapView *)theMapView viewForAnnotation:(id <MKAnnotation>) annotation {
|
||||
|
||||
if ([annotation class] != CDVAnnotation.class) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
CDVAnnotation *phAnnotation=(CDVAnnotation *) annotation;
|
||||
NSString *identifier=[NSString stringWithFormat:@"INDEX[%i]", phAnnotation.index];
|
||||
|
||||
MKPinAnnotationView *annView = (MKPinAnnotationView *)[theMapView dequeueReusableAnnotationViewWithIdentifier:identifier];
|
||||
|
||||
if (annView!=nil) return annView;
|
||||
|
||||
annView=[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
|
||||
|
||||
annView.animatesDrop=YES;
|
||||
annView.canShowCallout = YES;
|
||||
if ([phAnnotation.pinColor isEqualToString:@"green"])
|
||||
annView.pinColor = MKPinAnnotationColorGreen;
|
||||
else if ([phAnnotation.pinColor isEqualToString:@"purple"])
|
||||
annView.pinColor = MKPinAnnotationColorPurple;
|
||||
else
|
||||
annView.pinColor = MKPinAnnotationColorRed;
|
||||
|
||||
AsyncImageView* asyncImage = [[[AsyncImageView alloc] initWithFrame:CGRectMake(0,0, 50, 32)] autorelease];
|
||||
asyncImage.tag = 999;
|
||||
if (phAnnotation.imageURL)
|
||||
{
|
||||
NSURL *url = [[NSURL alloc] initWithString:phAnnotation.imageURL];
|
||||
[asyncImage loadImageFromURL:url];
|
||||
[ url release ];
|
||||
}
|
||||
else
|
||||
{
|
||||
[asyncImage loadDefaultImage];
|
||||
}
|
||||
|
||||
annView.leftCalloutAccessoryView = asyncImage;
|
||||
|
||||
|
||||
if (self.buttonCallback && phAnnotation.index!=-1)
|
||||
{
|
||||
|
||||
UIButton *myDetailButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
|
||||
myDetailButton.frame = CGRectMake(0, 0, 23, 23);
|
||||
myDetailButton.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
|
||||
myDetailButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
|
||||
myDetailButton.tag=phAnnotation.index;
|
||||
annView.rightCalloutAccessoryView = myDetailButton;
|
||||
[ myDetailButton addTarget:self action:@selector(checkButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
|
||||
|
||||
}
|
||||
|
||||
if(phAnnotation.selected)
|
||||
{
|
||||
[self performSelector:@selector(openAnnotation:) withObject:phAnnotation afterDelay:1.0];
|
||||
}
|
||||
|
||||
return [annView autorelease];
|
||||
}
|
||||
|
||||
-(void)openAnnotation:(id <MKAnnotation>) annotation
|
||||
{
|
||||
[ self.mapView selectAnnotation:annotation animated:YES];
|
||||
|
||||
}
|
||||
|
||||
- (void) checkButtonTapped:(id)button
|
||||
{
|
||||
UIButton *tmpButton = button;
|
||||
NSString* jsString = [NSString stringWithFormat:@"%@(\"%i\");", self.buttonCallback, tmpButton.tag];
|
||||
[self.webView stringByEvaluatingJavaScriptFromString:jsString];
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
if (self.mapView)
|
||||
{
|
||||
[ self.mapView removeAnnotations:mapView.annotations];
|
||||
[ self.mapView removeFromSuperview];
|
||||
self.mapView = nil;
|
||||
}
|
||||
if(self.imageButton)
|
||||
{
|
||||
[ self.imageButton removeFromSuperview];
|
||||
self.imageButton = nil;
|
||||
}
|
||||
if(childView)
|
||||
{
|
||||
[ self.childView removeFromSuperview];
|
||||
self.childView = nil;
|
||||
}
|
||||
self.buttonCallback = nil;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@end
|
||||
11
iOS/MapKit/README.md
Normal file
11
iOS/MapKit/README.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# PhoneGap iOS Map Plugin #
|
||||
|
||||
## Adding the Plugin to your project ##
|
||||
|
||||
Using this plugin requires [iOS PhoneGap](http://github.com/phonegap/phonegap-iphone) and the MapKit framework.
|
||||
|
||||
1. Add the "MapKit" framework to your Xcode project (different in Xcode 3 and 4, search for instructions)
|
||||
2. Add the .h and .m files to your Plugins folder in your project
|
||||
3. Add the .js files to your "www" folder on disk, and add reference(s) to the .js files as <script> tags in your html file(s)
|
||||
4. In your app's [APPNAME]-Info.plist, expand "Plugins", and add a new string key and value under it. For the key, add "MapKitView" (left column) for the key, and add "MapKitView" for the value (right column).
|
||||
|
||||
BIN
iOS/MapKit/icon.png
Normal file
BIN
iOS/MapKit/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.1 KiB |
BIN
iOS/MapKit/map-close-button.png
Normal file
BIN
iOS/MapKit/map-close-button.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
@@ -188,14 +188,7 @@ NativeControls.prototype.hideToolBar = function() {
|
||||
NativeControls.prototype.showToolBar = function() {
|
||||
cordova.exec("NativeControls.showToolBar");
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the toolbar title
|
||||
* @param: title
|
||||
*/
|
||||
NativeControls.prototype.setToolBarTitle = function(title) {
|
||||
cordova.exec("NativeControls.setToolBarTitle" , title );
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
||||
17
iOS/OCRPlugin/OCRPlugin.h
Normal file
17
iOS/OCRPlugin/OCRPlugin.h
Normal file
@@ -0,0 +1,17 @@
|
||||
//
|
||||
// OCRPlugin.h
|
||||
// pruebaTesseract
|
||||
//
|
||||
// Created by Admin on 09/06/12.
|
||||
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
|
||||
//
|
||||
#import <Cordova/CDV.h>
|
||||
@class claseAuxiliar;
|
||||
|
||||
@interface OCRPlugin : CDVPlugin
|
||||
|
||||
@property (nonatomic, copy) NSString* callbackID;
|
||||
|
||||
- (void) recogniseOCR:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;
|
||||
|
||||
@end
|
||||
82
iOS/OCRPlugin/OCRPlugin.m
Normal file
82
iOS/OCRPlugin/OCRPlugin.m
Normal file
@@ -0,0 +1,82 @@
|
||||
//
|
||||
// OCRPlugin.m
|
||||
// pruebaTesseract
|
||||
//
|
||||
// Created by Admin on 09/06/12.
|
||||
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
|
||||
//
|
||||
|
||||
#import "OCRPlugin.h"
|
||||
#import "claseAuxiliar.h"
|
||||
|
||||
@implementation OCRPlugin
|
||||
@synthesize callbackID;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
- (void) recogniseOCR:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options { //get the callback id
|
||||
|
||||
NSString *url_string = [options objectForKey:@"url_imagen"];
|
||||
self.callbackID = [arguments pop];
|
||||
|
||||
claseAuxiliar *cA = [[claseAuxiliar alloc]init];
|
||||
|
||||
NSURL *url = [NSURL URLWithString:url_string];
|
||||
NSData *data = [NSData dataWithContentsOfURL:url];
|
||||
UIImage *Realimage = [[UIImage alloc] initWithData:data];
|
||||
|
||||
UIImage *newImage = [cA resizeImage:Realimage];
|
||||
|
||||
NSString *text = [cA ocrImage:newImage];
|
||||
[self performSelectorOnMainThread:@selector(ocrProcessingFinished:)
|
||||
withObject:text
|
||||
waitUntilDone:NO];
|
||||
|
||||
|
||||
[cA release];
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
- (void)ocrProcessingFinished:(NSString *)result
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
// Create Plugin Result
|
||||
|
||||
CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
|
||||
messageAsString: result ];
|
||||
|
||||
|
||||
// Checking if the string received is HelloWorld or not
|
||||
|
||||
if (result == nil
|
||||
|| ([result respondsToSelector:@selector(length)]
|
||||
&& [(NSData *)result length] == 0)
|
||||
|| ([result respondsToSelector:@selector(count)]
|
||||
&& [(NSArray *)result count] == 0))
|
||||
|
||||
{
|
||||
// Call the Failure Javascript function
|
||||
|
||||
[self writeJavascript: [pluginResult toErrorCallbackString:self.callbackID]];
|
||||
|
||||
|
||||
} else
|
||||
|
||||
{
|
||||
|
||||
// Call the Success Javascript function
|
||||
|
||||
[self writeJavascript: [pluginResult toSuccessCallbackString:self.callbackID]];
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
57
iOS/OCRPlugin/README.md
Normal file
57
iOS/OCRPlugin/README.md
Normal file
@@ -0,0 +1,57 @@
|
||||
PhonegapOCRPlugin
|
||||
=================
|
||||
|
||||
ocr plugin for phonegap using tesseract
|
||||
|
||||
drag the tessdata folder to your phonegap project
|
||||
mark the checkbox "copy items into destination group"
|
||||
Choose the radio-button "Create folder references for any added folders"
|
||||
|
||||
drag the dependencies folder to your phonegap project
|
||||
mark the checkbox "copy items into destination group"
|
||||
Choose the radio-button "Created groups for any added folders"
|
||||
|
||||
drag OCRPlugin.h, OCRPlugin.m, claseAuxiliar.h and claseAuxiliar.mm
|
||||
|
||||
drag OCRPlugin.js to your www folder
|
||||
|
||||
Add the plugin to cordova.xml
|
||||
|
||||
com.jcesarmobile.OCRPlugin OCRPlugin
|
||||
|
||||
|
||||
Thanks to suzuki for compiling tesseract in this post
|
||||
http://tinsuke.wordpress.com/2011/11/01/how-to-compile-and-use-tesseract-3-01-on-ios-sdk-5
|
||||
|
||||
I have included an index.html with an example.
|
||||
|
||||
It uses the camera function with destinationType.FILE_URI (IMPORTANT!!!)
|
||||
|
||||
|
||||
// A button will call this function
|
||||
//
|
||||
function capturePhoto() {
|
||||
// Take picture using device camera and retrieve image as base64-encoded string
|
||||
navigator.camera.getPicture(onPhotoURISuccess, onFail, { quality: 100,
|
||||
destinationType: destinationType.FILE_URI });
|
||||
}
|
||||
|
||||
// Call the plugin when a photo is successfully retrieved
|
||||
//
|
||||
function onPhotoURISuccess(imageURI) {
|
||||
callNativePlugin({url_imagen: imageURI});
|
||||
}
|
||||
|
||||
|
||||
function callNativePlugin( returnSuccess ) {
|
||||
OCRPlugin.callNativeFunction( nativePluginResultHandler, nativePluginErrorHandler, returnSuccess );
|
||||
}
|
||||
|
||||
function nativePluginResultHandler (result) {
|
||||
alert("ok: "+result);
|
||||
}
|
||||
|
||||
function nativePluginErrorHandler (error) {
|
||||
alert("error: "+error);
|
||||
}
|
||||
|
||||
42
iOS/OCRPlugin/claseAuxiliar.h
Normal file
42
iOS/OCRPlugin/claseAuxiliar.h
Normal file
@@ -0,0 +1,42 @@
|
||||
//
|
||||
// claseAuxiliar.h
|
||||
// pruebaTesseract
|
||||
//
|
||||
// Created by Admin on 03/06/12.
|
||||
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
|
||||
//
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include "baseapi.h"
|
||||
using namespace tesseract;
|
||||
#else
|
||||
@class TessBaseAPI;
|
||||
#endif
|
||||
|
||||
|
||||
@interface claseAuxiliar : NSObject {
|
||||
|
||||
|
||||
TessBaseAPI *tesseract;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
-(NSString *) ocrImage: (UIImage *) uiImage;
|
||||
-(UIImage *)resizeImage:(UIImage *)image;
|
||||
|
||||
|
||||
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
131
iOS/OCRPlugin/claseAuxiliar.mm
Normal file
131
iOS/OCRPlugin/claseAuxiliar.mm
Normal file
@@ -0,0 +1,131 @@
|
||||
//
|
||||
// claseAuxiliar.m
|
||||
// pruebaTesseract
|
||||
//
|
||||
// Created by Admin on 03/06/12.
|
||||
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
|
||||
//
|
||||
|
||||
#import "claseAuxiliar.h"
|
||||
|
||||
|
||||
#include "baseapi.h"
|
||||
|
||||
//#include "environ.h"
|
||||
//#import "pix.h"
|
||||
|
||||
static inline double radians (double degrees) {return degrees * M_PI/180;}
|
||||
|
||||
@implementation claseAuxiliar
|
||||
|
||||
-(id)init {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
// Set up the tessdata path. This is included in the application bundle
|
||||
// but is copied to the Documents directory on the first run.
|
||||
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
|
||||
NSString *documentPath = ([documentPaths count] > 0) ? [documentPaths objectAtIndex:0] : nil;
|
||||
|
||||
NSString *dataPath = [documentPath stringByAppendingPathComponent:@"tessdata"];
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
// If the expected store doesn't exist, copy the default store.
|
||||
if (![fileManager fileExistsAtPath:dataPath]) {
|
||||
// get the path to the app bundle (with the tessdata dir)
|
||||
NSString *bundlePath = [[NSBundle mainBundle] bundlePath];
|
||||
NSString *tessdataPath = [bundlePath stringByAppendingPathComponent:@"tessdata"];
|
||||
if (tessdataPath) {
|
||||
[fileManager copyItemAtPath:tessdataPath toPath:dataPath error:NULL];
|
||||
}
|
||||
}
|
||||
|
||||
setenv("TESSDATA_PREFIX", [[documentPath stringByAppendingString:@"/"] UTF8String], 1);
|
||||
|
||||
// init the tesseract engine.
|
||||
tesseract = new tesseract::TessBaseAPI();
|
||||
tesseract->Init([dataPath cStringUsingEncoding:NSUTF8StringEncoding], "eng");
|
||||
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
- (NSString *) ocrImage: (UIImage *) uiImage
|
||||
{
|
||||
|
||||
//code from http://robertcarlsen.net/2009/12/06/ocr-on-iphone-demo-1043
|
||||
|
||||
CGSize imageSize = [uiImage size];
|
||||
double bytes_per_line = CGImageGetBytesPerRow([uiImage CGImage]);
|
||||
double bytes_per_pixel = CGImageGetBitsPerPixel([uiImage CGImage]) / 8.0;
|
||||
|
||||
CFDataRef data = CGDataProviderCopyData(CGImageGetDataProvider([uiImage CGImage]));
|
||||
const UInt8 *imageData = CFDataGetBytePtr(data);
|
||||
|
||||
// this could take a while. maybe needs to happen asynchronously.
|
||||
char* text = tesseract->TesseractRect(imageData,(int)bytes_per_pixel,(int)bytes_per_line, 0, 0,(int) imageSize.height,(int) imageSize.width);
|
||||
|
||||
// Do something useful with the text!
|
||||
// NSLog(@"Converted text: %@",[NSString stringWithCString:text encoding:NSUTF8StringEncoding]);
|
||||
|
||||
return [NSString stringWithCString:text encoding:NSUTF8StringEncoding];
|
||||
}
|
||||
|
||||
|
||||
//http://www.iphonedevsdk.com/forum/iphone-sdk-development/7307-resizing-photo-new-uiimage.html#post33912
|
||||
-(UIImage *)resizeImage:(UIImage *)image {
|
||||
|
||||
CGImageRef imageRef = [image CGImage];
|
||||
CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo(imageRef);
|
||||
CGColorSpaceRef colorSpaceInfo = CGColorSpaceCreateDeviceRGB();
|
||||
|
||||
if (alphaInfo == kCGImageAlphaNone)
|
||||
alphaInfo = kCGImageAlphaNoneSkipLast;
|
||||
|
||||
int width, height;
|
||||
|
||||
width = 640;//[image size].width;
|
||||
height = 640;//[image size].height;
|
||||
|
||||
CGContextRef bitmap;
|
||||
|
||||
if (image.imageOrientation == UIImageOrientationUp | image.imageOrientation == UIImageOrientationDown) {
|
||||
bitmap = CGBitmapContextCreate(NULL, width, height, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, alphaInfo);
|
||||
|
||||
} else {
|
||||
bitmap = CGBitmapContextCreate(NULL, height, width, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, alphaInfo);
|
||||
|
||||
}
|
||||
|
||||
if (image.imageOrientation == UIImageOrientationLeft) {
|
||||
NSLog(@"image orientation left");
|
||||
CGContextRotateCTM (bitmap, radians(90));
|
||||
CGContextTranslateCTM (bitmap, 0, -height);
|
||||
|
||||
} else if (image.imageOrientation == UIImageOrientationRight) {
|
||||
NSLog(@"image orientation right");
|
||||
CGContextRotateCTM (bitmap, radians(-90));
|
||||
CGContextTranslateCTM (bitmap, -width, 0);
|
||||
|
||||
} else if (image.imageOrientation == UIImageOrientationUp) {
|
||||
NSLog(@"image orientation up");
|
||||
|
||||
} else if (image.imageOrientation == UIImageOrientationDown) {
|
||||
NSLog(@"image orientation down");
|
||||
CGContextTranslateCTM (bitmap, width,height);
|
||||
CGContextRotateCTM (bitmap, radians(-180.));
|
||||
|
||||
}
|
||||
|
||||
CGContextDrawImage(bitmap, CGRectMake(0, 0, width, height), imageRef);
|
||||
CGImageRef ref = CGBitmapContextCreateImage(bitmap);
|
||||
UIImage *result = [UIImage imageWithCGImage:ref];
|
||||
|
||||
CGContextRelease(bitmap);
|
||||
CGImageRelease(ref);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@end
|
||||
32
iOS/OCRPlugin/dependencies/include/leptonica/allheaders.h
Normal file
32
iOS/OCRPlugin/dependencies/include/leptonica/allheaders.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/*====================================================================*
|
||||
- Copyright (C) 2001 Leptonica. All rights reserved.
|
||||
- This software is distributed in the hope that it will be
|
||||
- useful, but with NO WARRANTY OF ANY KIND.
|
||||
- No author or distributor accepts responsibility to anyone for the
|
||||
- consequences of using this software, or for whether it serves any
|
||||
- particular purpose or works at all, unless he or she says so in
|
||||
- writing. Everyone is granted permission to copy, modify and
|
||||
- redistribute this source code, for commercial or non-commercial
|
||||
- purposes, with the following restrictions: (1) the origin of this
|
||||
- source code must not be misrepresented; (2) modified versions must
|
||||
- be plainly marked as such; and (3) this notice may not be removed
|
||||
- or altered from any source or modified source distribution.
|
||||
*====================================================================*/
|
||||
|
||||
#ifndef LEPTONICA_ALLHEADERS_H
|
||||
#define LEPTONICA_ALLHEADERS_H
|
||||
|
||||
|
||||
#define LIBLEPT_MAJOR_VERSION 1
|
||||
#define LIBLEPT_MINOR_VERSION 68
|
||||
|
||||
#include "alltypes.h"
|
||||
|
||||
#ifndef NO_PROTOS
|
||||
#include "leptprotos.h"
|
||||
#endif /* NO_PROTOS */
|
||||
|
||||
|
||||
#endif /* LEPTONICA_ALLHEADERS_H */
|
||||
|
||||
|
||||
49
iOS/OCRPlugin/dependencies/include/leptonica/alltypes.h
Normal file
49
iOS/OCRPlugin/dependencies/include/leptonica/alltypes.h
Normal file
@@ -0,0 +1,49 @@
|
||||
/*====================================================================*
|
||||
- Copyright (C) 2001 Leptonica. All rights reserved.
|
||||
- This software is distributed in the hope that it will be
|
||||
- useful, but with NO WARRANTY OF ANY KIND.
|
||||
- No author or distributor accepts responsibility to anyone for the
|
||||
- consequences of using this software, or for whether it serves any
|
||||
- particular purpose or works at all, unless he or she says so in
|
||||
- writing. Everyone is granted permission to copy, modify and
|
||||
- redistribute this source code, for commercial or non-commercial
|
||||
- purposes, with the following restrictions: (1) the origin of this
|
||||
- source code must not be misrepresented; (2) modified versions must
|
||||
- be plainly marked as such; and (3) this notice may not be removed
|
||||
- or altered from any source or modified source distribution.
|
||||
*====================================================================*/
|
||||
|
||||
#ifndef LEPTONICA_ALLTYPES_H
|
||||
#define LEPTONICA_ALLTYPES_H
|
||||
|
||||
/* Standard */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* General and configuration defs */
|
||||
#include "environ.h"
|
||||
|
||||
/* Imaging */
|
||||
#include "array.h"
|
||||
#include "arrayaccess.h"
|
||||
#include "bbuffer.h"
|
||||
#include "bmf.h"
|
||||
#include "ccbord.h"
|
||||
#include "dewarp.h"
|
||||
#include "gplot.h"
|
||||
#include "heap.h"
|
||||
#include "imageio.h"
|
||||
#include "jbclass.h"
|
||||
#include "list.h"
|
||||
#include "morph.h"
|
||||
#include "pix.h"
|
||||
#include "ptra.h"
|
||||
#include "queue.h"
|
||||
#include "regutils.h"
|
||||
#include "sudoku.h"
|
||||
#include "stack.h"
|
||||
#include "watershed.h"
|
||||
|
||||
|
||||
#endif /* LEPTONICA_ALLTYPES_H */
|
||||
|
||||
125
iOS/OCRPlugin/dependencies/include/leptonica/array.h
Normal file
125
iOS/OCRPlugin/dependencies/include/leptonica/array.h
Normal file
@@ -0,0 +1,125 @@
|
||||
/*====================================================================*
|
||||
- Copyright (C) 2001 Leptonica. All rights reserved.
|
||||
- This software is distributed in the hope that it will be
|
||||
- useful, but with NO WARRANTY OF ANY KIND.
|
||||
- No author or distributor accepts responsibility to anyone for the
|
||||
- consequences of using this software, or for whether it serves any
|
||||
- particular purpose or works at all, unless he or she says so in
|
||||
- writing. Everyone is granted permission to copy, modify and
|
||||
- redistribute this source code, for commercial or non-commercial
|
||||
- purposes, with the following restrictions: (1) the origin of this
|
||||
- source code must not be misrepresented; (2) modified versions must
|
||||
- be plainly marked as such; and (3) this notice may not be removed
|
||||
- or altered from any source or modified source distribution.
|
||||
*====================================================================*/
|
||||
|
||||
#ifndef LEPTONICA_ARRAY_H
|
||||
#define LEPTONICA_ARRAY_H
|
||||
|
||||
/*
|
||||
* Contains the following structs:
|
||||
* struct Numa
|
||||
* struct Numaa
|
||||
* struct Numa2d
|
||||
* struct NumaHash
|
||||
* struct Sarray
|
||||
* struct L_Bytea
|
||||
*
|
||||
* Contains definitions for:
|
||||
* Numa interpolation flags
|
||||
*/
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
* Array Structs *
|
||||
*------------------------------------------------------------------------*/
|
||||
|
||||
#define NUMA_VERSION_NUMBER 1
|
||||
|
||||
/* Number array: an array of floats */
|
||||
struct Numa
|
||||
{
|
||||
l_int32 nalloc; /* size of allocated number array */
|
||||
l_int32 n; /* number of numbers saved */
|
||||
l_int32 refcount; /* reference count (1 if no clones) */
|
||||
l_float32 startx; /* x value assigned to array[0] */
|
||||
l_float32 delx; /* change in x value as i --> i + 1 */
|
||||
l_float32 *array; /* number array */
|
||||
};
|
||||
typedef struct Numa NUMA;
|
||||
|
||||
|
||||
/* Array of number arrays */
|
||||
struct Numaa
|
||||
{
|
||||
l_int32 nalloc; /* size of allocated ptr array */
|
||||
l_int32 n; /* number of Numa saved */
|
||||
struct Numa **numa; /* array of Numa */
|
||||
};
|
||||
typedef struct Numaa NUMAA;
|
||||
|
||||
|
||||
|
||||
/* Sparse 2-dimensional array of number arrays */
|
||||
struct Numa2d
|
||||
{
|
||||
l_int32 nrows; /* number of rows allocated for ptr array */
|
||||
l_int32 ncols; /* number of cols allocated for ptr array */
|
||||
l_int32 initsize; /* initial size of each numa that is made */
|
||||
struct Numa ***numa; /* 2D array of Numa */
|
||||
};
|
||||
typedef struct Numa2d NUMA2D;
|
||||
|
||||
|
||||
/* A hash table of Numas */
|
||||
struct NumaHash
|
||||
{
|
||||
l_int32 nbuckets;
|
||||
l_int32 initsize; /* initial size of each numa that is made */
|
||||
struct Numa **numa;
|
||||
};
|
||||
typedef struct NumaHash NUMAHASH;
|
||||
|
||||
|
||||
#define SARRAY_VERSION_NUMBER 1
|
||||
|
||||
/* String array: an array of C strings */
|
||||
struct Sarray
|
||||
{
|
||||
l_int32 nalloc; /* size of allocated ptr array */
|
||||
l_int32 n; /* number of strings allocated */
|
||||
l_int32 refcount; /* reference count (1 if no clones) */
|
||||
char **array; /* string array */
|
||||
};
|
||||
typedef struct Sarray SARRAY;
|
||||
|
||||
|
||||
/* Byte array (analogous to C++ "string") */
|
||||
struct L_Bytea
|
||||
{
|
||||
size_t nalloc; /* number of bytes allocated in data array */
|
||||
size_t size; /* number of bytes presently used */
|
||||
l_int32 refcount; /* reference count (1 if no clones) */
|
||||
l_uint8 *data; /* data array */
|
||||
};
|
||||
typedef struct L_Bytea L_BYTEA;
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
* Array flags *
|
||||
*------------------------------------------------------------------------*/
|
||||
|
||||
/* Flags for interpolation in Numa */
|
||||
enum {
|
||||
L_LINEAR_INTERP = 1, /* linear */
|
||||
L_QUADRATIC_INTERP = 2 /* quadratic */
|
||||
};
|
||||
|
||||
/* Flags for added borders in Numa */
|
||||
enum {
|
||||
L_EXTENDED_BORDER = 1, /* extended with same value */
|
||||
L_MIRRORED_BORDER = 2 /* mirrored */
|
||||
};
|
||||
|
||||
|
||||
#endif /* LEPTONICA_ARRAY_H */
|
||||
194
iOS/OCRPlugin/dependencies/include/leptonica/arrayaccess.h
Normal file
194
iOS/OCRPlugin/dependencies/include/leptonica/arrayaccess.h
Normal file
@@ -0,0 +1,194 @@
|
||||
/*====================================================================*
|
||||
- Copyright (C) 2001 Leptonica. All rights reserved.
|
||||
- This software is distributed in the hope that it will be
|
||||
- useful, but with NO WARRANTY OF ANY KIND.
|
||||
- No author or distributor accepts responsibility to anyone for the
|
||||
- consequences of using this software, or for whether it serves any
|
||||
- particular purpose or works at all, unless he or she says so in
|
||||
- writing. Everyone is granted permission to copy, modify and
|
||||
- redistribute this source code, for commercial or non-commercial
|
||||
- purposes, with the following restrictions: (1) the origin of this
|
||||
- source code must not be misrepresented; (2) modified versions must
|
||||
- be plainly marked as such; and (3) this notice may not be removed
|
||||
- or altered from any source or modified source distribution.
|
||||
*====================================================================*/
|
||||
|
||||
#ifndef LEPTONICA_ARRAY_ACCESS_H
|
||||
#define LEPTONICA_ARRAY_ACCESS_H
|
||||
|
||||
/*
|
||||
* arrayaccess.h
|
||||
*
|
||||
* 1, 2, 4, 8, 16 and 32 bit data access within an array of 32-bit words
|
||||
*
|
||||
* This is used primarily to access 1, 2, 4, 8, 16 and 32 bit pixels
|
||||
* in a line of image data, represented as an array of 32-bit words.
|
||||
*
|
||||
* pdata: pointer to first 32-bit word in the array
|
||||
* n: index of the pixel in the array
|
||||
*
|
||||
* Function calls for these accessors are defined in arrayaccess.c.
|
||||
*
|
||||
* However, for efficiency we use the inline macros for all accesses.
|
||||
* Even though the 2 and 4 bit set* accessors are more complicated,
|
||||
* they are about 10% faster than the function calls.
|
||||
*
|
||||
* The 32 bit access is just a cast and ptr arithmetic. We include
|
||||
* it so that the input ptr can be void*.
|
||||
*
|
||||
* At the end of this file is code for invoking the function calls
|
||||
* instead of inlining.
|
||||
*
|
||||
* The macro SET_DATA_BIT_VAL(pdata, n, val) is a bit slower than
|
||||
* if (val == 0)
|
||||
* CLEAR_DATA_BIT(pdata, n);
|
||||
* else
|
||||
* SET_DATA_BIT(pdata, n);
|
||||
*/
|
||||
|
||||
|
||||
/* Use the inline accessors (except with _MSC_VER), because they
|
||||
* are faster. */
|
||||
#define USE_INLINE_ACCESSORS 1
|
||||
|
||||
#if USE_INLINE_ACCESSORS
|
||||
#ifndef _MSC_VER
|
||||
|
||||
/*--------------------------------------------------*
|
||||
* 1 bit access *
|
||||
*--------------------------------------------------*/
|
||||
#define GET_DATA_BIT(pdata, n) \
|
||||
((*((l_uint32 *)(pdata) + ((n) >> 5)) >> (31 - ((n) & 31))) & 1)
|
||||
|
||||
#define SET_DATA_BIT(pdata, n) \
|
||||
(*((l_uint32 *)(pdata) + ((n) >> 5)) |= (0x80000000 >> ((n) & 31)))
|
||||
|
||||
#define CLEAR_DATA_BIT(pdata, n) \
|
||||
(*((l_uint32 *)(pdata) + ((n) >> 5)) &= ~(0x80000000 >> ((n) & 31)))
|
||||
|
||||
#define SET_DATA_BIT_VAL(pdata, n, val) \
|
||||
({l_uint32 *_TEMP_WORD_PTR_; \
|
||||
_TEMP_WORD_PTR_ = (l_uint32 *)(pdata) + ((n) >> 5); \
|
||||
*_TEMP_WORD_PTR_ &= ~(0x80000000 >> ((n) & 31)); \
|
||||
*_TEMP_WORD_PTR_ |= ((val) << (31 - ((n) & 31))); \
|
||||
})
|
||||
|
||||
|
||||
/*--------------------------------------------------*
|
||||
* 2 bit access *
|
||||
*--------------------------------------------------*/
|
||||
#define GET_DATA_DIBIT(pdata, n) \
|
||||
((*((l_uint32 *)(pdata) + ((n) >> 4)) >> (2 * (15 - ((n) & 15)))) & 3)
|
||||
|
||||
#define SET_DATA_DIBIT(pdata, n, val) \
|
||||
({l_uint32 *_TEMP_WORD_PTR_; \
|
||||
_TEMP_WORD_PTR_ = (l_uint32 *)(pdata) + ((n) >> 4); \
|
||||
*_TEMP_WORD_PTR_ &= ~(0xc0000000 >> (2 * ((n) & 15))); \
|
||||
*_TEMP_WORD_PTR_ |= (((val) & 3) << (30 - 2 * ((n) & 15))); \
|
||||
})
|
||||
|
||||
#define CLEAR_DATA_DIBIT(pdata, n) \
|
||||
(*((l_uint32 *)(pdata) + ((n) >> 4)) &= ~(0xc0000000 >> (2 * ((n) & 15))))
|
||||
|
||||
|
||||
/*--------------------------------------------------*
|
||||
* 4 bit access *
|
||||
*--------------------------------------------------*/
|
||||
#define GET_DATA_QBIT(pdata, n) \
|
||||
((*((l_uint32 *)(pdata) + ((n) >> 3)) >> (4 * (7 - ((n) & 7)))) & 0xf)
|
||||
|
||||
#define SET_DATA_QBIT(pdata, n, val) \
|
||||
({l_uint32 *_TEMP_WORD_PTR_; \
|
||||
_TEMP_WORD_PTR_ = (l_uint32 *)(pdata) + ((n) >> 3); \
|
||||
*_TEMP_WORD_PTR_ &= ~(0xf0000000 >> (4 * ((n) & 7))); \
|
||||
*_TEMP_WORD_PTR_ |= (((val) & 15) << (28 - 4 * ((n) & 7))); \
|
||||
})
|
||||
|
||||
#define CLEAR_DATA_QBIT(pdata, n) \
|
||||
(*((l_uint32 *)(pdata) + ((n) >> 3)) &= ~(0xf0000000 >> (4 * ((n) & 7))))
|
||||
|
||||
|
||||
/*--------------------------------------------------*
|
||||
* 8 bit access *
|
||||
*--------------------------------------------------*/
|
||||
#ifdef L_BIG_ENDIAN
|
||||
#define GET_DATA_BYTE(pdata, n) \
|
||||
(*((l_uint8 *)(pdata) + (n)))
|
||||
#else /* L_LITTLE_ENDIAN */
|
||||
#define GET_DATA_BYTE(pdata, n) \
|
||||
(*(l_uint8 *)((l_uintptr_t)((l_uint8 *)(pdata) + (n)) ^ 3))
|
||||
#endif /* L_BIG_ENDIAN */
|
||||
|
||||
#ifdef L_BIG_ENDIAN
|
||||
#define SET_DATA_BYTE(pdata, n, val) \
|
||||
(*((l_uint8 *)(pdata) + (n)) = (val))
|
||||
#else /* L_LITTLE_ENDIAN */
|
||||
#define SET_DATA_BYTE(pdata, n, val) \
|
||||
(*(l_uint8 *)((l_uintptr_t)((l_uint8 *)(pdata) + (n)) ^ 3) = (val))
|
||||
#endif /* L_BIG_ENDIAN */
|
||||
|
||||
|
||||
/*--------------------------------------------------*
|
||||
* 16 bit access *
|
||||
*--------------------------------------------------*/
|
||||
#ifdef L_BIG_ENDIAN
|
||||
#define GET_DATA_TWO_BYTES(pdata, n) \
|
||||
(*((l_uint16 *)(pdata) + (n)))
|
||||
#else /* L_LITTLE_ENDIAN */
|
||||
#define GET_DATA_TWO_BYTES(pdata, n) \
|
||||
(*(l_uint16 *)((l_uintptr_t)((l_uint16 *)(pdata) + (n)) ^ 2))
|
||||
#endif /* L_BIG_ENDIAN */
|
||||
|
||||
#ifdef L_BIG_ENDIAN
|
||||
#define SET_DATA_TWO_BYTES(pdata, n, val) \
|
||||
(*((l_uint16 *)(pdata) + (n)) = (val))
|
||||
#else /* L_LITTLE_ENDIAN */
|
||||
#define SET_DATA_TWO_BYTES(pdata, n, val) \
|
||||
(*(l_uint16 *)((l_uintptr_t)((l_uint16 *)(pdata) + (n)) ^ 2) = (val))
|
||||
#endif /* L_BIG_ENDIAN */
|
||||
|
||||
|
||||
/*--------------------------------------------------*
|
||||
* 32 bit access *
|
||||
*--------------------------------------------------*/
|
||||
#define GET_DATA_FOUR_BYTES(pdata, n) \
|
||||
(*((l_uint32 *)(pdata) + (n)))
|
||||
|
||||
#define SET_DATA_FOUR_BYTES(pdata, n, val) \
|
||||
(*((l_uint32 *)(pdata) + (n)) = (val))
|
||||
|
||||
|
||||
#endif /* ! _MSC_VER */
|
||||
#endif /* USE_INLINE_ACCESSORS */
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------*
|
||||
* Slower, using function calls for all accessors *
|
||||
*--------------------------------------------------*/
|
||||
#if !USE_INLINE_ACCESSORS || defined(_MSC_VER)
|
||||
#define GET_DATA_BIT(pdata, n) l_getDataBit(pdata, n)
|
||||
#define SET_DATA_BIT(pdata, n) l_setDataBit(pdata, n)
|
||||
#define CLEAR_DATA_BIT(pdata, n) l_clearDataBit(pdata, n)
|
||||
#define SET_DATA_BIT_VAL(pdata, n, val) l_setDataBitVal(pdata, n, val)
|
||||
|
||||
#define GET_DATA_DIBIT(pdata, n) l_getDataDibit(pdata, n)
|
||||
#define SET_DATA_DIBIT(pdata, n, val) l_setDataDibit(pdata, n, val)
|
||||
#define CLEAR_DATA_DIBIT(pdata, n) l_clearDataDibit(pdata, n)
|
||||
|
||||
#define GET_DATA_QBIT(pdata, n) l_getDataQbit(pdata, n)
|
||||
#define SET_DATA_QBIT(pdata, n, val) l_setDataQbit(pdata, n, val)
|
||||
#define CLEAR_DATA_QBIT(pdata, n) l_clearDataQbit(pdata, n)
|
||||
|
||||
#define GET_DATA_BYTE(pdata, n) l_getDataByte(pdata, n)
|
||||
#define SET_DATA_BYTE(pdata, n, val) l_setDataByte(pdata, n, val)
|
||||
|
||||
#define GET_DATA_TWO_BYTES(pdata, n) l_getDataTwoBytes(pdata, n)
|
||||
#define SET_DATA_TWO_BYTES(pdata, n, val) l_setDataTwoBytes(pdata, n, val)
|
||||
|
||||
#define GET_DATA_FOUR_BYTES(pdata, n) l_getDataFourBytes(pdata, n)
|
||||
#define SET_DATA_FOUR_BYTES(pdata, n, val) l_setDataFourBytes(pdata, n, val)
|
||||
#endif /* !USE_INLINE_ACCESSORS || _MSC_VER */
|
||||
|
||||
|
||||
#endif /* LEPTONICA_ARRAY_ACCESS_H */
|
||||
46
iOS/OCRPlugin/dependencies/include/leptonica/bbuffer.h
Normal file
46
iOS/OCRPlugin/dependencies/include/leptonica/bbuffer.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/*====================================================================*
|
||||
- Copyright (C) 2001 Leptonica. All rights reserved.
|
||||
- This software is distributed in the hope that it will be
|
||||
- useful, but with NO WARRANTY OF ANY KIND.
|
||||
- No author or distributor accepts responsibility to anyone for the
|
||||
- consequences of using this software, or for whether it serves any
|
||||
- particular purpose or works at all, unless he or she says so in
|
||||
- writing. Everyone is granted permission to copy, modify and
|
||||
- redistribute this source code, for commercial or non-commercial
|
||||
- purposes, with the following restrictions: (1) the origin of this
|
||||
- source code must not be misrepresented; (2) modified versions must
|
||||
- be plainly marked as such; and (3) this notice may not be removed
|
||||
- or altered from any source or modified source distribution.
|
||||
*====================================================================*/
|
||||
|
||||
#ifndef LEPTONICA_BBUFFER_H
|
||||
#define LEPTONICA_BBUFFER_H
|
||||
|
||||
/*
|
||||
* bbuffer.h
|
||||
*
|
||||
* Expandable byte buffer for reading data in from memory and
|
||||
* writing data out to other memory.
|
||||
*
|
||||
* This implements a queue of bytes, so data read in is put
|
||||
* on the "back" of the queue (i.e., the end of the byte array)
|
||||
* and data written out is taken from the "front" of the queue
|
||||
* (i.e., from an index marker "nwritten" that is initially set at
|
||||
* the beginning of the array.) As usual with expandable
|
||||
* arrays, we keep the size of the allocated array and the
|
||||
* number of bytes that have been read into the array.
|
||||
*
|
||||
* For implementation details, see bbuffer.c.
|
||||
*/
|
||||
|
||||
struct ByteBuffer
|
||||
{
|
||||
l_int32 nalloc; /* size of allocated byte array */
|
||||
l_int32 n; /* number of bytes read into to the array */
|
||||
l_int32 nwritten; /* number of bytes written from the array */
|
||||
l_uint8 *array; /* byte array */
|
||||
};
|
||||
typedef struct ByteBuffer BBUFFER;
|
||||
|
||||
|
||||
#endif /* LEPTONICA_BBUFFER_H */
|
||||
51
iOS/OCRPlugin/dependencies/include/leptonica/bmf.h
Normal file
51
iOS/OCRPlugin/dependencies/include/leptonica/bmf.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/*====================================================================*
|
||||
- Copyright (C) 2001 Leptonica. All rights reserved.
|
||||
- This software is distributed in the hope that it will be
|
||||
- useful, but with NO WARRANTY OF ANY KIND.
|
||||
- No author or distributor accepts responsibility to anyone for the
|
||||
- consequences of using this software, or for whether it serves any
|
||||
- particular purpose or works at all, unless he or she says so in
|
||||
- writing. Everyone is granted permission to copy, modify and
|
||||
- redistribute this source code, for commercial or non-commercial
|
||||
- purposes, with the following restrictions: (1) the origin of this
|
||||
- source code must not be misrepresented; (2) modified versions must
|
||||
- be plainly marked as such; and (3) this notice may not be removed
|
||||
- or altered from any source or modified source distribution.
|
||||
*====================================================================*/
|
||||
|
||||
#ifndef LEPTONICA_BMF_H
|
||||
#define LEPTONICA_BMF_H
|
||||
|
||||
/*
|
||||
* bmf.h
|
||||
*
|
||||
* Simple data structure to hold bitmap fonts and related data
|
||||
*/
|
||||
|
||||
/* Constants for deciding when text block is divided into paragraphs */
|
||||
enum {
|
||||
SPLIT_ON_LEADING_WHITE = 1, /* tab or space at beginning of line */
|
||||
SPLIT_ON_BLANK_LINE = 2, /* newline with optional white space */
|
||||
SPLIT_ON_BOTH = 3 /* leading white space or newline */
|
||||
};
|
||||
|
||||
|
||||
struct L_Bmf
|
||||
{
|
||||
struct Pixa *pixa; /* pixa of bitmaps for 93 characters */
|
||||
l_int32 size; /* font size (in points at 300 ppi) */
|
||||
char *directory; /* directory containing font bitmaps */
|
||||
l_int32 baseline1; /* baseline offset for ascii 33 - 57 */
|
||||
l_int32 baseline2; /* baseline offset for ascii 58 - 91 */
|
||||
l_int32 baseline3; /* baseline offset for ascii 93 - 126 */
|
||||
l_int32 lineheight; /* max height of line of chars */
|
||||
l_int32 kernwidth; /* pixel dist between char bitmaps */
|
||||
l_int32 spacewidth; /* pixel dist between word bitmaps */
|
||||
l_int32 vertlinesep; /* extra vertical space between text lines */
|
||||
l_int32 *fonttab; /* table mapping ascii --> font index */
|
||||
l_int32 *baselinetab; /* table mapping ascii --> baseline offset */
|
||||
l_int32 *widthtab; /* table mapping ascii --> char width */
|
||||
};
|
||||
typedef struct L_Bmf L_BMF;
|
||||
|
||||
#endif /* LEPTONICA_BMF_H */
|
||||
74
iOS/OCRPlugin/dependencies/include/leptonica/bmp.h
Normal file
74
iOS/OCRPlugin/dependencies/include/leptonica/bmp.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/*====================================================================*
|
||||
- Copyright (C) 2001 Leptonica. All rights reserved.
|
||||
- This software is distributed in the hope that it will be
|
||||
- useful, but with NO WARRANTY OF ANY KIND.
|
||||
- No author or distributor accepts responsibility to anyone for the
|
||||
- consequences of using this software, or for whether it serves any
|
||||
- particular purpose or works at all, unless he or she says so in
|
||||
- writing. Everyone is granted permission to copy, modify and
|
||||
- redistribute this source code, for commercial or non-commercial
|
||||
- purposes, with the following restrictions: (1) the origin of this
|
||||
- source code must not be misrepresented; (2) modified versions must
|
||||
- be plainly marked as such; and (3) this notice may not be removed
|
||||
- or altered from any source or modified source distribution.
|
||||
*====================================================================*/
|
||||
|
||||
#ifndef LEPTONICA_BMP_H
|
||||
#define LEPTONICA_BMP_H
|
||||
|
||||
/*
|
||||
* This file is here to describe the fields in the header of
|
||||
* the BMP file. These fields are not used directly in Leptonica.
|
||||
* The only thing we use are the sizes of these two headers.
|
||||
* Furthermore, because of potential namespace conflicts with
|
||||
* the typedefs and defined sizes, we have changed the names
|
||||
* to protect anyone who may also need to use the original definitions.
|
||||
* Thanks to J. D. Bryan for pointing out the potential problems when
|
||||
* developing on Win32 compatible systems.
|
||||
*/
|
||||
|
||||
/*-------------------------------------------------------------*
|
||||
* BMP file header *
|
||||
*-------------------------------------------------------------*/
|
||||
struct BMP_FileHeader
|
||||
{
|
||||
l_int16 bfType; /* file type; must be "BM" */
|
||||
l_int16 bfSize; /* length of the file;
|
||||
sizeof(BMP_FileHeader) +
|
||||
sizeof(BMP_InfoHeader) +
|
||||
size of color table +
|
||||
size of DIB bits */
|
||||
l_int16 bfFill1; /* remainder of the bfSize field */
|
||||
l_int16 bfReserved1; /* don't care (set to 0)*/
|
||||
l_int16 bfReserved2; /* don't care (set to 0)*/
|
||||
l_int16 bfOffBits; /* offset from beginning of file */
|
||||
l_int16 bfFill2; /* remainder of the bfOffBits field */
|
||||
};
|
||||
typedef struct BMP_FileHeader BMP_FH;
|
||||
|
||||
#define BMP_FHBYTES sizeof(BMP_FH)
|
||||
|
||||
|
||||
/*-------------------------------------------------------------*
|
||||
* BMP info header *
|
||||
*-------------------------------------------------------------*/
|
||||
struct BMP_InfoHeader
|
||||
{
|
||||
l_int32 biSize; /* size of the BMP_InfoHeader struct */
|
||||
l_int32 biWidth; /* bitmap width in pixels */
|
||||
l_int32 biHeight; /* bitmap height in pixels */
|
||||
l_int16 biPlanes; /* number of bitmap planes */
|
||||
l_int16 biBitCount; /* number of bits per pixel */
|
||||
l_int32 biCompression; /* compression format (0 == uncompressed) */
|
||||
l_int32 biSizeImage; /* size of image in bytes */
|
||||
l_int32 biXPelsPerMeter; /* pixels per meter in x direction */
|
||||
l_int32 biYPelsPerMeter; /* pixels per meter in y direction */
|
||||
l_int32 biClrUsed; /* number of colors used */
|
||||
l_int32 biClrImportant; /* number of important colors used */
|
||||
};
|
||||
typedef struct BMP_InfoHeader BMP_IH;
|
||||
|
||||
#define BMP_IHBYTES sizeof(BMP_IH)
|
||||
|
||||
|
||||
#endif /* LEPTONICA_BMP_H */
|
||||
103
iOS/OCRPlugin/dependencies/include/leptonica/ccbord.h
Normal file
103
iOS/OCRPlugin/dependencies/include/leptonica/ccbord.h
Normal file
@@ -0,0 +1,103 @@
|
||||
/*====================================================================*
|
||||
- Copyright (C) 2001 Leptonica. All rights reserved.
|
||||
- This software is distributed in the hope that it will be
|
||||
- useful, but with NO WARRANTY OF ANY KIND.
|
||||
- No author or distributor accepts responsibility to anyone for the
|
||||
- consequences of using this software, or for whether it serves any
|
||||
- particular purpose or works at all, unless he or she says so in
|
||||
- writing. Everyone is granted permission to copy, modify and
|
||||
- redistribute this source code, for commercial or non-commercial
|
||||
- purposes, with the following restrictions: (1) the origin of this
|
||||
- source code must not be misrepresented; (2) modified versions must
|
||||
- be plainly marked as such; and (3) this notice may not be removed
|
||||
- or altered from any source or modified source distribution.
|
||||
*====================================================================*/
|
||||
|
||||
#ifndef LEPTONICA_CCBORD_H
|
||||
#define LEPTONICA_CCBORD_H
|
||||
|
||||
/*
|
||||
* ccbord.h
|
||||
*
|
||||
* CCBord: represents a single connected component
|
||||
* CCBorda: an array of CCBord
|
||||
*/
|
||||
|
||||
/* Use in ccbaStepChainsToPixCoords() */
|
||||
enum {
|
||||
CCB_LOCAL_COORDS = 1,
|
||||
CCB_GLOBAL_COORDS = 2
|
||||
};
|
||||
|
||||
/* Use in ccbaGenerateSPGlobalLocs() */
|
||||
enum {
|
||||
CCB_SAVE_ALL_PTS = 1,
|
||||
CCB_SAVE_TURNING_PTS = 2
|
||||
};
|
||||
|
||||
|
||||
/* CCBord contains:
|
||||
*
|
||||
* (1) a minimally-clipped bitmap of the component (pix),
|
||||
* (2) a boxa consisting of:
|
||||
* for the primary component:
|
||||
* (xul, yul) pixel location in global coords
|
||||
* (w, h) of the bitmap
|
||||
* for the hole components:
|
||||
* (x, y) in relative coordinates in primary component
|
||||
* (w, h) of the hole border (which is 2 pixels
|
||||
* larger in each direction than the hole itself)
|
||||
* (3) a pta ('start') of the initial border pixel location for each
|
||||
* closed curve, all in relative coordinates of the primary
|
||||
* component. This is given for the primary component,
|
||||
* followed by the hole components, if any.
|
||||
* (4) a refcount of the ccbord; used internally when a ccbord
|
||||
* is accessed from a ccborda (array of ccbord)
|
||||
* (5) a ptaa for the chain code for the border in relative
|
||||
* coordinates, where the first pta is the exterior border
|
||||
* and all other pta are for interior borders (holes)
|
||||
* (6) a ptaa for the global pixel loc rendition of the border,
|
||||
* where the first pta is the exterior border and all other
|
||||
* pta are for interior borders (holes).
|
||||
* This is derived from the local or step chain code.
|
||||
* (7) a numaa for the chain code for the border as orientation
|
||||
* directions between successive border pixels, where
|
||||
* the first numa is the exterior border and all other
|
||||
* numa are for interior borders (holes). This is derived
|
||||
* from the local chain code. The 8 directions are 0 - 7.
|
||||
* (8) a pta for a single chain for each c.c., comprised of outer
|
||||
* and hole borders, plus cut paths between them, all in
|
||||
* local coords.
|
||||
* (9) a pta for a single chain for each c.c., comprised of outer
|
||||
* and hole borders, plus cut paths between them, all in
|
||||
* global coords.
|
||||
*/
|
||||
struct CCBord
|
||||
{
|
||||
struct Pix *pix; /* component bitmap (min size) */
|
||||
struct Boxa *boxa; /* regions of each closed curve */
|
||||
struct Pta *start; /* initial border pixel locations */
|
||||
l_int32 refcount; /* number of handles; start at 1 */
|
||||
struct Ptaa *local; /* ptaa of chain pixels (local) */
|
||||
struct Ptaa *global; /* ptaa of chain pixels (global) */
|
||||
struct Numaa *step; /* numaa of chain code (step dir) */
|
||||
struct Pta *splocal; /* pta of single chain (local) */
|
||||
struct Pta *spglobal; /* pta of single chain (global) */
|
||||
};
|
||||
typedef struct CCBord CCBORD;
|
||||
|
||||
|
||||
struct CCBorda
|
||||
{
|
||||
struct Pix *pix; /* input pix (may be null) */
|
||||
l_int32 w; /* width of pix */
|
||||
l_int32 h; /* height of pix */
|
||||
l_int32 n; /* number of ccbord in ptr array */
|
||||
l_int32 nalloc; /* number of ccbord ptrs allocated */
|
||||
struct CCBord **ccb; /* ccb ptr array */
|
||||
};
|
||||
typedef struct CCBorda CCBORDA;
|
||||
|
||||
|
||||
#endif /* LEPTONICA_CCBORD_H */
|
||||
|
||||
57
iOS/OCRPlugin/dependencies/include/leptonica/dewarp.h
Normal file
57
iOS/OCRPlugin/dependencies/include/leptonica/dewarp.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/*====================================================================*
|
||||
- Copyright (C) 2001 Leptonica. All rights reserved.
|
||||
- This software is distributed in the hope that it will be
|
||||
- useful, but with NO WARRANTY OF ANY KIND.
|
||||
- No author or distributor accepts responsibility to anyone for the
|
||||
- consequences of using this software, or for whether it serves any
|
||||
- particular purpose or works at all, unless he or she says so in
|
||||
- writing. Everyone is granted permission to copy, modify and
|
||||
- redistribute this source code, for commercial or non-commercial
|
||||
- purposes, with the following restrictions: (1) the origin of this
|
||||
- source code must not be misrepresented; (2) modified versions must
|
||||
- be plainly marked as such; and (3) this notice may not be removed
|
||||
- or altered from any source or modified source distribution.
|
||||
*====================================================================*/
|
||||
|
||||
#ifndef LEPTONICA_DEWARP_H
|
||||
#define LEPTONICA_DEWARP_H
|
||||
|
||||
/*
|
||||
* dewarp.h
|
||||
*
|
||||
* Data structure to hold arrays and results for generating
|
||||
* a vertical disparity array based on textlines. The disparity
|
||||
* array is two-dimensional, and it represents a vertical
|
||||
* displacement, relative to the flat point in the textlines.
|
||||
* After dewarping, all points on the altered curve will have
|
||||
* a y-value equal to the flat point.
|
||||
*
|
||||
* The sampled vertical disparity array is expanded to full resolution,
|
||||
* using linear interpolation, from which it is trivially applied
|
||||
* to the input image.
|
||||
*/
|
||||
|
||||
#define DEWARP_VERSION_NUMBER 1
|
||||
|
||||
struct L_Dewarp
|
||||
{
|
||||
struct Pix *pixs; /* source pix, 1 bpp */
|
||||
struct Pix *pixd; /* dewarped pix; 1, 8 or 32 bpp */
|
||||
struct FPix *sampvdispar; /* sampled vertical disparity array */
|
||||
struct FPix *samphdispar; /* sampled horizontal disparity array */
|
||||
struct FPix *fullvdispar; /* full vertical disparity array */
|
||||
struct FPix *fullhdispar; /* full horiztontal disparity array */
|
||||
struct Numa *naflats; /* sorted flat location of each line */
|
||||
struct Numa *nacurves; /* sorted curvature of each line */
|
||||
l_int32 pageno; /* page number; important for reuse */
|
||||
l_int32 sampling; /* sampling factor of disparity array */
|
||||
l_int32 minlines; /* min number of long lines required */
|
||||
l_int32 applyhoriz; /* flag for estimating horiz. disparity */
|
||||
l_int32 nx; /* number of sampling pts in x direction */
|
||||
l_int32 ny; /* number of sampling pts in y direction */
|
||||
l_int32 extraw; /* extra width required for hor. disparity */
|
||||
l_int32 success; /* sets to 1 if model build succeeds */
|
||||
};
|
||||
typedef struct L_Dewarp L_DEWARP;
|
||||
|
||||
#endif /* LEPTONICA_DEWARP_H */
|
||||
11
iOS/OCRPlugin/dependencies/include/leptonica/endianness.h
Normal file
11
iOS/OCRPlugin/dependencies/include/leptonica/endianness.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#if !defined (L_BIG_ENDIAN) && !defined (L_LITTLE_ENDIAN)
|
||||
# if 0
|
||||
# ifdef __BIG_ENDIAN__
|
||||
# define L_BIG_ENDIAN
|
||||
# else
|
||||
# define L_LITTLE_ENDIAN
|
||||
# endif
|
||||
# else
|
||||
# define L_LITTLE_ENDIAN
|
||||
# endif
|
||||
#endif
|
||||
281
iOS/OCRPlugin/dependencies/include/leptonica/environ.h
Normal file
281
iOS/OCRPlugin/dependencies/include/leptonica/environ.h
Normal file
@@ -0,0 +1,281 @@
|
||||
/*====================================================================*
|
||||
- Copyright (C) 2001 Leptonica. All rights reserved.
|
||||
- This software is distributed in the hope that it will be
|
||||
- useful, but with NO WARRANTY OF ANY KIND.
|
||||
- No author or distributor accepts responsibility to anyone for the
|
||||
- consequences of using this software, or for whether it serves any
|
||||
- particular purpose or works at all, unless he or she says so in
|
||||
- writing. Everyone is granted permission to copy, modify and
|
||||
- redistribute this source code, for commercial or non-commercial
|
||||
- purposes, with the following restrictions: (1) the origin of this
|
||||
- source code must not be misrepresented; (2) modified versions must
|
||||
- be plainly marked as such; and (3) this notice may not be removed
|
||||
- or altered from any source or modified source distribution.
|
||||
*====================================================================*/
|
||||
|
||||
#ifndef LEPTONICA_ENVIRON_H
|
||||
#define LEPTONICA_ENVIRON_H
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
* Defines and includes differ for Unix and Windows. Also for Windows, *
|
||||
* differentiate between conditionals based on platform and compiler. *
|
||||
* For platforms: *
|
||||
* _WIN32 => Windows, 32- or 64-bit *
|
||||
* _WIN64 => Windows, 64-bit only *
|
||||
* __CYGWIN__ => Cygwin *
|
||||
* For compilers: *
|
||||
* __GNUC__ => gcc *
|
||||
* _MSC_VER => msvc *
|
||||
*------------------------------------------------------------------------*/
|
||||
|
||||
/* MS VC++ does not provide stdint.h, so define the missing types here */
|
||||
|
||||
#ifndef _MSC_VER
|
||||
#include <stdint.h>
|
||||
|
||||
#else
|
||||
/* Note that _WIN32 is defined for both 32 and 64 bit applications,
|
||||
whereas _WIN64 is defined only for the latter */
|
||||
|
||||
#ifdef _WIN64
|
||||
typedef __int64 intptr_t;
|
||||
typedef unsigned __int64 uintptr_t;
|
||||
#else
|
||||
typedef int intptr_t;
|
||||
typedef unsigned int uintptr_t;
|
||||
#endif
|
||||
|
||||
/* VC++6 doesn't seem to have powf, expf. */
|
||||
#if (_MSC_VER < 1400)
|
||||
#define powf(x, y) (float)pow((double)(x), (double)(y))
|
||||
#define expf(x) (float)exp((double)(x))
|
||||
#endif
|
||||
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
/* Windows specifics */
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
/* DLL EXPORTS and IMPORTS:
|
||||
* Important: LEPTONLIB_* is deprected. It is retained here only for
|
||||
* compatibility with tesseract 3.00. In your project files, use
|
||||
* LIBLEPT_EXPORTS and LIBLEPT_IMPORTS */
|
||||
#if defined(LIBLEPT_EXPORTS) || defined(LEPTONLIB_EXPORTS)
|
||||
#define LEPT_DLL __declspec(dllexport)
|
||||
#elif defined(LIBLEPT_IMPORTS) || defined(LEPTONLIB_IMPORTS)
|
||||
#define LEPT_DLL __declspec(dllimport)
|
||||
#else
|
||||
#define LEPT_DLL
|
||||
#endif
|
||||
|
||||
#else /* non-WINDOWS-SPECIFICS */
|
||||
#include <stdint.h>
|
||||
#define LEPT_DLL
|
||||
#endif /* _WIN32 */
|
||||
|
||||
typedef intptr_t l_intptr_t;
|
||||
typedef uintptr_t l_uintptr_t;
|
||||
typedef void *L_TIMER;
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------*
|
||||
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*
|
||||
* USER CONFIGURABLE *
|
||||
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*
|
||||
* Environ variables with I/O libraries *
|
||||
* Manual Configuration Only: NOT AUTO_CONF *
|
||||
*--------------------------------------------------------------------*/
|
||||
/*
|
||||
* Leptonica provides interfaces to link to five external image I/O
|
||||
* libraries, plus zlib. Setting any of these to 0 here causes
|
||||
* non-functioning stubs to be linked.
|
||||
*/
|
||||
#ifndef HAVE_CONFIG_H
|
||||
#define HAVE_LIBJPEG 1
|
||||
#define HAVE_LIBTIFF 1
|
||||
#define HAVE_LIBPNG 1
|
||||
#define HAVE_LIBZ 1
|
||||
#define HAVE_LIBGIF 0
|
||||
#define HAVE_LIBUNGIF 0
|
||||
#define HAVE_LIBWEBP 0
|
||||
#endif /* ~HAVE_CONFIG_H */
|
||||
|
||||
/*
|
||||
* On linux systems, you can do I/O between Pix and memory. Specifically,
|
||||
* you can compress (write compressed data to memory from a Pix) and
|
||||
* uncompress (read from compressed data in memory to a Pix).
|
||||
* For jpeg, png, pnm and bmp, these use the non-posix GNU functions
|
||||
* fmemopen() and open_memstream(). These functions are not
|
||||
* available on other systems. To use these functions in linux,
|
||||
* you must define HAVE_FMEMOPEN to be 1 here.
|
||||
*/
|
||||
#ifndef HAVE_CONFIG_H
|
||||
#define HAVE_FMEMOPEN 0
|
||||
#endif /* ~HAVE_CONFIG_H */
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------*
|
||||
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*
|
||||
* USER CONFIGURABLE *
|
||||
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*
|
||||
* Environ variables for uncompressed formatted image I/O *
|
||||
*--------------------------------------------------------------------*/
|
||||
/*
|
||||
* Leptonica supplies image I/O for pnm, bmp, ps, and pdf.
|
||||
* Setting any of these to 0 causes non-functioning stubs to be linked.
|
||||
*/
|
||||
#define USE_BMPIO 1
|
||||
#define USE_PNMIO 1
|
||||
#define USE_PSIO 1
|
||||
#define USE_PDFIO 1
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------*
|
||||
* Built-in types *
|
||||
*--------------------------------------------------------------------*/
|
||||
typedef signed char l_int8;
|
||||
typedef unsigned char l_uint8;
|
||||
typedef short l_int16;
|
||||
typedef unsigned short l_uint16;
|
||||
typedef int l_int32;
|
||||
typedef unsigned int l_uint32;
|
||||
typedef float l_float32;
|
||||
typedef double l_float64;
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
* Standard macros *
|
||||
*------------------------------------------------------------------------*/
|
||||
#ifndef L_MIN
|
||||
#define L_MIN(x,y) (((x) < (y)) ? (x) : (y))
|
||||
#endif
|
||||
|
||||
#ifndef L_MAX
|
||||
#define L_MAX(x,y) (((x) > (y)) ? (x) : (y))
|
||||
#endif
|
||||
|
||||
#ifndef L_ABS
|
||||
#define L_ABS(x) (((x) < 0) ? (-1 * (x)) : (x))
|
||||
#endif
|
||||
|
||||
#ifndef L_SIGN
|
||||
#define L_SIGN(x) (((x) < 0) ? -1 : 1)
|
||||
#endif
|
||||
|
||||
#ifndef UNDEF
|
||||
#define UNDEF -1
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------*
|
||||
* Environ variables used within compiler invocation *
|
||||
*--------------------------------------------------------------------*/
|
||||
/*
|
||||
* To control conditional compilation, one of two variables
|
||||
*
|
||||
* L_LITTLE_ENDIAN (e.g., for Intel X86)
|
||||
* L_BIG_ENDIAN (e.g., for Sun SPARC, Mac Power PC)
|
||||
*
|
||||
* is defined when the GCC compiler is invoked.
|
||||
* All code should compile properly for both hardware architectures.
|
||||
*/
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
* Simple search state variables *
|
||||
*------------------------------------------------------------------------*/
|
||||
enum {
|
||||
L_NOT_FOUND = 0,
|
||||
L_FOUND = 1
|
||||
};
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
* Standard memory allocation *
|
||||
*
|
||||
* These specify the memory management functions that are used
|
||||
* on all heap data except for Pix. Memory management for Pix
|
||||
* also defaults to malloc and free. See pix1.c for details.
|
||||
*------------------------------------------------------------------------*/
|
||||
#define MALLOC(blocksize) malloc(blocksize)
|
||||
#define CALLOC(numelem, elemsize) calloc(numelem, elemsize)
|
||||
#define REALLOC(ptr, blocksize) realloc(ptr, blocksize)
|
||||
#define FREE(ptr) free(ptr)
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
* Control printing of error, warning, and info messages *
|
||||
* *
|
||||
* (Use -DNO_CONSOLE_IO on compiler line to prevent text output) *
|
||||
*------------------------------------------------------------------------*/
|
||||
#ifdef NO_CONSOLE_IO
|
||||
|
||||
#define PROCNAME(name)
|
||||
#define ERROR_PTR(a,b,c) ((void *)(c))
|
||||
#define ERROR_INT(a,b,c) ((l_int32)(c))
|
||||
#define ERROR_FLOAT(a,b,c) ((l_float32)(c))
|
||||
#define L_ERROR(a,b)
|
||||
#define L_ERROR_STRING(a,b,c)
|
||||
#define L_ERROR_INT(a,b,c)
|
||||
#define L_ERROR_FLOAT(a,b,c)
|
||||
#define L_WARNING(a,b)
|
||||
#define L_WARNING_STRING(a,b,c)
|
||||
#define L_WARNING_INT(a,b,c)
|
||||
#define L_WARNING_INT2(a,b,c,d)
|
||||
#define L_WARNING_FLOAT(a,b,c)
|
||||
#define L_WARNING_FLOAT2(a,b,c,d)
|
||||
#define L_INFO(a,b)
|
||||
#define L_INFO_STRING(a,b,c)
|
||||
#define L_INFO_INT(a,b,c)
|
||||
#define L_INFO_INT2(a,b,c,d)
|
||||
#define L_INFO_FLOAT(a,b,c)
|
||||
#define L_INFO_FLOAT2(a,b,c,d)
|
||||
|
||||
#else
|
||||
|
||||
#define PROCNAME(name) static const char procName[] = name
|
||||
#define ERROR_PTR(a,b,c) returnErrorPtr((a),(b),(c))
|
||||
#define ERROR_INT(a,b,c) returnErrorInt((a),(b),(c))
|
||||
#define ERROR_FLOAT(a,b,c) returnErrorFloat((a),(b),(c))
|
||||
#define L_ERROR(a,b) l_error((a),(b))
|
||||
#define L_ERROR_STRING(a,b,c) l_errorString((a),(b),(c))
|
||||
#define L_ERROR_INT(a,b,c) l_errorInt((a),(b),(c))
|
||||
#define L_ERROR_FLOAT(a,b,c) l_errorFloat((a),(b),(c))
|
||||
#define L_WARNING(a,b) l_warning((a),(b))
|
||||
#define L_WARNING_STRING(a,b,c) l_warningString((a),(b),(c))
|
||||
#define L_WARNING_INT(a,b,c) l_warningInt((a),(b),(c))
|
||||
#define L_WARNING_INT2(a,b,c,d) l_warningInt2((a),(b),(c),(d))
|
||||
#define L_WARNING_FLOAT(a,b,c) l_warningFloat((a),(b),(c))
|
||||
#define L_WARNING_FLOAT2(a,b,c,d) l_warningFloat2((a),(b),(c),(d))
|
||||
#define L_INFO(a,b) l_info((a),(b))
|
||||
#define L_INFO_STRING(a,b,c) l_infoString((a),(b),(c))
|
||||
#define L_INFO_INT(a,b,c) l_infoInt((a),(b),(c))
|
||||
#define L_INFO_INT2(a,b,c,d) l_infoInt2((a),(b),(c),(d))
|
||||
#define L_INFO_FLOAT(a,b,c) l_infoFloat((a),(b),(c))
|
||||
#define L_INFO_FLOAT2(a,b,c,d) l_infoFloat2((a),(b),(c),(d))
|
||||
|
||||
#endif /* NO_CONSOLE_IO */
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
* snprintf() renamed in MSVC *
|
||||
*------------------------------------------------------------------------*/
|
||||
#ifdef _MSC_VER
|
||||
#define snprintf(buf, size, ...) _snprintf_s(buf, size, _TRUNCATE, __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* LEPTONICA_ENVIRON_H */
|
||||
23
iOS/OCRPlugin/dependencies/include/leptonica/freetype.h
Normal file
23
iOS/OCRPlugin/dependencies/include/leptonica/freetype.h
Normal file
@@ -0,0 +1,23 @@
|
||||
/*====================================================================*
|
||||
- Copyright (C) 2008 Leptonica. All rights reserved.
|
||||
- This software is distributed in the hope that it will be
|
||||
- useful, but with NO WARRANTY OF ANY KIND.
|
||||
- No author or distributor accepts responsibility to anyone for the
|
||||
- consequences of using this software, or for whether it serves any
|
||||
- particular purpose or works at all, unless he or she says so in
|
||||
- writing. Everyone is granted permission to copy, modify and
|
||||
- redistribute this source code, for commercial or non-commercial
|
||||
- purposes, with the following restrictions: (1) the origin of this
|
||||
- source code must not be misrepresented; (2) modified versions must
|
||||
- be plainly marked as such; and (3) this notice may not be removed
|
||||
- or altered from any source or modified source distribution.
|
||||
*====================================================================*/
|
||||
|
||||
#ifndef LEPTONICA_FREETYPE_H
|
||||
#define LEPTONICA_FREETYPE_H
|
||||
|
||||
#define LEPTONICA_FT_RESOLUTION 96
|
||||
|
||||
typedef struct ft_library_st FT_LIBRARY;
|
||||
|
||||
#endif /* LEPTONICA_FREETYPE_H */
|
||||
77
iOS/OCRPlugin/dependencies/include/leptonica/gplot.h
Normal file
77
iOS/OCRPlugin/dependencies/include/leptonica/gplot.h
Normal file
@@ -0,0 +1,77 @@
|
||||
/*====================================================================*
|
||||
- Copyright (C) 2001 Leptonica. All rights reserved.
|
||||
- This software is distributed in the hope that it will be
|
||||
- useful, but with NO WARRANTY OF ANY KIND.
|
||||
- No author or distributor accepts responsibility to anyone for the
|
||||
- consequences of using this software, or for whether it serves any
|
||||
- particular purpose or works at all, unless he or she says so in
|
||||
- writing. Everyone is granted permission to copy, modify and
|
||||
- redistribute this source code, for commercial or non-commercial
|
||||
- purposes, with the following restrictions: (1) the origin of this
|
||||
- source code must not be misrepresented; (2) modified versions must
|
||||
- be plainly marked as such; and (3) this notice may not be removed
|
||||
- or altered from any source or modified source distribution.
|
||||
*====================================================================*/
|
||||
|
||||
#ifndef LEPTONICA_GPLOT_H
|
||||
#define LEPTONICA_GPLOT_H
|
||||
|
||||
/*
|
||||
* gplot.h
|
||||
*
|
||||
* Data structures and parameters for generating gnuplot files
|
||||
*/
|
||||
|
||||
#define GPLOT_VERSION_NUMBER 1
|
||||
|
||||
#define NUM_GPLOT_STYLES 5
|
||||
enum GPLOT_STYLE {
|
||||
GPLOT_LINES = 0,
|
||||
GPLOT_POINTS = 1,
|
||||
GPLOT_IMPULSES = 2,
|
||||
GPLOT_LINESPOINTS = 3,
|
||||
GPLOT_DOTS = 4
|
||||
};
|
||||
|
||||
#define NUM_GPLOT_OUTPUTS 6
|
||||
enum GPLOT_OUTPUT {
|
||||
GPLOT_NONE = 0,
|
||||
GPLOT_PNG = 1,
|
||||
GPLOT_PS = 2,
|
||||
GPLOT_EPS = 3,
|
||||
GPLOT_X11 = 4,
|
||||
GPLOT_LATEX = 5
|
||||
};
|
||||
|
||||
enum GPLOT_SCALING {
|
||||
GPLOT_LINEAR_SCALE = 0, /* default */
|
||||
GPLOT_LOG_SCALE_X = 1,
|
||||
GPLOT_LOG_SCALE_Y = 2,
|
||||
GPLOT_LOG_SCALE_X_Y = 3
|
||||
};
|
||||
|
||||
extern const char *gplotstylenames[]; /* used in gnuplot cmd file */
|
||||
extern const char *gplotfilestyles[]; /* used in simple file input */
|
||||
extern const char *gplotfileoutputs[]; /* used in simple file input */
|
||||
|
||||
struct GPlot
|
||||
{
|
||||
char *rootname; /* for cmd, data, output */
|
||||
char *cmdname; /* command file name */
|
||||
struct Sarray *cmddata; /* command file contents */
|
||||
struct Sarray *datanames; /* data file names */
|
||||
struct Sarray *plotdata; /* plot data (1 string/file) */
|
||||
struct Sarray *plottitles; /* title for each individual plot */
|
||||
struct Numa *plotstyles; /* plot style for individual plots */
|
||||
l_int32 nplots; /* current number of plots */
|
||||
char *outname; /* output file name */
|
||||
l_int32 outformat; /* GPLOT_OUTPUT values */
|
||||
l_int32 scaling; /* GPLOT_SCALING values */
|
||||
char *title; /* optional */
|
||||
char *xlabel; /* optional x axis label */
|
||||
char *ylabel; /* optional y axis label */
|
||||
};
|
||||
typedef struct GPlot GPLOT;
|
||||
|
||||
|
||||
#endif /* LEPTONICA_GPLOT_H */
|
||||
73
iOS/OCRPlugin/dependencies/include/leptonica/heap.h
Normal file
73
iOS/OCRPlugin/dependencies/include/leptonica/heap.h
Normal file
@@ -0,0 +1,73 @@
|
||||
/*====================================================================*
|
||||
- Copyright (C) 2001 Leptonica. All rights reserved.
|
||||
- This software is distributed in the hope that it will be
|
||||
- useful, but with NO WARRANTY OF ANY KIND.
|
||||
- No author or distributor accepts responsibility to anyone for the
|
||||
- consequences of using this software, or for whether it serves any
|
||||
- particular purpose or works at all, unless he or she says so in
|
||||
- writing. Everyone is granted permission to copy, modify and
|
||||
- redistribute this source code, for commercial or non-commercial
|
||||
- purposes, with the following restrictions: (1) the origin of this
|
||||
- source code must not be misrepresented; (2) modified versions must
|
||||
- be plainly marked as such; and (3) this notice may not be removed
|
||||
- or altered from any source or modified source distribution.
|
||||
*====================================================================*/
|
||||
|
||||
#ifndef LEPTONICA_HEAP_H
|
||||
#define LEPTONICA_HEAP_H
|
||||
|
||||
/*
|
||||
* heap.h
|
||||
*
|
||||
* Expandable priority queue configured as a heap for arbitrary void* data
|
||||
*
|
||||
* The L_Heap is used to implement a priority queue. The elements
|
||||
* in the heap are ordered in either increasing or decreasing key value.
|
||||
* The key is a float field 'keyval' that is required to be
|
||||
* contained in the elements of the queue.
|
||||
*
|
||||
* The heap is a simple binary tree with the following constraints:
|
||||
* - the key of each node is >= the keys of the two children
|
||||
* - the tree is complete, meaning that each level (1, 2, 4, ...)
|
||||
* is filled and the last level is filled from left to right
|
||||
*
|
||||
* The tree structure is implicit in the queue array, with the
|
||||
* array elements numbered as a breadth-first search of the tree
|
||||
* from left to right. It is thus guaranteed that the largest
|
||||
* (or smallest) key belongs to the first element in the array.
|
||||
*
|
||||
* Heap sort is used to sort the array. Once an array has been
|
||||
* sorted as a heap, it is convenient to use it as a priority queue,
|
||||
* because the min (or max) elements are always at the root of
|
||||
* the tree (element 0), and once removed, the heap can be
|
||||
* resorted in not more than log[n] steps, where n is the number
|
||||
* of elements on the heap. Likewise, if an arbitrary element is
|
||||
* added to the end of the array A, the sorted heap can be restored
|
||||
* in not more than log[n] steps.
|
||||
*
|
||||
* A L_Heap differs from a L_Queue in that the elements in the former
|
||||
* are sorted by a key. Internally, the array is maintained
|
||||
* as a queue, with a pointer to the end of the array. The
|
||||
* head of the array always remains at array[0]. The array is
|
||||
* maintained (sorted) as a heap. When an item is removed from
|
||||
* the head, the last item takes its place (thus reducing the
|
||||
* array length by 1), and this is followed by array element
|
||||
* swaps to restore the heap property. When an item is added,
|
||||
* it goes at the end of the array, and is swapped up to restore
|
||||
* the heap. If the ptr array is full, adding another item causes
|
||||
* the ptr array size to double.
|
||||
*
|
||||
* For further implementation details, see heap.c.
|
||||
*/
|
||||
|
||||
struct L_Heap
|
||||
{
|
||||
l_int32 nalloc; /* size of allocated ptr array */
|
||||
l_int32 n; /* number of elements stored in the heap */
|
||||
void **array; /* ptr array */
|
||||
l_int32 direction; /* L_SORT_INCREASING or L_SORT_DECREASING */
|
||||
};
|
||||
typedef struct L_Heap L_HEAP;
|
||||
|
||||
|
||||
#endif /* LEPTONICA_HEAP_H */
|
||||
153
iOS/OCRPlugin/dependencies/include/leptonica/imageio.h
Normal file
153
iOS/OCRPlugin/dependencies/include/leptonica/imageio.h
Normal file
@@ -0,0 +1,153 @@
|
||||
/*====================================================================*
|
||||
- Copyright (C) 2001 Leptonica. All rights reserved.
|
||||
- This software is distributed in the hope that it will be
|
||||
- useful, but with NO WARRANTY OF ANY KIND.
|
||||
- No author or distributor accepts responsibility to anyone for the
|
||||
- consequences of using this software, or for whether it serves any
|
||||
- particular purpose or works at all, unless he or she says so in
|
||||
- writing. Everyone is granted permission to copy, modify and
|
||||
- redistribute this source code, for commercial or non-commercial
|
||||
- purposes, with the following restrictions: (1) the origin of this
|
||||
- source code must not be misrepresented; (2) modified versions must
|
||||
- be plainly marked as such; and (3) this notice may not be removed
|
||||
- or altered from any source or modified source distribution.
|
||||
*====================================================================*/
|
||||
|
||||
#ifndef LEPTONICA_IMAGEIO_H
|
||||
#define LEPTONICA_IMAGEIO_H
|
||||
|
||||
/* ------------------ Image file format types -------------- */
|
||||
/*
|
||||
* The IFF_DEFAULT flag is used to write the file out in the
|
||||
* same (input) file format that the pix was read from. If the pix
|
||||
* was not read from file, the input format field will be
|
||||
* IFF_UNKNOWN and the output file format will be chosen to
|
||||
* be compressed and lossless; namely, IFF_TIFF_G4 for d = 1
|
||||
* and IFF_PNG for everything else. IFF_JP2 is for jpeg2000, which
|
||||
* is not supported in leptonica.
|
||||
*
|
||||
* In the future, new format types that have defined extensions
|
||||
* will be added before IFF_DEFAULT, and will be kept in sync with
|
||||
* the file format extensions in writefile.c. The positions of
|
||||
* file formats before IFF_DEFAULT will remain invariant.
|
||||
*/
|
||||
enum {
|
||||
IFF_UNKNOWN = 0,
|
||||
IFF_BMP = 1,
|
||||
IFF_JFIF_JPEG = 2,
|
||||
IFF_PNG = 3,
|
||||
IFF_TIFF = 4,
|
||||
IFF_TIFF_PACKBITS = 5,
|
||||
IFF_TIFF_RLE = 6,
|
||||
IFF_TIFF_G3 = 7,
|
||||
IFF_TIFF_G4 = 8,
|
||||
IFF_TIFF_LZW = 9,
|
||||
IFF_TIFF_ZIP = 10,
|
||||
IFF_PNM = 11,
|
||||
IFF_PS = 12,
|
||||
IFF_GIF = 13,
|
||||
IFF_JP2 = 14,
|
||||
IFF_WEBP = 15,
|
||||
IFF_LPDF = 16,
|
||||
IFF_DEFAULT = 17,
|
||||
IFF_SPIX = 18
|
||||
};
|
||||
|
||||
|
||||
/* ---------------------- Format header ids --------------------- */
|
||||
enum {
|
||||
BMP_ID = 0x4d42,
|
||||
TIFF_BIGEND_ID = 0x4d4d, /* MM - for 'motorola' */
|
||||
TIFF_LITTLEEND_ID = 0x4949 /* II - for 'intel' */
|
||||
};
|
||||
|
||||
|
||||
/* ------------------ Gray hinting in jpeg reader --------------- */
|
||||
enum {
|
||||
L_HINT_GRAY = 1, /* only want grayscale information */
|
||||
};
|
||||
|
||||
|
||||
/* ------------------ Pdf formated encoding types --------------- */
|
||||
enum {
|
||||
L_JPEG_ENCODE = 1, /* use dct encoding: 8 and 32 bpp, no cmap */
|
||||
L_G4_ENCODE = 2, /* use ccitt g4 fax encoding: 1 bpp */
|
||||
L_FLATE_ENCODE = 3 /* use flate encoding: any depth, cmap ok */
|
||||
};
|
||||
|
||||
|
||||
/* ------------------ Compressed image data --------------------- */
|
||||
/*
|
||||
* In use, either datacomp or data85 will be produced, depending
|
||||
* on whether the data needs to be ascii85 encoded. PostScript
|
||||
* requires ascii85 encoding; pdf does not.
|
||||
*
|
||||
* For the colormap (flate compression only), PostScript uses ascii85
|
||||
* encoding and pdf uses a bracketed array of space-separated
|
||||
* hex-encoded rgb triples. Only tiff g4 (type == L_G4_ENCODE) uses
|
||||
* the minisblack field.
|
||||
*/
|
||||
struct L_Compressed_Data
|
||||
{
|
||||
l_int32 type; /* encoding type: L_JPEG_ENCODE, etc */
|
||||
l_uint8 *datacomp; /* gzipped raster data */
|
||||
size_t nbytescomp; /* number of compressed bytes */
|
||||
char *data85; /* ascii85-encoded gzipped raster data */
|
||||
size_t nbytes85; /* number of ascii85 encoded bytes */
|
||||
char *cmapdata85; /* ascii85-encoded uncompressed cmap */
|
||||
char *cmapdatahex; /* hex pdf array for the cmap */
|
||||
l_int32 ncolors; /* number of colors in cmap */
|
||||
l_int32 w; /* image width */
|
||||
l_int32 h; /* image height */
|
||||
l_int32 bps; /* bits/sample; typ. 1, 2, 4 or 8 */
|
||||
l_int32 spp; /* samples/pixel; typ. 1 or 3 */
|
||||
l_int32 minisblack; /* tiff g4 photometry */
|
||||
size_t nbytes; /* number of uncompressed raster bytes */
|
||||
l_int32 res; /* resolution (ppi) */
|
||||
};
|
||||
typedef struct L_Compressed_Data L_COMPRESSED_DATA;
|
||||
|
||||
|
||||
/* ------------------------ Pdf multi-image flags ------------------------ */
|
||||
enum {
|
||||
L_FIRST_IMAGE = 1, /* first image to be used */
|
||||
L_NEXT_IMAGE = 2, /* intermediate image; not first or last */
|
||||
L_LAST_IMAGE = 3 /* last image to be used */
|
||||
};
|
||||
|
||||
|
||||
/* ------------------ Intermediate pdf generation data -------------------- */
|
||||
/*
|
||||
* This accumulates data for generating a pdf of a single page consisting
|
||||
* of an arbitrary number of images.
|
||||
*
|
||||
* None of the strings have a trailing newline.
|
||||
*/
|
||||
struct L_Pdf_Data
|
||||
{
|
||||
char *title; /* optional title for pdf */
|
||||
l_int32 n; /* number of images */
|
||||
l_int32 ncmap; /* number of colormaps */
|
||||
struct L_Ptra *cida; /* array of compressed image data */
|
||||
char *id; /* %PDF-1.2 id string */
|
||||
char *obj1; /* catalog string */
|
||||
char *obj2; /* metadata string */
|
||||
char *obj3; /* pages string */
|
||||
char *obj4; /* page string (variable data) */
|
||||
char *obj5; /* content string (variable data) */
|
||||
char *poststream; /* post-binary-stream string */
|
||||
char *trailer; /* trailer string (variable data) */
|
||||
struct Pta *xy; /* store (xpt, ypt) array */
|
||||
struct Pta *wh; /* store (wpt, hpt) array */
|
||||
struct Box *mediabox; /* bounding region for all images */
|
||||
struct Sarray *saprex; /* pre-binary-stream xobject strings */
|
||||
struct Sarray *sacmap; /* colormap pdf object strings */
|
||||
struct Numa *objsize; /* sizes of each pdf string object */
|
||||
struct Numa *objloc; /* location of each pdf string object */
|
||||
l_int32 xrefloc; /* location of xref */
|
||||
};
|
||||
typedef struct L_Pdf_Data L_PDF_DATA;
|
||||
|
||||
|
||||
#endif /* LEPTONICA_IMAGEIO_H */
|
||||
|
||||
122
iOS/OCRPlugin/dependencies/include/leptonica/jbclass.h
Normal file
122
iOS/OCRPlugin/dependencies/include/leptonica/jbclass.h
Normal file
@@ -0,0 +1,122 @@
|
||||
/*====================================================================*
|
||||
- Copyright (C) 2001 Leptonica. All rights reserved.
|
||||
- This software is distributed in the hope that it will be
|
||||
- useful, but with NO WARRANTY OF ANY KIND.
|
||||
- No author or distributor accepts responsibility to anyone for the
|
||||
- consequences of using this software, or for whether it serves any
|
||||
- particular purpose or works at all, unless he or she says so in
|
||||
- writing. Everyone is granted permission to copy, modify and
|
||||
- redistribute this source code, for commercial or non-commercial
|
||||
- purposes, with the following restrictions: (1) the origin of this
|
||||
- source code must not be misrepresented; (2) modified versions must
|
||||
- be plainly marked as such; and (3) this notice may not be removed
|
||||
- or altered from any source or modified source distribution.
|
||||
*====================================================================*/
|
||||
|
||||
#ifndef LEPTONICA_JBCLASS_H
|
||||
#define LEPTONICA_JBCLASS_H
|
||||
|
||||
/*
|
||||
* jbclass.h
|
||||
*
|
||||
* JbClasser
|
||||
* JbData
|
||||
*/
|
||||
|
||||
|
||||
/* The JbClasser struct holds all the data accumulated during the
|
||||
* classification process that can be used for a compressed
|
||||
* jbig2-type representation of a set of images. This is created
|
||||
* in an initialization process and added to as the selected components
|
||||
* on each successive page are analyzed. */
|
||||
struct JbClasser
|
||||
{
|
||||
struct Sarray *safiles; /* input page image file names */
|
||||
l_int32 method; /* JB_RANKHAUS, JB_CORRELATION */
|
||||
l_int32 components; /* JB_CONN_COMPS, JB_CHARACTERS or */
|
||||
/* JB_WORDS */
|
||||
l_int32 maxwidth; /* max component width allowed */
|
||||
l_int32 maxheight; /* max component height allowed */
|
||||
l_int32 npages; /* number of pages already processed */
|
||||
l_int32 baseindex; /* number of components already processed */
|
||||
/* on fully processed pages */
|
||||
struct Numa *nacomps; /* number of components on each page */
|
||||
l_int32 sizehaus; /* size of square struct element for haus */
|
||||
l_float32 rankhaus; /* rank val of haus match, each way */
|
||||
l_float32 thresh; /* thresh value for correlation score */
|
||||
l_float32 weightfactor; /* corrects thresh value for heaver */
|
||||
/* components; use 0 for no correction */
|
||||
struct Numa *naarea; /* w * h of each template, without extra */
|
||||
/* border pixels */
|
||||
l_int32 w; /* max width of original src images */
|
||||
l_int32 h; /* max height of original src images */
|
||||
l_int32 nclass; /* current number of classes */
|
||||
l_int32 keep_pixaa; /* If zero, pixaa isn't filled */
|
||||
struct Pixaa *pixaa; /* instances for each class; unbordered */
|
||||
struct Pixa *pixat; /* templates for each class; bordered */
|
||||
/* and not dilated */
|
||||
struct Pixa *pixatd; /* templates for each class; bordered */
|
||||
/* and dilated */
|
||||
struct NumaHash *nahash; /* Hash table to find templates by size */
|
||||
struct Numa *nafgt; /* fg areas of undilated templates; */
|
||||
/* only used for rank < 1.0 */
|
||||
struct Pta *ptac; /* centroids of all bordered cc */
|
||||
struct Pta *ptact; /* centroids of all bordered template cc */
|
||||
struct Numa *naclass; /* array of class ids for each component */
|
||||
struct Numa *napage; /* array of page nums for each component */
|
||||
struct Pta *ptaul; /* array of UL corners at which the */
|
||||
/* template is to be placed for each */
|
||||
/* component */
|
||||
struct Pta *ptall; /* similar to ptaul, but for LL corners */
|
||||
};
|
||||
typedef struct JbClasser JBCLASSER;
|
||||
|
||||
|
||||
/* The JbData struct holds all the data required for
|
||||
* the compressed jbig-type representation of a set of images.
|
||||
* The data can be written to file, read back, and used
|
||||
* to regenerate an approximate version of the original,
|
||||
* which differs in two ways from the original:
|
||||
* (1) It uses a template image for each c.c. instead of the
|
||||
* original instance, for each occurrence on each page.
|
||||
* (2) It discards components with either a height or width larger
|
||||
* than the maximuma, given here by the lattice dimensions
|
||||
* used for storing the templates. */
|
||||
struct JbData
|
||||
{
|
||||
struct Pix *pix; /* template composite for all classes */
|
||||
l_int32 npages; /* number of pages */
|
||||
l_int32 w; /* max width of original page images */
|
||||
l_int32 h; /* max height of original page images */
|
||||
l_int32 nclass; /* number of classes */
|
||||
l_int32 latticew; /* lattice width for template composite */
|
||||
l_int32 latticeh; /* lattice height for template composite */
|
||||
struct Numa *naclass; /* array of class ids for each component */
|
||||
struct Numa *napage; /* array of page nums for each component */
|
||||
struct Pta *ptaul; /* array of UL corners at which the */
|
||||
/* template is to be placed for each */
|
||||
/* component */
|
||||
};
|
||||
typedef struct JbData JBDATA;
|
||||
|
||||
|
||||
/* Classifier methods */
|
||||
enum {
|
||||
JB_RANKHAUS = 0,
|
||||
JB_CORRELATION = 1
|
||||
};
|
||||
|
||||
/* For jbGetComponents(): type of component to extract from images */
|
||||
enum {
|
||||
JB_CONN_COMPS = 0,
|
||||
JB_CHARACTERS = 1,
|
||||
JB_WORDS = 2
|
||||
};
|
||||
|
||||
/* These parameters are used for naming the two files
|
||||
* in which the jbig2-like compressed data is stored. */
|
||||
#define JB_TEMPLATE_EXT ".templates.png"
|
||||
#define JB_DATA_EXT ".data"
|
||||
|
||||
|
||||
#endif /* LEPTONICA_JBCLASS_H */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user