Browse Source

2017/6/18

YanaDH 8 years ago
parent
commit
cdbff6480e
100 changed files with 7123 additions and 258 deletions
  1. 1 0
      .gitignore
  2. BIN
      .vs/miaomiao/v14/.suo
  3. BIN
      miaomiao/bin/Android/Debug/android-debug-unaligned.apk
  4. BIN
      miaomiao/bin/Android/Debug/android-debug.apk
  5. 9 5
      miaomiao/config.xml
  6. 5 1
      miaomiao/miaomiao.jsproj.user
  7. 3 1
      miaomiao/package.json
  8. 1 1
      miaomiao/platforms/android/build/generated/source/buildConfig/debug/com/ionicframework/ionictabs121641/BuildConfig.java
  9. 1 0
      miaomiao/platforms/android/build/generated/source/r/debug/com/ionicframework/ionictabs121641/R.java
  10. 35 1
      miaomiao/platforms/android/build/intermediates/assets/debug/www/cordova-js-src/platform.js
  11. 197 9
      miaomiao/platforms/android/build/intermediates/assets/debug/www/cordova.js
  12. 207 6
      miaomiao/platforms/android/build/intermediates/assets/debug/www/cordova_plugins.js
  13. 7 3
      miaomiao/platforms/android/build/intermediates/assets/debug/www/css/style.css
  14. 1 1
      miaomiao/platforms/android/build/intermediates/assets/debug/www/index.html
  15. 21 7
      miaomiao/platforms/android/build/intermediates/assets/debug/www/js/controllers/account.js
  16. 38 5
      miaomiao/platforms/android/build/intermediates/assets/debug/www/js/controllers/my.js
  17. 4 30
      miaomiao/platforms/android/build/intermediates/assets/debug/www/js/services/userservice.js
  18. 2 1
      miaomiao/platforms/android/build/intermediates/assets/debug/www/plugins/cordova-plugin-device/www/device.js
  19. 2 1
      miaomiao/platforms/android/build/intermediates/assets/debug/www/plugins/cordova-plugin-splashscreen/www/splashscreen.js
  20. 2 1
      miaomiao/platforms/android/build/intermediates/assets/debug/www/plugins/cordova-plugin-statusbar/www/statusbar.js
  21. 2 1
      miaomiao/platforms/android/build/intermediates/assets/debug/www/plugins/ionic-plugin-keyboard/www/android/keyboard.js
  22. 1 1
      miaomiao/platforms/android/build/intermediates/assets/debug/www/templates/account/login.html
  23. 10 7
      miaomiao/platforms/android/build/intermediates/assets/debug/www/templates/add/index.html
  24. 4 4
      miaomiao/platforms/android/build/intermediates/assets/debug/www/templates/home/index.html
  25. 2 2
      miaomiao/platforms/android/build/intermediates/assets/debug/www/templates/home/search.html
  26. 2 1
      miaomiao/platforms/android/build/intermediates/assets/debug/www/templates/my/index.html
  27. 2 2
      miaomiao/platforms/android/build/intermediates/assets/debug/www/templates/my/my-profile.html
  28. BIN
      miaomiao/platforms/android/build/intermediates/classes/debug/com/ionicframework/ionictabs121641/BuildConfig.class
  29. BIN
      miaomiao/platforms/android/build/intermediates/classes/debug/com/ionicframework/ionictabs121641/R$xml.class
  30. BIN
      miaomiao/platforms/android/build/intermediates/classes/debug/org/apache/cordova/device/Device.class
  31. BIN
      miaomiao/platforms/android/build/intermediates/classes/debug/org/apache/cordova/splashscreen/SplashScreen.class
  32. 25 4
      miaomiao/platforms/android/build/intermediates/dex-cache/cache.xml
  33. BIN
      miaomiao/platforms/android/build/intermediates/dex/debug/classes.dex
  34. BIN
      miaomiao/platforms/android/build/intermediates/exploded-aar/android/CordovaLib/unspecified/debug/classes.jar
  35. BIN
      miaomiao/platforms/android/build/intermediates/incremental/aidl/debug/dependency.store
  36. 0 1
      miaomiao/platforms/android/build/intermediates/incremental/mergeAssets/debug/merger.xml
  37. 0 1
      miaomiao/platforms/android/build/intermediates/incremental/mergeResources/debug/merger.xml
  38. 13 4
      miaomiao/platforms/android/build/intermediates/manifests/full/debug/AndroidManifest.xml
  39. BIN
      miaomiao/platforms/android/build/intermediates/pre-dexed/debug/classes-b5048828b0dfe60f63719a1d6257ef873b6751a3.jar
  40. BIN
      miaomiao/platforms/android/build/intermediates/res/debug/drawable-hdpi-v4/icon.png
  41. BIN
      miaomiao/platforms/android/build/intermediates/res/debug/drawable-land-hdpi-v4/screen.png
  42. BIN
      miaomiao/platforms/android/build/intermediates/res/debug/drawable-land-ldpi-v4/screen.png
  43. BIN
      miaomiao/platforms/android/build/intermediates/res/debug/drawable-land-mdpi-v4/screen.png
  44. BIN
      miaomiao/platforms/android/build/intermediates/res/debug/drawable-land-xhdpi-v4/screen.png
  45. BIN
      miaomiao/platforms/android/build/intermediates/res/debug/drawable-land-xxhdpi-v4/screen.png
  46. BIN
      miaomiao/platforms/android/build/intermediates/res/debug/drawable-land-xxxhdpi-v4/screen.png
  47. BIN
      miaomiao/platforms/android/build/intermediates/res/debug/drawable-ldpi-v4/icon.png
  48. BIN
      miaomiao/platforms/android/build/intermediates/res/debug/drawable-mdpi-v4/icon.png
  49. BIN
      miaomiao/platforms/android/build/intermediates/res/debug/drawable-port-hdpi-v4/screen.png
  50. BIN
      miaomiao/platforms/android/build/intermediates/res/debug/drawable-port-ldpi-v4/screen.png
  51. BIN
      miaomiao/platforms/android/build/intermediates/res/debug/drawable-port-mdpi-v4/screen.png
  52. BIN
      miaomiao/platforms/android/build/intermediates/res/debug/drawable-port-xhdpi-v4/screen.png
  53. BIN
      miaomiao/platforms/android/build/intermediates/res/debug/drawable-port-xxhdpi-v4/screen.png
  54. BIN
      miaomiao/platforms/android/build/intermediates/res/debug/drawable-port-xxxhdpi-v4/screen.png
  55. BIN
      miaomiao/platforms/android/build/intermediates/res/debug/drawable-xhdpi-v4/icon.png
  56. BIN
      miaomiao/platforms/android/build/intermediates/res/debug/drawable-xxhdpi-v4/icon.png
  57. BIN
      miaomiao/platforms/android/build/intermediates/res/debug/drawable-xxxhdpi-v4/icon.png
  58. 0 8
      miaomiao/platforms/android/build/intermediates/res/debug/values/values.xml
  59. 0 63
      miaomiao/platforms/android/build/intermediates/res/debug/xml/config.xml
  60. BIN
      miaomiao/platforms/android/build/intermediates/res/resources-debug.ap_
  61. 1 0
      miaomiao/platforms/android/build/intermediates/symbols/debug/R.txt
  62. 0 2
      miaomiao/platforms/android/build/intermediates/tmp/dex/debug/inputList.txt
  63. BIN
      miaomiao/platforms/android/build/outputs/apk/android-debug-unaligned.apk
  64. 0 84
      miaomiao/platforms/android/build/outputs/apk/manifest-merger-debug-report.txt
  65. BIN
      miaomiao/platforms/android/build/outputs/apk/喵喵.apk
  66. 15 0
      miaomiao/plugins/android.json
  67. 163 0
      miaomiao/plugins/cordova-plugin-actionsheet/README.md
  68. 43 0
      miaomiao/plugins/cordova-plugin-actionsheet/package.json
  69. 76 0
      miaomiao/plugins/cordova-plugin-actionsheet/plugin.xml
  70. 196 0
      miaomiao/plugins/cordova-plugin-actionsheet/src/android/ActionSheet.java
  71. 132 0
      miaomiao/plugins/cordova-plugin-actionsheet/src/browser/ActionSheetProxy.js
  72. 13 0
      miaomiao/plugins/cordova-plugin-actionsheet/src/ios/ActionSheet.h
  73. 186 0
      miaomiao/plugins/cordova-plugin-actionsheet/src/ios/ActionSheet.m
  74. 217 0
      miaomiao/plugins/cordova-plugin-actionsheet/src/windows/ActionSheetProxy.js
  75. 209 0
      miaomiao/plugins/cordova-plugin-actionsheet/src/wp8/ActionSheet.cs
  76. 30 0
      miaomiao/plugins/cordova-plugin-actionsheet/www/ActionSheet.js
  77. 37 0
      miaomiao/plugins/cordova-plugin-camera/CONTRIBUTING.md
  78. 202 0
      miaomiao/plugins/cordova-plugin-camera/LICENSE
  79. 5 0
      miaomiao/plugins/cordova-plugin-camera/NOTICE
  80. 793 0
      miaomiao/plugins/cordova-plugin-camera/README.md
  81. 360 0
      miaomiao/plugins/cordova-plugin-camera/RELEASENOTES.md
  82. 628 0
      miaomiao/plugins/cordova-plugin-camera/appium-tests/android/android.spec.js
  83. 305 0
      miaomiao/plugins/cordova-plugin-camera/appium-tests/helpers/cameraHelper.js
  84. 489 0
      miaomiao/plugins/cordova-plugin-camera/appium-tests/ios/ios.spec.js
  85. 421 0
      miaomiao/plugins/cordova-plugin-camera/doc/de/README.md
  86. 434 0
      miaomiao/plugins/cordova-plugin-camera/doc/de/index.md
  87. 411 0
      miaomiao/plugins/cordova-plugin-camera/doc/es/README.md
  88. 391 0
      miaomiao/plugins/cordova-plugin-camera/doc/es/index.md
  89. 378 0
      miaomiao/plugins/cordova-plugin-camera/doc/fr/README.md
  90. 391 0
      miaomiao/plugins/cordova-plugin-camera/doc/fr/index.md
  91. BIN
      miaomiao/plugins/cordova-plugin-camera/doc/img/android-fail.png
  92. BIN
      miaomiao/plugins/cordova-plugin-camera/doc/img/android-success.png
  93. BIN
      miaomiao/plugins/cordova-plugin-camera/doc/img/blackberry-fail.png
  94. BIN
      miaomiao/plugins/cordova-plugin-camera/doc/img/blackberry-success.png
  95. BIN
      miaomiao/plugins/cordova-plugin-camera/doc/img/browser-fail.png
  96. BIN
      miaomiao/plugins/cordova-plugin-camera/doc/img/browser-success.png
  97. BIN
      miaomiao/plugins/cordova-plugin-camera/doc/img/firefox-fail.png
  98. BIN
      miaomiao/plugins/cordova-plugin-camera/doc/img/firefox-success.png
  99. BIN
      miaomiao/plugins/cordova-plugin-camera/doc/img/fireos-fail.png
  100. BIN
      miaomiao/plugins/cordova-plugin-camera/doc/img/fireos-success.png

+ 1 - 0
.gitignore

xqd
@@ -21,3 +21,4 @@ server/public/apidoc/
 miaomiao/miaomiao/platforms/android/.gradle/2.2.1/taskArtifacts/cache.properties.lock
 miaomiao/miaomiao/platforms/android/.gradle/2.2.1/taskArtifacts/fileHashes.bin
 
+platforms

BIN
.vs/miaomiao/v14/.suo


BIN
miaomiao/bin/Android/Debug/android-debug-unaligned.apk


BIN
miaomiao/bin/Android/Debug/android-debug.apk


+ 9 - 5
miaomiao/config.xml

xqd xqd
@@ -24,11 +24,6 @@
   <feature name="StatusBar">
     <param name="ios-package" onload="true" value="CDVStatusBar"/>
   </feature>
-  <plugin name="cordova-plugin-device" spec="~1.1.1"/>
-  <plugin name="cordova-plugin-console" spec="~1.0.2"/>
-  <plugin name="cordova-plugin-whitelist" spec="~1.2.1"/>
-  <plugin name="cordova-plugin-statusbar" spec="~2.1.0"/>
-  <plugin name="ionic-plugin-keyboard" spec="~1.0.9"/>
   <platform name="ios">
     <icon height="57" src="resources/ios/icon/icon.png" width="57"/>
     <icon height="114" src="resources/ios/icon/icon@2x.png" width="114"/>
@@ -81,4 +76,13 @@
     <splash src="resources/android/splash/drawable-port-xxhdpi-screen.png" density="port-xxhdpi"/>
     <splash src="resources/android/splash/drawable-port-xxxhdpi-screen.png" density="port-xxxhdpi"/>
   </platform>
+  <plugin name="cordova-plugin-device" spec="~1.1.1"/>
+  <plugin name="cordova-plugin-console" spec="~1.0.2"/>
+  <plugin name="cordova-plugin-whitelist" spec="~1.2.1"/>
+  <plugin name="cordova-plugin-statusbar" spec="~2.1.0"/>
+  <plugin name="ionic-plugin-keyboard" spec="~1.0.9"/>
+  <plugin name="cordova-plugin-file-transfer" version="1.6.2" />
+  <plugin name="cordova-plugin-file" version="4.3.2" />
+  <plugin name="cordova-plugin-camera" version="2.4.0" />
+  <plugin name="cordova-plugin-actionsheet" version="2.3.3" />
 </widget>

+ 5 - 1
miaomiao/miaomiao.jsproj.user

xqd
@@ -1,6 +1,10 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <PropertyGroup>
-    <ReferenceCachePath>C:\Users\RD2\AppData\Local\Temp\miaomiao_refcache</ReferenceCachePath>
+    <ReferenceCachePath>C:\Users\Ben\AppData\Local\Temp\miaomiao_refcache</ReferenceCachePath>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Android'">
+    <DebuggerFlavor>AndroidEmulator</DebuggerFlavor>
+    <AndroidEmulatorID>AndroidDevice;设备</AndroidEmulatorID>
   </PropertyGroup>
 </Project>

+ 3 - 1
miaomiao/package.json

xqd
@@ -21,7 +21,9 @@
     "cordova-plugin-console",
     "cordova-plugin-whitelist",
     "cordova-plugin-statusbar",
-    "ionic-plugin-keyboard"
+    "ionic-plugin-keyboard",
+    "cordova-plugin-file-transfer@1.6.2",
+    "cordova-plugin-camera@2.4.0"
   ],
   "cordovaPlatforms": []
 }

+ 1 - 1
miaomiao/platforms/android/build/generated/source/buildConfig/debug/com/ionicframework/ionictabs121641/BuildConfig.java

xqd
@@ -9,5 +9,5 @@ public final class BuildConfig {
   public static final String BUILD_TYPE = "debug";
   public static final String FLAVOR = "";
   public static final int VERSION_CODE = 18;
-  public static final String VERSION_NAME = "";
+  public static final String VERSION_NAME = "0.0.1";
 }

+ 1 - 0
miaomiao/platforms/android/build/generated/source/r/debug/com/ionicframework/ionictabs121641/R.java

xqd
@@ -21,5 +21,6 @@ public final class R {
     }
     public static final class xml {
         public static final int config=0x7f030000;
+        public static final int provider_paths=0x7f030001;
     }
 }

+ 35 - 1
miaomiao/platforms/android/build/intermediates/assets/debug/www/cordova-js-src/platform.js

xqd xqd xqd
@@ -19,6 +19,9 @@
  *
 */
 
+// The last resume event that was received that had the result of a plugin call.
+var lastResumeEvent = null;
+
 module.exports = {
     id: 'android',
     bootstrap: function() {
@@ -58,6 +61,19 @@ module.exports = {
         bindButtonChannel('volumeup');
         bindButtonChannel('volumedown');
 
+        // The resume event is not "sticky", but it is possible that the event
+        // will contain the result of a plugin call. We need to ensure that the
+        // plugin result is delivered even after the event is fired (CB-10498)
+        var cordovaAddEventListener = document.addEventListener;
+
+        document.addEventListener = function(evt, handler, capture) {
+            cordovaAddEventListener(evt, handler, capture);
+
+            if (evt === 'resume' && lastResumeEvent) {
+                handler(lastResumeEvent);
+            }
+        };
+
         // Let native code know we are all done on the JS side.
         // Native code will then un-hide the WebView.
         channel.onCordovaReady.subscribe(function() {
@@ -79,12 +95,30 @@ function onMessageFromNative(msg) {
         case 'searchbutton':
         // App life cycle events
         case 'pause':
-        case 'resume':
         // Volume events
         case 'volumedownbutton':
         case 'volumeupbutton':
             cordova.fireDocumentEvent(action);
             break;
+        case 'resume':
+            if(arguments.length > 1 && msg.pendingResult) {
+                if(arguments.length === 2) {
+                    msg.pendingResult.result = arguments[1];
+                } else {
+                    // The plugin returned a multipart message
+                    var res = [];
+                    for(var i = 1; i < arguments.length; i++) {
+                        res.push(arguments[i]);
+                    }
+                    msg.pendingResult.result = res;
+                }
+
+                // Save the plugin result so that it can be delivered to the js
+                // even if they miss the initial firing of the event
+                lastResumeEvent = msg;
+            }
+            cordova.fireDocumentEvent(action, msg);
+            break;
         default:
             throw new Error('Unknown event action ' + action);
     }

+ 197 - 9
miaomiao/platforms/android/build/intermediates/assets/debug/www/cordova.js

xqd xqd xqd xqd xqd xqd xqd xqd xqd xqd
@@ -1,5 +1,5 @@
 // Platform: android
-// 2c29e187e4206a6a77fba940ef6f77aef5c7eb8c
+// c517ca811b4948b630e0b74dbae6c9637939da24
 /*
  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
@@ -19,7 +19,7 @@
  under the License.
 */
 ;(function() {
-var PLATFORM_VERSION_BUILD_LABEL = '4.1.1';
+var PLATFORM_VERSION_BUILD_LABEL = '5.1.1';
 // file: src/scripts/require.js
 
 /*jshint -W079 */
@@ -101,7 +101,9 @@ if (typeof module === "object" && typeof require === "function") {
 // file: src/cordova.js
 define("cordova", function(require, exports, module) {
 
-if(window.cordova){
+// Workaround for Windows 10 in hosted environment case
+// http://www.w3.org/html/wg/drafts/html/master/browsers.html#named-access-on-the-window-object
+if (window.cordova && !(window.cordova instanceof HTMLElement)) {
     throw new Error("cordova already defined");
 }
 
@@ -1291,10 +1293,12 @@ define("cordova/init_b", function(require, exports, module) {
 
 var channel = require('cordova/channel');
 var cordova = require('cordova');
+var modulemapper = require('cordova/modulemapper');
 var platform = require('cordova/platform');
+var pluginloader = require('cordova/pluginloader');
 var utils = require('cordova/utils');
 
-var platformInitChannelsArray = [channel.onDOMContentLoaded, channel.onNativeReady];
+var platformInitChannelsArray = [channel.onDOMContentLoaded, channel.onNativeReady, channel.onPluginsReady];
 
 // setting exec
 cordova.exec = require('cordova/exec');
@@ -1379,10 +1383,19 @@ if (window._nativeReady) {
 // Call the platform-specific initialization.
 platform.bootstrap && platform.bootstrap();
 
+// Wrap in a setTimeout to support the use-case of having plugin JS appended to cordova.js.
+// The delay allows the attached modules to be defined before the plugin loader looks for them.
+setTimeout(function() {
+    pluginloader.load(function() {
+        channel.onPluginsReady.fire();
+    });
+}, 0);
+
 /**
  * Create all cordova objects once native side is ready.
  */
 channel.join(function() {
+    modulemapper.mapModules(window);
 
     platform.initialize && platform.initialize();
 
@@ -1499,11 +1512,111 @@ exports.getOriginalSymbol = function(context, symbolPath) {
 exports.reset();
 
 
+});
+
+// file: src/common/modulemapper_b.js
+define("cordova/modulemapper_b", function(require, exports, module) {
+
+var builder = require('cordova/builder'),
+    symbolList = [],
+    deprecationMap;
+
+exports.reset = function() {
+    symbolList = [];
+    deprecationMap = {};
+};
+
+function addEntry(strategy, moduleName, symbolPath, opt_deprecationMessage) {
+    symbolList.push(strategy, moduleName, symbolPath);
+    if (opt_deprecationMessage) {
+        deprecationMap[symbolPath] = opt_deprecationMessage;
+    }
+}
+
+// Note: Android 2.3 does have Function.bind().
+exports.clobbers = function(moduleName, symbolPath, opt_deprecationMessage) {
+    addEntry('c', moduleName, symbolPath, opt_deprecationMessage);
+};
+
+exports.merges = function(moduleName, symbolPath, opt_deprecationMessage) {
+    addEntry('m', moduleName, symbolPath, opt_deprecationMessage);
+};
+
+exports.defaults = function(moduleName, symbolPath, opt_deprecationMessage) {
+    addEntry('d', moduleName, symbolPath, opt_deprecationMessage);
+};
+
+exports.runs = function(moduleName) {
+    addEntry('r', moduleName, null);
+};
+
+function prepareNamespace(symbolPath, context) {
+    if (!symbolPath) {
+        return context;
+    }
+    var parts = symbolPath.split('.');
+    var cur = context;
+    for (var i = 0, part; part = parts[i]; ++i) {
+        cur = cur[part] = cur[part] || {};
+    }
+    return cur;
+}
+
+exports.mapModules = function(context) {
+    var origSymbols = {};
+    context.CDV_origSymbols = origSymbols;
+    for (var i = 0, len = symbolList.length; i < len; i += 3) {
+        var strategy = symbolList[i];
+        var moduleName = symbolList[i + 1];
+        var module = require(moduleName);
+        // <runs/>
+        if (strategy == 'r') {
+            continue;
+        }
+        var symbolPath = symbolList[i + 2];
+        var lastDot = symbolPath.lastIndexOf('.');
+        var namespace = symbolPath.substr(0, lastDot);
+        var lastName = symbolPath.substr(lastDot + 1);
+
+        var deprecationMsg = symbolPath in deprecationMap ? 'Access made to deprecated symbol: ' + symbolPath + '. ' + deprecationMsg : null;
+        var parentObj = prepareNamespace(namespace, context);
+        var target = parentObj[lastName];
+
+        if (strategy == 'm' && target) {
+            builder.recursiveMerge(target, module);
+        } else if ((strategy == 'd' && !target) || (strategy != 'd')) {
+            if (!(symbolPath in origSymbols)) {
+                origSymbols[symbolPath] = target;
+            }
+            builder.assignOrWrapInDeprecateGetter(parentObj, lastName, module, deprecationMsg);
+        }
+    }
+};
+
+exports.getOriginalSymbol = function(context, symbolPath) {
+    var origSymbols = context.CDV_origSymbols;
+    if (origSymbols && (symbolPath in origSymbols)) {
+        return origSymbols[symbolPath];
+    }
+    var parts = symbolPath.split('.');
+    var obj = context;
+    for (var i = 0; i < parts.length; ++i) {
+        obj = obj && obj[parts[i]];
+    }
+    return obj;
+};
+
+exports.reset();
+
+
 });
 
 // file: /Users/steveng/repo/cordova/cordova-android/cordova-js-src/platform.js
 define("cordova/platform", function(require, exports, module) {
 
+// The last resume event that was received that had the result of a plugin call.
+var lastResumeEvent = null;
+
 module.exports = {
     id: 'android',
     bootstrap: function() {
@@ -1543,6 +1656,19 @@ module.exports = {
         bindButtonChannel('volumeup');
         bindButtonChannel('volumedown');
 
+        // The resume event is not "sticky", but it is possible that the event
+        // will contain the result of a plugin call. We need to ensure that the
+        // plugin result is delivered even after the event is fired (CB-10498)
+        var cordovaAddEventListener = document.addEventListener;
+
+        document.addEventListener = function(evt, handler, capture) {
+            cordovaAddEventListener(evt, handler, capture);
+
+            if (evt === 'resume' && lastResumeEvent) {
+                handler(lastResumeEvent);
+            }
+        };
+
         // Let native code know we are all done on the JS side.
         // Native code will then un-hide the WebView.
         channel.onCordovaReady.subscribe(function() {
@@ -1564,12 +1690,30 @@ function onMessageFromNative(msg) {
         case 'searchbutton':
         // App life cycle events
         case 'pause':
-        case 'resume':
         // Volume events
         case 'volumedownbutton':
         case 'volumeupbutton':
             cordova.fireDocumentEvent(action);
             break;
+        case 'resume':
+            if(arguments.length > 1 && msg.pendingResult) {
+                if(arguments.length === 2) {
+                    msg.pendingResult.result = arguments[1];
+                } else {
+                    // The plugin returned a multipart message
+                    var res = [];
+                    for(var i = 1; i < arguments.length; i++) {
+                        res.push(arguments[i]);
+                    }
+                    msg.pendingResult.result = res;
+                }
+
+                // Save the plugin result so that it can be delivered to the js
+                // even if they miss the initial firing of the event
+                lastResumeEvent = msg;
+            }
+            cordova.fireDocumentEvent(action, msg);
+            break;
         default:
             throw new Error('Unknown event action ' + action);
     }
@@ -1673,10 +1817,6 @@ module.exports = {
 // file: src/common/pluginloader.js
 define("cordova/pluginloader", function(require, exports, module) {
 
-/*
-    NOTE: this file is NOT used when we use the browserify workflow
-*/
-
 var modulemapper = require('cordova/modulemapper');
 var urlutil = require('cordova/urlutil');
 
@@ -1784,6 +1924,54 @@ exports.load = function(callback) {
 };
 
 
+});
+
+// file: src/common/pluginloader_b.js
+define("cordova/pluginloader_b", function(require, exports, module) {
+
+var modulemapper = require('cordova/modulemapper');
+
+// Handler for the cordova_plugins.js content.
+// See plugman's plugin_loader.js for the details of this object.
+function handlePluginsObject(moduleList) {
+    // if moduleList is not defined or empty, we've nothing to do
+    if (!moduleList || !moduleList.length) {
+        return;
+    }
+
+    // Loop through all the modules and then through their clobbers and merges.
+    for (var i = 0, module; module = moduleList[i]; i++) {
+        if (module.clobbers && module.clobbers.length) {
+            for (var j = 0; j < module.clobbers.length; j++) {
+                modulemapper.clobbers(module.id, module.clobbers[j]);
+            }
+        }
+
+        if (module.merges && module.merges.length) {
+            for (var k = 0; k < module.merges.length; k++) {
+                modulemapper.merges(module.id, module.merges[k]);
+            }
+        }
+
+        // Finally, if runs is truthy we want to simply require() the module.
+        if (module.runs) {
+            modulemapper.runs(module.id);
+        }
+    }
+}
+
+// Loads all plugins' js-modules. Plugin loading is syncronous in browserified bundle
+// but the method accepts callback to be compatible with non-browserify flow.
+// onDeviceReady is blocked on onPluginsReady. onPluginsReady is fired when there are
+// no plugins to load, or they are all done.
+exports.load = function(callback) {
+    var moduleList = require("cordova/plugin_list");
+    handlePluginsObject(moduleList);
+
+    callback();
+};
+
+
 });
 
 // file: src/common/urlutil.js

+ 207 - 6
miaomiao/platforms/android/build/intermediates/assets/debug/www/cordova_plugins.js

xqd xqd xqd
@@ -1,17 +1,208 @@
 cordova.define('cordova/plugin_list', function(require, exports, module) {
 module.exports = [
+    {
+        "file": "plugins/cordova-plugin-camera/www/CameraConstants.js",
+        "id": "cordova-plugin-camera.Camera",
+        "clobbers": [
+            "Camera"
+        ]
+    },
+    {
+        "file": "plugins/cordova-plugin-camera/www/CameraPopoverOptions.js",
+        "id": "cordova-plugin-camera.CameraPopoverOptions",
+        "clobbers": [
+            "CameraPopoverOptions"
+        ]
+    },
+    {
+        "file": "plugins/cordova-plugin-camera/www/Camera.js",
+        "id": "cordova-plugin-camera.camera",
+        "clobbers": [
+            "navigator.camera"
+        ]
+    },
+    {
+        "file": "plugins/cordova-plugin-camera/www/CameraPopoverHandle.js",
+        "id": "cordova-plugin-camera.CameraPopoverHandle",
+        "clobbers": [
+            "CameraPopoverHandle"
+        ]
+    },
     {
         "file": "plugins/cordova-plugin-device/www/device.js",
         "id": "cordova-plugin-device.device",
-        "pluginId": "cordova-plugin-device",
         "clobbers": [
             "device"
         ]
     },
+    {
+        "file": "plugins/cordova-plugin-file/www/DirectoryEntry.js",
+        "id": "cordova-plugin-file.DirectoryEntry",
+        "clobbers": [
+            "window.DirectoryEntry"
+        ]
+    },
+    {
+        "file": "plugins/cordova-plugin-file/www/DirectoryReader.js",
+        "id": "cordova-plugin-file.DirectoryReader",
+        "clobbers": [
+            "window.DirectoryReader"
+        ]
+    },
+    {
+        "file": "plugins/cordova-plugin-file/www/Entry.js",
+        "id": "cordova-plugin-file.Entry",
+        "clobbers": [
+            "window.Entry"
+        ]
+    },
+    {
+        "file": "plugins/cordova-plugin-file/www/File.js",
+        "id": "cordova-plugin-file.File",
+        "clobbers": [
+            "window.File"
+        ]
+    },
+    {
+        "file": "plugins/cordova-plugin-file/www/FileEntry.js",
+        "id": "cordova-plugin-file.FileEntry",
+        "clobbers": [
+            "window.FileEntry"
+        ]
+    },
+    {
+        "file": "plugins/cordova-plugin-file/www/FileError.js",
+        "id": "cordova-plugin-file.FileError",
+        "clobbers": [
+            "window.FileError"
+        ]
+    },
+    {
+        "file": "plugins/cordova-plugin-file/www/FileReader.js",
+        "id": "cordova-plugin-file.FileReader",
+        "clobbers": [
+            "window.FileReader"
+        ]
+    },
+    {
+        "file": "plugins/cordova-plugin-file/www/FileSystem.js",
+        "id": "cordova-plugin-file.FileSystem",
+        "clobbers": [
+            "window.FileSystem"
+        ]
+    },
+    {
+        "file": "plugins/cordova-plugin-file/www/FileUploadOptions.js",
+        "id": "cordova-plugin-file.FileUploadOptions",
+        "clobbers": [
+            "window.FileUploadOptions"
+        ]
+    },
+    {
+        "file": "plugins/cordova-plugin-file/www/FileUploadResult.js",
+        "id": "cordova-plugin-file.FileUploadResult",
+        "clobbers": [
+            "window.FileUploadResult"
+        ]
+    },
+    {
+        "file": "plugins/cordova-plugin-file/www/FileWriter.js",
+        "id": "cordova-plugin-file.FileWriter",
+        "clobbers": [
+            "window.FileWriter"
+        ]
+    },
+    {
+        "file": "plugins/cordova-plugin-file/www/Flags.js",
+        "id": "cordova-plugin-file.Flags",
+        "clobbers": [
+            "window.Flags"
+        ]
+    },
+    {
+        "file": "plugins/cordova-plugin-file/www/LocalFileSystem.js",
+        "id": "cordova-plugin-file.LocalFileSystem",
+        "clobbers": [
+            "window.LocalFileSystem"
+        ],
+        "merges": [
+            "window"
+        ]
+    },
+    {
+        "file": "plugins/cordova-plugin-file/www/Metadata.js",
+        "id": "cordova-plugin-file.Metadata",
+        "clobbers": [
+            "window.Metadata"
+        ]
+    },
+    {
+        "file": "plugins/cordova-plugin-file/www/ProgressEvent.js",
+        "id": "cordova-plugin-file.ProgressEvent",
+        "clobbers": [
+            "window.ProgressEvent"
+        ]
+    },
+    {
+        "file": "plugins/cordova-plugin-file/www/fileSystems.js",
+        "id": "cordova-plugin-file.fileSystems"
+    },
+    {
+        "file": "plugins/cordova-plugin-file/www/requestFileSystem.js",
+        "id": "cordova-plugin-file.requestFileSystem",
+        "clobbers": [
+            "window.requestFileSystem"
+        ]
+    },
+    {
+        "file": "plugins/cordova-plugin-file/www/resolveLocalFileSystemURI.js",
+        "id": "cordova-plugin-file.resolveLocalFileSystemURI",
+        "merges": [
+            "window"
+        ]
+    },
+    {
+        "file": "plugins/cordova-plugin-file/www/browser/isChrome.js",
+        "id": "cordova-plugin-file.isChrome",
+        "runs": true
+    },
+    {
+        "file": "plugins/cordova-plugin-file/www/android/FileSystem.js",
+        "id": "cordova-plugin-file.androidFileSystem",
+        "merges": [
+            "FileSystem"
+        ]
+    },
+    {
+        "file": "plugins/cordova-plugin-file/www/fileSystems-roots.js",
+        "id": "cordova-plugin-file.fileSystems-roots",
+        "runs": true
+    },
+    {
+        "file": "plugins/cordova-plugin-file/www/fileSystemPaths.js",
+        "id": "cordova-plugin-file.fileSystemPaths",
+        "merges": [
+            "cordova"
+        ],
+        "runs": true
+    },
+    {
+        "file": "plugins/cordova-plugin-file-transfer/www/FileTransferError.js",
+        "id": "cordova-plugin-file-transfer.FileTransferError",
+        "clobbers": [
+            "window.FileTransferError"
+        ]
+    },
+    {
+        "file": "plugins/cordova-plugin-file-transfer/www/FileTransfer.js",
+        "id": "cordova-plugin-file-transfer.FileTransfer",
+        "clobbers": [
+            "window.FileTransfer"
+        ]
+    },
     {
         "file": "plugins/cordova-plugin-splashscreen/www/splashscreen.js",
         "id": "cordova-plugin-splashscreen.SplashScreen",
-        "pluginId": "cordova-plugin-splashscreen",
         "clobbers": [
             "navigator.splashscreen"
         ]
@@ -19,7 +210,6 @@ module.exports = [
     {
         "file": "plugins/cordova-plugin-statusbar/www/statusbar.js",
         "id": "cordova-plugin-statusbar.statusbar",
-        "pluginId": "cordova-plugin-statusbar",
         "clobbers": [
             "window.StatusBar"
         ]
@@ -27,22 +217,33 @@ module.exports = [
     {
         "file": "plugins/ionic-plugin-keyboard/www/android/keyboard.js",
         "id": "ionic-plugin-keyboard.keyboard",
-        "pluginId": "ionic-plugin-keyboard",
         "clobbers": [
             "cordova.plugins.Keyboard"
         ],
         "runs": true
+    },
+    {
+        "file": "plugins/cordova-plugin-actionsheet/www/ActionSheet.js",
+        "id": "cordova-plugin-actionsheet.ActionSheet",
+        "clobbers": [
+            "window.plugins.actionsheet"
+        ]
     }
 ];
 module.exports.metadata = 
 // TOP OF METADATA
 {
+    "cordova-plugin-compat": "1.1.0",
+    "cordova-plugin-camera": "2.4.0",
     "cordova-plugin-console": "1.0.7",
     "cordova-plugin-device": "1.1.6",
+    "cordova-plugin-file": "4.3.3",
+    "cordova-plugin-file-transfer": "1.6.2",
     "cordova-plugin-splashscreen": "4.0.3",
     "cordova-plugin-statusbar": "2.1.3",
     "cordova-plugin-whitelist": "1.2.2",
-    "ionic-plugin-keyboard": "1.0.9"
-}
+    "ionic-plugin-keyboard": "1.0.9",
+    "cordova-plugin-actionsheet": "2.3.3"
+};
 // BOTTOM OF METADATA
 });

+ 7 - 3
miaomiao/platforms/android/build/intermediates/assets/debug/www/css/style.css

xqd xqd xqd
@@ -118,8 +118,8 @@ overflow:auto;
     border-bottom:5px solid #FBF2F5;
 }
 .subcontent img{
-    max-width:60px;
-    border-radius:30px;
+    max-width:17%;
+    border-radius:50%;
 }
     .subcontent i {
         font-size: 1.5rem;
@@ -133,6 +133,10 @@ overflow:auto;
         .subcontent i:last-child {
             right: 10px;
         }
+.item-image img, .item-image .list-img {
+    width: 100%;
+    vertical-align: middle;
+}
 .mainitem {
     padding:0;
 }
@@ -282,7 +286,7 @@ padding-right:3px;
         display: block;
         position: relative;
         background:#FE4B82; 
-        height: 20px; /* ¸ß¶È */
+        height: 20px; /* �߶� */
         line-height: 20px;
     }
 .reply-sx {

+ 1 - 1
miaomiao/platforms/android/build/intermediates/assets/debug/www/index.html

xqd
@@ -9,7 +9,7 @@
     <link href="css/style.css" rel="stylesheet">
     <script src="js/platformOverrides.js"></script>
     <script src="lib/ionic/js/ionic.bundle.min.js"></script>
- 
+
     <script src="cordova.js"></script>
     
     <script src="js/app.js"></script>

+ 21 - 7
miaomiao/platforms/android/build/intermediates/assets/debug/www/js/controllers/account.js

xqd xqd
@@ -1,26 +1,40 @@
 (function (app) {
-    app.controller('loginCtrl', function ($scope, userService, storage,$ionicHistory, $state, msg, $http) {
+    app.controller('loginCtrl', ["$scope", "userService", "storage", "$state", "msg", "$http", "util","$timeout",
+        function ($scope, userService, storage, $state, msg, $http, util, $timeout) {
         $scope.vm = {
             mobile: '',
             verify_code: '',
             waitSeconds: "获取验证码"
         };
         $scope.login = function () {
-            $state.go('app.home');
-            return;
             msg.loading('登录中...');
-            userService.login($scope.vm.mobile, $scope.vm.password).then(function (result) {
+            userService.login($scope.vm.mobile, $scope.vm.verify_code).then(function (result) {
                 msg.hide();
                 storage.setObject('user', result.data.data.user);
                 storage.set('token', result.data.data.token);
                 $http.defaults.headers.common["Authorization"] = 'Bearer ' + result.data.data.token;
-                $state.go('app.borrow');
+                $state.go('app.home');
             }, function (erro) {
-                console.log("login erro:"+JSON.stringify(erro));
                 msg.hide();
                 msg.error(erro.data.message);
             });
         }
+        //获取验证码
+        $scope.getVerifyCode = function () {
+            if (!util.isMobile($scope.vm.mobile)) {
+                msg.text('请输入正确的手机号');
+                return;
+            }
+            $scope.vm.waitSeconds = "正在发送";
+            userService.getVerifyCode($scope.vm.mobile).then(function (result) {
+                wait(50);
+                $scope.returncode = result.data;
+            }, function (error) {
+                $scope.vm.waitSeconds = "获取验证码";
+                wait(0);
+                msg.error(error.data.Message);
+            });
+        };
         var wait = function (seconds) {
             if (seconds > 0) {
                 $scope.vm.waitSeconds = "" + seconds + "秒";
@@ -32,6 +46,6 @@
                     wait(seconds - 1);
             }, 1000);
         };
-    });
+    }]);
   
 })(angular.module('app.controllers'));

+ 38 - 5
miaomiao/platforms/android/build/intermediates/assets/debug/www/js/controllers/my.js

xqd
@@ -1,16 +1,49 @@
 (function (app) {
-    app.controller('myCtrl', ["$scope", "$state", "storage", "myService", "msg"
-        , function ($scope, $state, storage, myService, msg) {
+    app.controller('myCtrl', ["$scope", "$state", "$http", "storage", "myService", "common", "config", "msg"
+        , function ($scope, $state, $http, storage, myService, common, config, msg) {
         $scope.$on('$ionicView.beforeEnter', function (viewResult) {
             
         });
+
+
+        $scope.testuploadFile = function(files) {       //单次提交图片的函数
+          console.log(files[0]);
+          var formData = new FormData();
+          formData.append('file', files[0]);
+          formData.append('tag', 'avatar');
+
+          $http({
+              method: 'POST',
+              url: config.server + 'api/attachment/upload',
+              transformRequest: angular.identity,
+              data: formData,
+              // headers: { 'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8' }
+              headers: {'Content-Type': undefined}
+          }).then(function (result) {
+              // alert(JSON.stringify(result));
+            console.log("attachment upload result:"+JSON.stringify(result));
+          }, function (erro) {
+            console.log("attachment upload erro:"+JSON.stringify(erro));
+              
+          })
+        }
         $scope.toprofile = function () {
             $state.go('app.my_profile');
         }
-        
         }]);
-    app.controller('profileCtrl', ["$scope", "$state", "storage", "myService", "msg"
-      , function ($scope, $state, storage, myService, msg) {
+    app.controller('profileCtrl', ["$scope", "$state", "storage", "myService", "msg", "common"
+      , function ($scope, $state, storage, myService, msg, common) {
+          $scope.setAvator = function () {
+              common.setAvator().then(function (result) {
+                  debugger;
+                  var response = JSON.parse(result.response);
+                  $timeout(function () {
+                      $scope.vm.user.avatar = response.data.md5;
+                  });
+              }, function (erro) {
+                  msg.erro(JSON.stringify(erro));
+              });
+          };
           $scope.$on('$ionicView.beforeEnter', function () {
 
           });

+ 4 - 30
miaomiao/platforms/android/build/intermediates/assets/debug/www/js/services/userservice.js

xqd
@@ -1,48 +1,22 @@
 (function (app) {
     app.factory('userService', ['$http', 'config', "util", 'storage', function ($http, config, util, storage) {
         return {
-            login:function (username,password) {
+            login: function (phone, verify_code) {
                 return $http({
                     url: config.server + 'api/auth/login',
                     method: "post",
-                    data: { phone: username, password: password, type:2 }
+                    data: { phone: phone, verify_code: verify_code}
                 })
             },
-            register: function (data) {
-                return $http({
-                    url: config.server + 'api/auth/register',
-                    method: "post",
-                    data: data
-                })
-            },
-           
             getVerifyCode:function (mobile) {
                 return $http({
                     url: config.server + 'api/auth/code',
                     method: "post",
-                    data: { phone: mobile, type:2}
-                })
-            },
-            getRegisterCode:function (mobile) {
-                return $http({
-                    url: config.server + 'api/auth/code',
-                    method: "post",
-                    data: { phone: mobile, type:3}
-                })
-            },
-            resetPassword: function (data) {
-                return $http({
-                    url: config.server + 'api/auth/reset',
-                    method: "post",
-                    data: data
+                    data: { phone: mobile}
                 })
             },
             isLogin: function () {
-                return $http({
-                    url: config.server + 'api/auth/is_login',
-                    method: "get",
-                })
-                // return !util.empty(storage.get("token")) && storage.getObject("user");
+             return !util.empty(storage.get("token")) && storage.getObject("user");
             } 
         };
     }]);

+ 2 - 1
miaomiao/platforms/android/build/intermediates/assets/debug/www/plugins/cordova-plugin-device/www/device.js

xqd
@@ -1,4 +1,5 @@
-cordova.define("cordova-plugin-device.device", function(require, exports, module) { /*
+cordova.define("cordova-plugin-device.device", function(require, exports, module) {
+/*
  *
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file

+ 2 - 1
miaomiao/platforms/android/build/intermediates/assets/debug/www/plugins/cordova-plugin-splashscreen/www/splashscreen.js

xqd
@@ -1,4 +1,5 @@
-cordova.define("cordova-plugin-splashscreen.SplashScreen", function(require, exports, module) { /*
+cordova.define("cordova-plugin-splashscreen.SplashScreen", function(require, exports, module) {
+/*
  *
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file

+ 2 - 1
miaomiao/platforms/android/build/intermediates/assets/debug/www/plugins/cordova-plugin-statusbar/www/statusbar.js

xqd
@@ -1,4 +1,5 @@
-cordova.define("cordova-plugin-statusbar.statusbar", function(require, exports, module) { /*
+cordova.define("cordova-plugin-statusbar.statusbar", function(require, exports, module) {
+/*
  *
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file

+ 2 - 1
miaomiao/platforms/android/build/intermediates/assets/debug/www/plugins/ionic-plugin-keyboard/www/android/keyboard.js

xqd
@@ -1,4 +1,5 @@
-cordova.define("ionic-plugin-keyboard.keyboard", function(require, exports, module) { 
+cordova.define("ionic-plugin-keyboard.keyboard", function(require, exports, module) {
+
 var argscheck = require('cordova/argscheck'),
     utils = require('cordova/utils'),
     exec = require('cordova/exec'),

+ 1 - 1
miaomiao/platforms/android/build/intermediates/assets/debug/www/templates/account/login.html

xqd
@@ -9,7 +9,7 @@
             </div>
             <div class="item item-input">
                 <input type="text" ng-model="vm.verify_code" placeholder="短信验证码">
-                <button ng-click="getRegisterCode()" class="button button-calm" style="margin-right:5px">{{vm.waitSeconds}}</button>
+                <button ng-click="getVerifyCode()" class="button button-calm" style="margin-right:5px">{{vm.waitSeconds}}</button>
             </div>
         </div>
         <div class="padding">

+ 10 - 7
miaomiao/platforms/android/build/intermediates/assets/debug/www/templates/add/index.html

xqd xqd
@@ -21,12 +21,16 @@
                 <i class="icon ion-plus"></i>
                 添加梦想介绍</a>
             </div>
-            <div class="item">上传一张照片,让别人更好的了解你</div>
+            <div class="item">上传图片和视频,让别人更好的了解你</div>
             <div class="item itemjs">
                 <a ng-repeat="item in files" ng-click="showImages(item)" class="img-file-up">
                     <b style="background-image:url({{item}});"><em ng-click="deletePicture(item)" class="ion-ios-close-outline"></em></b>
                 </a>
                 <a class="btn-file-up" ng-click="addfile()"><i class="ion-image"></i>添加图片</a>
+                <a ng-repeat="item in files" ng-click="showImages(item)" class="img-file-up">
+                    <b style="background-image:url({{item}});"><em ng-click="deletePicture(item)" class="ion-ios-close-outline"></em></b>
+                </a>
+                <a class="btn-file-up" ng-click="addfile()"><i class="icon ion-cash"></i>添加视频</a>
             </div>
             <div class="item">实现梦想所需要的人民币</div>
             <div class="item item-input-inset itemjs">
@@ -50,14 +54,13 @@
                 <button class="button button-clear" ng-click="closeModal()">确定</button>
             </ion-header-bar>
             <ion-content>
-                <div class="addmodal">
+                <div class="addmodal" style="border-bottom: 2px solid #EEEEEE">
                     <textarea placeholder="请输入梦想介绍"></textarea>
                 </div>
-                <div class="addfoot">
-                    <img ng-src="img/图片.png" />
-                    <img ng-src="img/相机.png" />
-                    <img ng-src="img/表情.png" />
-                </div>
+                <a ng-repeat="item in files" ng-click="showImages(item)" class="img-file-up">
+                    <b style="background-image:url({{item}});"><em ng-click="deletePicture(item)" class="ion-ios-close-outline"></em></b>
+                </a>
+                <a class="btn-file-up" ng-click="addfile()"><i class="ion-image"></i>添加图片</a>
             </ion-content>
         
         </ion-modal-view>

+ 4 - 4
miaomiao/platforms/android/build/intermediates/assets/debug/www/templates/home/index.html

xqd
@@ -33,16 +33,16 @@
                     <div class="box banner"><img ng-src="img/demo/banner3.jpg" /></div>  
                 </ion-slide-page>
             </ion-slides>
-            <div class="subcontent">
-                <i class="icon ion-ios-arrow-left"></i>
-                <span style="padding:15px">
+            <div class="item item-image" style="margin: 20px 0; border: none;">
+                <i class="icon ion-ios-arrow-left" style="font-size: 1.5rem;"></i>
+                <span class="subcontent">
                     <img ng-src="img/demo/head1.jpg" />
                     <img ng-src="img/demo/head2.jpg" />
                     <img ng-src="img/demo/head3.jpg" />
                     <img ng-src="img/demo/head4.jpg" />
                     <img ng-src="img/demo/head5.jpg" />
                 </span>
-                <i class="icon ion-ios-arrow-right"></i>
+                <i class="icon ion-ios-arrow-right" style="font-size: 1.5rem"></i>
             </div>
             <div class="list">
                 <div class="item mainitem" ng-click="todetail()">

+ 2 - 2
miaomiao/platforms/android/build/intermediates/assets/debug/www/templates/home/search.html

xqd
@@ -2,9 +2,9 @@
     <ion-nav-buttons side="primary">
         <label class="item item-input" style="width:315px">
             <i class="icon ion-search placeholder-icon"></i>
-            <input type="text" placeholder="搜索内容" ng-change="keychange()" ng-model="vm.keywords">
+            <input type="text" style="width: 100%" placeholder="搜索内容" ng-change="keychange()" ng-model="vm.keywords">
         </label>
-        <button class="button button-calm" style="padding-left:10px" ng-click="$ionicGoBack()">取消</button>
+        <button class="button button-calm" style="width: 30%; padding: 0;" ng-click="$ionicGoBack()">取消</button>
     </ion-nav-buttons>
      <ion-content>
          <div ng-if="vm.keywords.length==0&&ismore==false">

+ 2 - 1
miaomiao/platforms/android/build/intermediates/assets/debug/www/templates/my/index.html

xqd
@@ -1,7 +1,8 @@
 <ion-view view-title="我的"  hide-nav-bar="true">
     <ion-content>
         <div class="user-box">
-            <div class="myinfo">
+         
+            <div class="myinfo" ng-click="toprofile()">
                 <img ng-src="img/demo/head5.jpg" />
                 <div>
                     喵喵喵喵酱

+ 2 - 2
miaomiao/platforms/android/build/intermediates/assets/debug/www/templates/my/my-profile.html

xqd
@@ -1,8 +1,8 @@
 <ion-view view-title="个人信息" >
     <ion-content>
      <div class="list">
-         <a class="item item-avatar-right">
-             <img  src="../../img/demo/head5.jpg" />
+         <a class="item item-avatar-right" ng-click="setAvator()">
+             <img  src="img/demo/head5.jpg" />
              <h2>头像</h2>
              <p style="font-size:12px">点击上传</p>
          </a>

BIN
miaomiao/platforms/android/build/intermediates/classes/debug/com/ionicframework/ionictabs121641/BuildConfig.class


BIN
miaomiao/platforms/android/build/intermediates/classes/debug/com/ionicframework/ionictabs121641/R$xml.class


BIN
miaomiao/platforms/android/build/intermediates/classes/debug/org/apache/cordova/device/Device.class


BIN
miaomiao/platforms/android/build/intermediates/classes/debug/org/apache/cordova/splashscreen/SplashScreen.class


+ 25 - 4
miaomiao/platforms/android/build/intermediates/dex-cache/cache.xml

xqd
@@ -2,11 +2,32 @@
 <items version="2" >
 
     <item
-        jar="/Users/Mike/Vagrant/wwwroot/miaomiao/miaomiao/miaomiao/platforms/android/build/intermediates/exploded-aar/android/CordovaLib/unspecified/debug/classes.jar"
+        jar="D:\my\miao\miaomiao\platforms\android\build\intermediates\exploded-aar\com.android.support\support-v4\24.1.1\jars\classes.jar"
         jumboMode="false"
-        revision="24.0.2"
-        sha1="e78245843b9a81c3c6498d3a07ddfd56ca61b443">
-        <dex dex="/Users/Mike/Vagrant/wwwroot/miaomiao/miaomiao/miaomiao/platforms/android/build/intermediates/pre-dexed/debug/classes-b5048828b0dfe60f63719a1d6257ef873b6751a3.jar" />
+        revision="25.0.0"
+        sha1="6d7d803871e3203465f71a163e7af104f807b446">
+        <dex dex="D:\my\miao\miaomiao\platforms\android\build\intermediates\pre-dexed\debug\com.android.support-support-v4-24.1.1_7d1db190c305e812832b1dbce2b982d29103d99c.jar" />
+    </item>
+    <item
+        jar="D:\android\android-sdk\extras\android\m2repository\com\android\support\support-annotations\24.1.1\support-annotations-24.1.1.jar"
+        jumboMode="false"
+        revision="25.0.0"
+        sha1="3af19f153122737b372622fa6c81dd11a1c6b999">
+        <dex dex="D:\my\miao\miaomiao\platforms\android\build\intermediates\pre-dexed\debug\support-annotations-24.1.1_84795206824da57dba754676c9a5fa35beb3217c.jar" />
+    </item>
+    <item
+        jar="D:\my\miao\miaomiao\platforms\android\build\intermediates\exploded-aar\android\CordovaLib\unspecified\debug\jars\classes.jar"
+        jumboMode="false"
+        revision="25.0.0"
+        sha1="4b163cd7d2fcf09a32ba00e6ce127e65a25a0d48">
+        <dex dex="D:\my\miao\miaomiao\platforms\android\build\intermediates\pre-dexed\debug\CordovaLib-unspecified-debug_ee55b7e2b473552afdc736956997bc59f4ab4d6e.jar" />
+    </item>
+    <item
+        jar="D:\my\miao\miaomiao\platforms\android\build\intermediates\exploded-aar\com.android.support\support-v4\24.1.1\jars\libs\internal_impl-24.1.1.jar"
+        jumboMode="false"
+        revision="25.0.0"
+        sha1="f78c2f395cb096f9dc1dc07e729922b8fcd3c4f5">
+        <dex dex="D:\my\miao\miaomiao\platforms\android\build\intermediates\pre-dexed\debug\internal_impl-24.1.1_8864d75700e8351a78aaae43ad03090936937652.jar" />
     </item>
 
 </items>

BIN
miaomiao/platforms/android/build/intermediates/dex/debug/classes.dex


BIN
miaomiao/platforms/android/build/intermediates/exploded-aar/android/CordovaLib/unspecified/debug/classes.jar


BIN
miaomiao/platforms/android/build/intermediates/incremental/aidl/debug/dependency.store


File diff suppressed because it is too large
+ 0 - 1
miaomiao/platforms/android/build/intermediates/incremental/mergeAssets/debug/merger.xml


File diff suppressed because it is too large
+ 0 - 1
miaomiao/platforms/android/build/intermediates/incremental/mergeResources/debug/merger.xml


+ 13 - 4
miaomiao/platforms/android/build/intermediates/manifests/full/debug/AndroidManifest.xml

xqd xqd xqd xqd
@@ -7,7 +7,7 @@
 
     <uses-sdk
         android:minSdkVersion="16"
-        android:targetSdkVersion="22" />
+        android:targetSdkVersion="23" />
 
     <supports-screens
         android:anyDensity="true"
@@ -18,8 +18,7 @@
         android:xlargeScreens="true" />
 
     <uses-permission android:name="android.permission.INTERNET" />
-    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
-    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
 
     <application
         android:hardwareAccelerated="true"
@@ -31,7 +30,7 @@
             android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale"
             android:label="@string/activity_name"
             android:launchMode="singleTop"
-            android:theme="@android:style/Theme.Black.NoTitleBar"
+            android:theme="@android:style/Theme.DeviceDefault.NoActionBar"
             android:windowSoftInputMode="adjustResize" >
             <intent-filter android:label="@string/launcher_name" >
                 <action android:name="android.intent.action.MAIN" />
@@ -39,6 +38,16 @@
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
+
+        <provider
+            android:name="android.support.v4.content.FileProvider"
+            android:authorities="com.ionicframework.ionictabs121641.provider"
+            android:exported="false"
+            android:grantUriPermissions="true" >
+            <meta-data
+                android:name="android.support.FILE_PROVIDER_PATHS"
+                android:resource="@xml/provider_paths" />
+        </provider>
     </application>
 
 </manifest>

BIN
miaomiao/platforms/android/build/intermediates/pre-dexed/debug/classes-b5048828b0dfe60f63719a1d6257ef873b6751a3.jar


BIN
miaomiao/platforms/android/build/intermediates/res/debug/drawable-hdpi-v4/icon.png


BIN
miaomiao/platforms/android/build/intermediates/res/debug/drawable-land-hdpi-v4/screen.png


BIN
miaomiao/platforms/android/build/intermediates/res/debug/drawable-land-ldpi-v4/screen.png


BIN
miaomiao/platforms/android/build/intermediates/res/debug/drawable-land-mdpi-v4/screen.png


BIN
miaomiao/platforms/android/build/intermediates/res/debug/drawable-land-xhdpi-v4/screen.png


BIN
miaomiao/platforms/android/build/intermediates/res/debug/drawable-land-xxhdpi-v4/screen.png


BIN
miaomiao/platforms/android/build/intermediates/res/debug/drawable-land-xxxhdpi-v4/screen.png


BIN
miaomiao/platforms/android/build/intermediates/res/debug/drawable-ldpi-v4/icon.png


BIN
miaomiao/platforms/android/build/intermediates/res/debug/drawable-mdpi-v4/icon.png


BIN
miaomiao/platforms/android/build/intermediates/res/debug/drawable-port-hdpi-v4/screen.png


BIN
miaomiao/platforms/android/build/intermediates/res/debug/drawable-port-ldpi-v4/screen.png


BIN
miaomiao/platforms/android/build/intermediates/res/debug/drawable-port-mdpi-v4/screen.png


BIN
miaomiao/platforms/android/build/intermediates/res/debug/drawable-port-xhdpi-v4/screen.png


BIN
miaomiao/platforms/android/build/intermediates/res/debug/drawable-port-xxhdpi-v4/screen.png


BIN
miaomiao/platforms/android/build/intermediates/res/debug/drawable-port-xxxhdpi-v4/screen.png


BIN
miaomiao/platforms/android/build/intermediates/res/debug/drawable-xhdpi-v4/icon.png


BIN
miaomiao/platforms/android/build/intermediates/res/debug/drawable-xxhdpi-v4/icon.png


BIN
miaomiao/platforms/android/build/intermediates/res/debug/drawable-xxxhdpi-v4/icon.png


+ 0 - 8
miaomiao/platforms/android/build/intermediates/res/debug/values/values.xml

xqd
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <!-- From: file:/Users/Mike/Vagrant/wwwroot/miaomiao/miaomiao/miaomiao/platforms/android/res/values/strings.xml -->
-    <eat-comment/>
-    <string name="activity_name">@string/launcher_name</string>
-    <string name="app_name">喵喵</string>
-    <string name="launcher_name">@string/app_name</string>
-</resources>

+ 0 - 63
miaomiao/platforms/android/build/intermediates/res/debug/xml/config.xml

xqd
@@ -1,63 +0,0 @@
-<?xml version='1.0' encoding='utf-8'?>
-<widget id="com.ionicframework.ionictabs121641" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
-    <preference name="loglevel" value="DEBUG" />
-    <feature name="Device">
-        <param name="android-package" value="org.apache.cordova.device.Device" />
-    </feature>
-    <feature name="SplashScreen">
-        <param name="android-package" value="org.apache.cordova.splashscreen.SplashScreen" />
-        <param name="onload" value="true" />
-    </feature>
-    <feature name="StatusBar">
-        <param name="android-package" value="org.apache.cordova.statusbar.StatusBar" />
-        <param name="onload" value="true" />
-    </feature>
-    <feature name="Whitelist">
-        <param name="android-package" value="org.apache.cordova.whitelist.WhitelistPlugin" />
-        <param name="onload" value="true" />
-    </feature>
-    <feature name="Keyboard">
-        <param name="android-package" value="io.ionic.keyboard.IonicKeyboard" />
-        <param name="onload" value="true" />
-    </feature>
-    <icon density="ldpi" src="resources/android/icon/drawable-ldpi-icon.png" />
-    <icon density="mdpi" src="resources/android/icon/drawable-mdpi-icon.png" />
-    <icon density="hdpi" src="resources/android/icon/drawable-hdpi-icon.png" />
-    <icon density="xhdpi" src="resources/android/icon/drawable-xhdpi-icon.png" />
-    <icon density="xxhdpi" src="resources/android/icon/drawable-xxhdpi-icon.png" />
-    <icon density="xxxhdpi" src="resources/android/icon/drawable-xxxhdpi-icon.png" />
-    <splash density="land-ldpi" src="resources/android/splash/drawable-land-ldpi-screen.png" />
-    <splash density="land-mdpi" src="resources/android/splash/drawable-land-mdpi-screen.png" />
-    <splash density="land-hdpi" src="resources/android/splash/drawable-land-hdpi-screen.png" />
-    <splash density="land-xhdpi" src="resources/android/splash/drawable-land-xhdpi-screen.png" />
-    <splash density="land-xxhdpi" src="resources/android/splash/drawable-land-xxhdpi-screen.png" />
-    <splash density="land-xxxhdpi" src="resources/android/splash/drawable-land-xxxhdpi-screen.png" />
-    <splash density="port-ldpi" src="resources/android/splash/drawable-port-ldpi-screen.png" />
-    <splash density="port-mdpi" src="resources/android/splash/drawable-port-mdpi-screen.png" />
-    <splash density="port-hdpi" src="resources/android/splash/drawable-port-hdpi-screen.png" />
-    <splash density="port-xhdpi" src="resources/android/splash/drawable-port-xhdpi-screen.png" />
-    <splash density="port-xxhdpi" src="resources/android/splash/drawable-port-xxhdpi-screen.png" />
-    <splash density="port-xxxhdpi" src="resources/android/splash/drawable-port-xxxhdpi-screen.png" />
-    <name>喵喵</name>
-    <description>
-        An Ionic Framework and Cordova project.
-    </description>
-    <author email="you@example.com" href="http://example.com.com/">
-      Your Name Here
-    </author>
-    <content src="index.html" />
-    <access origin="*" />
-    <preference name="webviewbounce" value="false" />
-    <preference name="UIWebViewBounce" value="false" />
-    <preference name="DisallowOverscroll" value="true" />
-    <preference name="android-minSdkVersion" value="16" />
-    <preference name="BackupWebStorage" value="none" />
-    <preference name="KeepRunning" value="True" />
-    <preference name="ShowTitle" value="True" />
-    <preference name="InAppBrowserStorageEnabled" value="True" />
-    <preference name="SuppressesIncrementalRendering" value="True" />
-    <preference name="windows-target-version" value="10.0" />
-    <preference name="SplashScreen" value="screen" />
-    <preference name="SplashScreenDelay" value="3000" />
-</widget>
-<!-- From: file:/Users/Mike/Vagrant/wwwroot/miaomiao/miaomiao/miaomiao/platforms/android/res/xml/config.xml -->

BIN
miaomiao/platforms/android/build/intermediates/res/resources-debug.ap_


+ 1 - 0
miaomiao/platforms/android/build/intermediates/symbols/debug/R.txt

xqd
@@ -4,3 +4,4 @@ int string activity_name 0x7f040000
 int string app_name 0x7f040001
 int string launcher_name 0x7f040002
 int xml config 0x7f030000
+int xml provider_paths 0x7f030001

+ 0 - 2
miaomiao/platforms/android/build/intermediates/tmp/dex/debug/inputList.txt

xqd
@@ -1,2 +0,0 @@
-/Users/Mike/Vagrant/wwwroot/miaomiao/miaomiao/miaomiao/platforms/android/build/intermediates/classes/debug
-/Users/Mike/Vagrant/wwwroot/miaomiao/miaomiao/miaomiao/platforms/android/build/intermediates/pre-dexed/debug/classes-b5048828b0dfe60f63719a1d6257ef873b6751a3.jar

BIN
miaomiao/platforms/android/build/outputs/apk/android-debug-unaligned.apk


+ 0 - 84
miaomiao/platforms/android/build/outputs/apk/manifest-merger-debug-report.txt

xqd
@@ -1,84 +0,0 @@
--- Merging decision tree log ---
-manifest
-ADDED from AndroidManifest.xml:2:1
-	package
-		ADDED from AndroidManifest.xml:2:98
-	android:versionName
-		ADDED from AndroidManifest.xml:2:70
-	android:hardwareAccelerated
-		ADDED from AndroidManifest.xml:2:11
-	android:versionCode
-		ADDED from AndroidManifest.xml:2:46
-		INJECTED from AndroidManifest.xml:0:0
-		INJECTED from AndroidManifest.xml:0:0
-	xmlns:android
-		ADDED from AndroidManifest.xml:2:143
-supports-screens
-ADDED from AndroidManifest.xml:3:5
-	android:largeScreens
-		ADDED from AndroidManifest.xml:3:49
-	android:smallScreens
-		ADDED from AndroidManifest.xml:3:132
-	android:normalScreens
-		ADDED from AndroidManifest.xml:3:77
-	android:xlargeScreens
-		ADDED from AndroidManifest.xml:3:160
-	android:resizeable
-		ADDED from AndroidManifest.xml:3:106
-	android:anyDensity
-		ADDED from AndroidManifest.xml:3:23
-uses-permission#android.permission.INTERNET
-ADDED from AndroidManifest.xml:4:5
-	android:name
-		ADDED from AndroidManifest.xml:4:22
-uses-permission#android.permission.ACCESS_NETWORK_STATE
-ADDED from AndroidManifest.xml:5:5
-	android:name
-		ADDED from AndroidManifest.xml:5:22
-uses-permission#android.permission.ACCESS_WIFI_STATE
-ADDED from AndroidManifest.xml:6:5
-	android:name
-		ADDED from AndroidManifest.xml:6:22
-application
-ADDED from AndroidManifest.xml:7:5
-	android:label
-		ADDED from AndroidManifest.xml:7:83
-	android:supportsRtl
-		ADDED from AndroidManifest.xml:7:116
-	android:hardwareAccelerated
-		ADDED from AndroidManifest.xml:7:18
-	android:icon
-		ADDED from AndroidManifest.xml:7:53
-activity#com.ionicframework.ionictabs121641.MainActivity
-ADDED from AndroidManifest.xml:8:9
-	android:label
-		ADDED from AndroidManifest.xml:8:97
-	android:launchMode
-		ADDED from AndroidManifest.xml:8:135
-	android:windowSoftInputMode
-		ADDED from AndroidManifest.xml:8:248
-	android:configChanges
-		ADDED from AndroidManifest.xml:8:19
-	android:theme
-		ADDED from AndroidManifest.xml:8:194
-	android:name
-		ADDED from AndroidManifest.xml:8:166
-intent-filter#android.intent.action.MAIN+android.intent.category.LAUNCHER
-ADDED from AndroidManifest.xml:9:13
-	android:label
-		ADDED from AndroidManifest.xml:9:28
-action#android.intent.action.MAIN
-ADDED from AndroidManifest.xml:10:17
-	android:name
-		ADDED from AndroidManifest.xml:10:25
-category#android.intent.category.LAUNCHER
-ADDED from AndroidManifest.xml:11:17
-	android:name
-		ADDED from AndroidManifest.xml:11:27
-uses-sdk
-ADDED from AndroidManifest.xml:15:5
-MERGED from android:CordovaLib:unspecified:debug:25:5
-	android:targetSdkVersion
-		ADDED from AndroidManifest.xml:15:42
-	android:minSdkVersion
-		ADDED from AndroidManifest.xml:15:15

BIN
miaomiao/platforms/android/build/outputs/apk/喵喵.apk


+ 15 - 0
miaomiao/plugins/android.json

xqd xqd
@@ -7,12 +7,24 @@
         "files": {}
     },
     "installed_plugins": {
+        "cordova-plugin-camera": {
+            "PACKAGE_NAME": "com.ionicframework.ionictabs121641"
+        },
+        "cordova-plugin-compat": {
+            "PACKAGE_NAME": "com.ionicframework.ionictabs121641"
+        },
         "cordova-plugin-console": {
             "PACKAGE_NAME": "com.ionicframework.ionictabs121641"
         },
         "cordova-plugin-device": {
             "PACKAGE_NAME": "com.ionicframework.ionictabs121641"
         },
+        "cordova-plugin-file": {
+            "PACKAGE_NAME": "com.ionicframework.ionictabs121641"
+        },
+        "cordova-plugin-file-transfer": {
+            "PACKAGE_NAME": "com.ionicframework.ionictabs121641"
+        },
         "cordova-plugin-splashscreen": {
             "PACKAGE_NAME": "com.ionicframework.ionictabs121641"
         },
@@ -24,6 +36,9 @@
         },
         "ionic-plugin-keyboard": {
             "PACKAGE_NAME": "com.ionicframework.ionictabs121641"
+        },
+        "cordova-plugin-actionsheet": {
+            "PACKAGE_NAME": "com.ionicframework.ionictabs121641"
         }
     },
     "dependent_plugins": {}

+ 163 - 0
miaomiao/plugins/cordova-plugin-actionsheet/README.md

xqd
@@ -0,0 +1,163 @@
+# ActionSheet Cordova / PhoneGap Plugin
+by [Eddy Verbruggen](http://twitter.com/eddyverbruggen)
+
+## 0. Index
+
+1. [Description](#1-description)
+2. [Screenshots](#2-screenshots)
+3. [Installation](#3-installation)
+4. [Usage](#4-usage)
+5. [Credits](#5-credits)
+6. [License](#6-license)
+
+## 1. Description
+
+Show a sheet of options the user can choose from.
+
+* Compatible with [Cordova Plugman](https://github.com/apache/cordova-plugman)
+* iOS uses the native `UIActionSheet`
+* Android uses the native `AlertDialog`
+* WP8 uses the native `Popup`
+
+## 2. Screenshots
+
+iOS
+
+<img src="screenshots/ios/ios-share.png" width="235"/>&nbsp;
+<img src="screenshots/ios/ios-delete.png" width="235"/>&nbsp;
+<img src="screenshots/ios/ios-logout.png" width="235"/>
+
+
+Android
+
+<img src="screenshots/android/android-share.png" width="235"/>&nbsp;
+<img src="screenshots/android/android-delete.png" width="235"/>&nbsp;
+<img src="screenshots/android/android-logout.png" width="235"/>
+
+Windows Phone 8
+
+<img src="screenshots/wp8/wp8-share.jpg" width="235"/>&nbsp;
+<img src="screenshots/wp8/wp8-delete.jpg" width="235"/>&nbsp;
+<img src="screenshots/wp8/wp8-logout.jpg" width="235"/>
+
+## 3. Installation
+
+### Automatically (CLI / Plugman)
+```
+$ cordova plugin add cordova-plugin-actionsheet
+$ cordova prepare
+```
+
+ActionSheet.js is brought in automatically. There is no need to change or add anything in your html.
+
+### PhoneGap Build
+ActionSheet  works with PhoneGap build too! Just add the following xml to your `config.xml` to always use the latest version of this plugin:
+```xml
+<plugin name="cordova-plugin-actionsheet" />
+```
+
+ActionSheet.js is brought in automatically. Make sure though you include a reference to cordova.js in your index.html's head:
+```html
+<script type="text/javascript" src="cordova.js"></script>
+```
+
+## 4. Usage
+
+### show
+
+Check the [demo code](demo) to get you going quickly,
+or copy-paste some of the code below to replicate the ActionSheets of the screenshots above.
+
+Also, wait for `deviceready` to fire before using plugins in general!
+
+```js
+  var callback = function(buttonIndex) {
+    setTimeout(function() {
+      // like other Cordova plugins (prompt, confirm) the buttonIndex is 1-based (first button is index 1)
+      alert('button index clicked: ' + buttonIndex);
+    });
+  };
+
+  function testShareSheet() {
+    var options = {
+        androidTheme: window.plugins.actionsheet.ANDROID_THEMES.THEME_DEVICE_DEFAULT_LIGHT, // default is THEME_TRADITIONAL
+        title: 'What do you want with this image?',
+        subtitle: 'Choose wisely, my friend', // supported on iOS only
+        buttonLabels: ['Share via Facebook', 'Share via Twitter'],
+        androidEnableCancelButton : true, // default false
+        winphoneEnableCancelButton : true, // default false
+        addCancelButtonWithLabel: 'Cancel',
+        addDestructiveButtonWithLabel : 'Delete it',
+        position: [20, 40], // for iPad pass in the [x, y] position of the popover
+        destructiveButtonLast: true // you can choose where the destructive button is shown
+    };
+    // Depending on the buttonIndex, you can now call shareViaFacebook or shareViaTwitter
+    // of the SocialSharing plugin (https://github.com/EddyVerbruggen/SocialSharing-PhoneGap-Plugin)
+    window.plugins.actionsheet.show(options, callback);
+  };
+
+  function testDeleteSheet() {
+    var options = {
+        'addCancelButtonWithLabel': 'Cancel',
+        'addDestructiveButtonWithLabel' : 'Delete note'
+    };
+    window.plugins.actionsheet.show(options, callback);
+  };
+
+  function testLogoutSheet() {
+    var options = {
+        'buttonLabels': ['Log out'],
+        'androidEnableCancelButton' : true, // default false
+        'winphoneEnableCancelButton' : true, // default false
+        'addCancelButtonWithLabel': 'Cancel'
+    };
+    window.plugins.actionsheet.show(options, callback);
+  };
+```
+
+On iOS, you can also position the actionSheet origin by adding `position: [100, 200]`
+
+### hide
+
+If for some reason you want to hide the actionsheet programmatically, do this:
+```js
+  // options and callbacks are optional, so either approach will work:
+  window.plugins.actionsheet.hide();
+  window.plugins.actionsheet.hide({}, onSuccess, onError);
+```
+
+## 5. Credits
+iOS and WP8 code: [Eddy Verbruggen](https://github.com/EddyVerbruggen)
+
+Android code: mostly [Brill Papping](https://github.com/bpappin)
+
+
+## 6. Change history
+* 2.3.3 Default iPad popup is now in the center (was in the top left corner)
+* 2.3.1 Added `subtitle` (iOS) and `destructiveButtonLast` preferences. Also, iOS now uses the newer `UIAlertController` instead of `UIActionSheet`.
+* 2.2.2 OK, 2.2.1 has issues with Russian and the like, so reverted. Just add `<meta charset="utf-8" />` to your html file.
+* 2.2.1 Encoding of diacritical characters fixed on iOS, so you can now use `Español` as a title or button label.
+* 1.1.6 You can now set the iOS actionSheet origin position (uses the iOS `actionSheet.showFromRect` method)
+* 1.1.2 You can now select a theme for your Android popup, see the first example above
+
+## 7. License
+
+[The MIT License (MIT)](http://www.opensource.org/licenses/mit-license.html)
+
+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.

+ 43 - 0
miaomiao/plugins/cordova-plugin-actionsheet/package.json

xqd
@@ -0,0 +1,43 @@
+{
+  "name": "cordova-plugin-actionsheet",
+  "version": "2.3.3",
+  "description": "Show a sheet of options the user can choose from.",
+  "cordova": {
+    "id": "cordova-plugin-actionsheet",
+    "platforms": [
+      "ios",
+      "android",
+      "wp8"
+    ]
+  },
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/EddyVerbruggen/cordova-plugin-actionsheet.git"
+  },
+  "keywords": [
+    "ActionSheet",
+    "UIActionSheet",
+    "AlertDialog",
+    "Dialog",
+    "List",
+    "Picker",
+    "Popup",
+    "cordova",
+    "ecosystem:cordova",
+    "cordova-ios",
+    "cordova-android",
+    "cordova-wp8"
+  ],
+  "engines": [
+    {
+      "name": "cordova",
+      "version": ">=3.0.0"
+    }
+  ],
+  "author": "Eddy Verbruggen - @EddyVerbruggen",
+  "license": "MIT",
+  "bugs": {
+    "url": "https://github.com/EddyVerbruggen/cordova-plugin-actionsheet/issues"
+  },
+  "homepage": "https://github.com/EddyVerbruggen/cordova-plugin-actionsheet#readme"
+}

+ 76 - 0
miaomiao/plugins/cordova-plugin-actionsheet/plugin.xml

xqd
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<plugin
+    xmlns="http://apache.org/cordova/ns/plugins/1.0"
+    id="cordova-plugin-actionsheet"
+    version="2.3.3">
+
+  <name>ActionSheet</name>
+
+  <description>Show a sheet of options the user can choose from.</description>
+
+  <author>Eddy Verbruggen</author>
+
+  <license>MIT</license>
+
+  <keywords>ActionSheet, UIActionSheet, AlertDialog, Dialog, List, Picker, Popup</keywords>
+
+  <repo>https://github.com/EddyVerbruggen/cordova-plugin-actionsheet.git</repo>
+
+  <issue>https://github.com/EddyVerbruggen/cordova-plugin-actionsheet/issues</issue>
+
+  <engines>
+    <engine name="cordova" version=">=3.0.0"/>
+  </engines>
+
+  <js-module src="www/ActionSheet.js" name="ActionSheet">
+    <clobbers target="window.plugins.actionsheet"/>
+  </js-module>
+
+
+
+  <!-- ios -->
+  <platform name="ios">
+    <config-file target="config.xml" parent="/*">
+      <feature name="ActionSheet">
+        <param name="ios-package" value="ActionSheet"/>
+      </feature>
+    </config-file>
+    <header-file src="src/ios/ActionSheet.h"/>
+    <source-file src="src/ios/ActionSheet.m"/>
+  </platform>
+
+  <!-- android -->
+  <platform name="android">
+    <config-file target="res/xml/config.xml" parent="/*">
+      <feature name="ActionSheet">
+        <param name="android-package" value="nl.xservices.plugins.actionsheet.ActionSheet"/>
+      </feature>
+    </config-file>
+    <source-file src="src/android/ActionSheet.java" target-dir="src/nl/xservices/plugins/actionsheet"/>
+  </platform>
+
+  <!-- wp8 -->
+  <platform name="wp8">
+    <config-file target="config.xml" parent="/*">
+      <feature name="ActionSheet">
+        <param name="wp-package" value="ActionSheet"/>
+      </feature>
+    </config-file>
+    <source-file src="src/wp8/ActionSheet.cs" />
+  </platform>
+
+  <!--windows-->
+  <platform name="windows">
+    <js-module src="src/windows/ActionSheetProxy.js" name="ActionSheetProxy">
+      <merges target="" />
+    </js-module>
+  </platform>
+
+  <!--browser-->
+  <platform name="browser">
+    <js-module src="src/browser/ActionSheetProxy.js" name="ActionSheetProxy">
+      <merges target="" />
+    </js-module>
+  </platform>
+
+</plugin>

+ 196 - 0
miaomiao/plugins/cordova-plugin-actionsheet/src/android/ActionSheet.java

xqd
@@ -0,0 +1,196 @@
+package nl.xservices.plugins.actionsheet;
+
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
+import android.os.Build;
+import android.text.TextUtils;
+import org.apache.cordova.CallbackContext;
+import org.apache.cordova.CordovaInterface;
+import org.apache.cordova.CordovaPlugin;
+import org.apache.cordova.PluginResult;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Original excellent PR by: Brill Pappin
+ * @author Mantainer of the code: Eddy Verbruggen
+ */
+public class ActionSheet extends CordovaPlugin {
+
+  private AlertDialog dialog;
+
+  public ActionSheet() {
+    super();
+  }
+
+  private static final String ACTION_SHOW = "show";
+  private static final String ACTION_HIDE = "hide";
+
+  public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
+
+    if (ACTION_SHOW.equals(action)) {
+      JSONObject options = args.optJSONObject(0);
+
+      String title = options.optString("title");
+      String subtitle = options.optString("subtitle");
+      int theme = options.optInt("androidTheme", 1);
+      JSONArray buttons = options.optJSONArray("buttonLabels");
+
+      boolean androidEnableCancelButton = options.optBoolean("androidEnableCancelButton", false);
+      boolean destructiveButtonLast = options.optBoolean("destructiveButtonLast", false);
+
+      String addCancelButtonWithLabel = options.optString("addCancelButtonWithLabel");
+      String addDestructiveButtonWithLabel = options.optString("addDestructiveButtonWithLabel");
+
+      this.show(title, subtitle, buttons, addCancelButtonWithLabel, androidEnableCancelButton,
+          addDestructiveButtonWithLabel, destructiveButtonLast,
+          theme, callbackContext);
+      // need to return as this call is async.
+      return true;
+
+    } else if (ACTION_HIDE.equals(action)) {
+      if (dialog != null && dialog.isShowing()) {
+        dialog.dismiss();
+        callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, -1));
+      }
+      return true;
+    }
+
+    return false;
+  }
+
+  public synchronized void show(final String title,
+                                final String subtitle,
+                                final JSONArray buttonLabels,
+                                final String addCancelButtonWithLabel,
+                                final boolean androidEnableCancelButton,
+                                final String addDestructiveButtonWithLabel,
+                                final boolean destructiveButtonLast,
+                                final int theme,
+                                final CallbackContext callbackContext) {
+
+    final CordovaInterface cordova = this.cordova;
+
+    Runnable runnable = new Runnable() {
+      public void run() {
+
+        final AlertDialog.Builder builder;
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
+          builder = new AlertDialog.Builder(cordova.getActivity(), theme);
+        } else {
+          builder = new AlertDialog.Builder(cordova.getActivity());
+        }
+
+        builder
+            .setTitle(title)
+            .setCancelable(true);
+
+
+        // Although there is not really anything technically wrong
+        // with adding a cancel button, Android typically doesn't use
+        // one for this kind of list dialog.
+        // We'll allow the user to override the "smart" option and
+        // include it if they insist anyway.
+
+        if (androidEnableCancelButton && !TextUtils.isEmpty(addCancelButtonWithLabel)) {
+          builder.setNegativeButton(addCancelButtonWithLabel,
+              new OnClickListener() {
+                @Override
+                public void onClick(DialogInterface dialog, int which) {
+                  dialog.cancel();
+                  // We catch the cancel event and return
+                  // the index then.
+                }
+              });
+        }
+
+        // So what do we do with the iOS destructive button?
+        // Android doesn't really have the concept, so we're going to
+        // ignore it until we have a situation where we can come up with
+        // a good way to implement it. Most likely adding an image
+        // or some other indicator.
+//        if (!TextUtils.isEmpty(addDestructiveButtonWithLabel)) {
+//          builder.setPositiveButton(addDestructiveButtonWithLabel,
+//              new OnClickListener() {
+//                @Override
+//                public void onClick(DialogInterface dialog, int which) {
+//                  dialog.dismiss();
+//                  callbackContext
+//                      .sendPluginResult(new PluginResult(
+//                          PluginResult.Status.OK, 0));
+//                }
+//              });
+//        }
+
+        final String[] buttons = getStringArray(
+            buttonLabels,
+            destructiveButtonLast,
+            (TextUtils.isEmpty(addDestructiveButtonWithLabel) ? null
+                : addDestructiveButtonWithLabel));
+
+        builder.setItems(buttons, new OnClickListener() {
+          @Override
+          public void onClick(DialogInterface dialog, int which) {
+            // java 0 based index converted to cordova 1 based
+            // index, so we don't confuse the webbies.
+            callbackContext.sendPluginResult(new PluginResult(
+                PluginResult.Status.OK, which + 1));
+          }
+        });
+
+        builder.setOnCancelListener(new AlertDialog.OnCancelListener() {
+          public void onCancel(DialogInterface dialog) {
+            // Match the way the iOS plugin works. Cancel is
+            // always the last index and destructive is always the
+            // first, if it exists. Even though we don't handle the
+            // destructive button, we want the selected index to
+            // match.
+            int cancelButtonIndex = buttons.length + 1;
+            callbackContext.sendPluginResult(new PluginResult(
+                PluginResult.Status.OK, cancelButtonIndex));
+          }
+        });
+
+        dialog = builder.create();
+        dialog.show();
+      }
+    };
+    this.cordova.getActivity().runOnUiThread(runnable);
+  }
+
+  private String[] getStringArray(JSONArray jsonArray, boolean append, String... additionalButtons) {
+
+    List<String> btns = new ArrayList<String>();
+
+    // Add prefix items
+    if (!append) {
+      for (String btn : additionalButtons) {
+        if (!TextUtils.isEmpty(btn)) {
+          btns.add(btn);
+        }
+      }
+    }
+
+    // add the rest of the buttons from the list.
+    if (jsonArray != null) {
+      for (int i = 0; i < jsonArray.length(); i++) {
+        btns.add(jsonArray.optString(i));
+      }
+    }
+
+    // Add postfix items
+    if (append) {
+      for (String btn : additionalButtons) {
+        if (!TextUtils.isEmpty(btn)) {
+          btns.add(btn);
+        }
+      }
+    }
+    return btns.toArray(new String[btns.size()]);
+  }
+}

+ 132 - 0
miaomiao/plugins/cordova-plugin-actionsheet/src/browser/ActionSheetProxy.js

xqd
@@ -0,0 +1,132 @@
+function ActionSheet() {
+}
+
+ActionSheet.prototype.show = function (options, successCallback, errorCallback) {
+
+    if (successCallback) {
+        ActionSheet.prototype.successCallBack = successCallback;
+    }
+
+    var actionSheetContainer = document.getElementById('actionSheetProxyContainer');
+    if (!actionSheetContainer) {
+        var body = document.getElementsByTagName('body')[0];
+        actionSheetContainer = document.createElement('div');
+        actionSheetContainer.setAttribute('class', 'action-sheet-container');
+        actionSheetContainer.setAttribute('id', 'actionSheetProxyContainer');
+        body.appendChild(actionSheetContainer);
+    }
+
+    if (actionSheetContainer.hidden) {
+        actionSheetContainer.hidden = false;
+    }
+
+    if (options) {
+        this._clearChildren(actionSheetContainer);
+
+        if (options.title) {
+            this._addTitle(options.title, actionSheetContainer);
+        }
+
+        if (!options.destructiveButtonLast && options.addDestructiveButtonWithLabel) {
+            this._addDestructiveButton(options.addDestructiveButtonWithLabel, actionSheetContainer, 1);
+            ActionSheet.prototype._btnOffsetIndex = 2;
+        } else {
+            ActionSheet.prototype._btnOffsetIndex = 1;
+        }
+
+        if (options.buttonLabels) {
+            this._addbuttons(options.buttonLabels, actionSheetContainer);
+        }
+
+        if (options.destructiveButtonLast && options.addDestructiveButtonWithLabel) {    //Generate Desctructive Button
+            this._addDestructiveButton(options.addDestructiveButtonWithLabel, actionSheetContainer, options.buttonLabels.length + 1);
+        }
+
+        if (options.addCancelButtonWithLabel) {
+            this._addCancelButton(options.addCancelButtonWithLabel, actionSheetContainer);
+        }
+
+    }
+};
+
+ActionSheet.prototype.hide = function (options, successCallback, errorCallback) {
+    var actionSheetContainer = document.getElementById('actionSheetProxyContainer');
+    actionSheetContainer.hidden = true;
+};
+
+ActionSheet.prototype.install = function () {
+    if (!window.plugins) {
+        window.plugins = {};
+    }
+    window.plugins.actionsheet = new ActionSheet();
+
+    return window.plugins.actionsheet;
+};
+
+cordova.addConstructor(ActionSheet.prototype.install);
+cordova.commandProxy.add('ActionSheet', ActionSheet);
+
+//Helpers
+ActionSheet.prototype._addTitle = function (label, destination) {
+    var title = document.createElement('h3');
+    title.setAttribute('class', 'action-sheet-title');
+    title.innerHTML = label;
+    destination.appendChild(title);
+};
+
+
+ActionSheet.prototype._addDestructiveButton = function (label, destination, position) {
+    var btn = document.createElement('button');
+    btn.setAttribute('value', position);
+    btn.setAttribute('class', 'action-sheet-button action-sheet-destructive-button');
+    btn.innerHTML = label;
+    btn.onclick = ActionSheet.prototype._onclick;
+    destination.appendChild(btn);
+};
+
+ActionSheet.prototype._addCancelButton = function (label, destination) {
+    var btn = document.createElement('button');
+    btn.setAttribute('class', 'action-sheet-button action-sheet-cancel-button');
+    btn.innerHTML = label;
+    btn.onclick = function () {
+        ActionSheet.prototype.hide();
+    };
+    destination.appendChild(btn);
+};
+
+ActionSheet.prototype._addbuttons = function (labels, destination) {
+    for (var i = 0; i < labels.length; i++) {
+        var btn = document.createElement('button');
+        btn.setAttribute('value', i + ActionSheet.prototype._btnOffsetIndex);
+        btn.setAttribute('class', 'action-sheet-button action-sheet-normal-button');
+        btn.innerHTML = labels[i];
+        btn.onclick = ActionSheet.prototype._onclick;
+        destination.appendChild(btn);
+    }
+};
+
+ActionSheet.prototype._onclick = function (ev) {
+    ev.preventDefault();
+    ev.stopPropagation();
+    ActionSheet.prototype.hide();
+    if (ActionSheet.prototype.successCallBack) {
+        ActionSheet.prototype.successCallBack(parseInt(ev.target.value, 10));
+    }
+};
+
+ActionSheet.prototype._clearChildren = function (element) {
+    if (element && element.hasChildNodes) {
+        while (element.hasChildNodes()) {
+            element.removeChild(element.lastChild);
+        }
+    }
+};
+
+ActionSheet.prototype.ANDROID_THEMES = {
+    THEME_TRADITIONAL: 1, // default
+    THEME_HOLO_DARK: 2,
+    THEME_HOLO_LIGHT: 3,
+    THEME_DEVICE_DEFAULT_DARK: 4,
+    THEME_DEVICE_DEFAULT_LIGHT: 5
+};
+

+ 13 - 0
miaomiao/plugins/cordova-plugin-actionsheet/src/ios/ActionSheet.h

xqd
@@ -0,0 +1,13 @@
+#import <Cordova/CDVPlugin.h>
+
+@interface ActionSheet :CDVPlugin<UIActionSheetDelegate>
+
+@property (nonatomic, copy) NSString *callbackId;
+// TODO remove one day, as it's deprecated since iOS 8
+@property (nonatomic, retain) UIActionSheet *actionSheet;
+@property (nonatomic, retain) UIAlertController *alertController;
+
+- (void) show:(CDVInvokedUrlCommand*)command;
+- (void) hide:(CDVInvokedUrlCommand*)command;
+
+@end

+ 186 - 0
miaomiao/plugins/cordova-plugin-actionsheet/src/ios/ActionSheet.m

xqd
@@ -0,0 +1,186 @@
+#import "ActionSheet.h"
+
+@implementation ActionSheet
+
+#pragma mark - Cordova interface methods
+
+- (void)show:(CDVInvokedUrlCommand *)command
+{
+  self.callbackId = command.callbackId;
+  NSDictionary *options = command.arguments[0];
+
+  NSString *title = options[@"title"] ?: nil;
+  NSString *subtitle = options[@"subtitle"] ?: nil;
+  NSArray *buttons = options[@"buttonLabels"];
+  NSArray *position = options[@"position"] ?: nil;
+  NSString *addCancelButtonWithLabel = options[@"addCancelButtonWithLabel"] ?: nil;
+  NSString *addDestructiveButtonWithLabel = options[@"addDestructiveButtonWithLabel"] ?: nil;
+  BOOL destructiveButtonLast = [options[@"destructiveButtonLast"] isEqual:@YES];
+
+  [self.commandDelegate runInBackground:^{
+
+      if ([UIAlertController class]) {
+
+        self.alertController = [UIAlertController alertControllerWithTitle:[self encodeString:title]
+                                                                   message:[self encodeString:subtitle]
+                                                            preferredStyle:UIAlertControllerStyleActionSheet];
+
+        if (addDestructiveButtonWithLabel != nil && !destructiveButtonLast) {
+          [self addDestructiveButton:addDestructiveButtonWithLabel toAlertController:self.alertController asLastItem:destructiveButtonLast relativeToButtons:buttons];
+        }
+
+        for (NSUInteger i = 0; i < [buttons count]; i++) {
+          UIAlertAction *action = [UIAlertAction actionWithTitle:[self encodeString:buttons[i]]
+                                                           style:UIAlertActionStyleDefault
+                                                         handler:^(UIAlertAction *handledAction) {
+                                                             int buttonIndex;
+                                                             for (NSUInteger j = 0; j < [buttons count]; j++) {
+                                                               if ([handledAction.title isEqualToString:buttons[j]]) {
+                                                                 buttonIndex = j + 1;
+                                                                 if (addDestructiveButtonWithLabel != nil && !destructiveButtonLast) {
+                                                                   buttonIndex++;
+                                                                 }
+                                                                 [self respondWithButtonIndex:buttonIndex];
+                                                                 break;
+                                                               }
+                                                             }
+                                                         }];
+          [self.alertController addAction:action];
+        }
+
+        if (addDestructiveButtonWithLabel != nil && destructiveButtonLast) {
+          [self addDestructiveButton:addDestructiveButtonWithLabel toAlertController:self.alertController asLastItem:destructiveButtonLast relativeToButtons:buttons];
+        }
+
+        if (addCancelButtonWithLabel != nil) {
+          UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:addCancelButtonWithLabel
+                                                                 style:UIAlertActionStyleCancel
+                                                               handler:^(UIAlertAction *action) {
+                                                                   [self respondWithButtonIndex:(int) buttons.count + (addDestructiveButtonWithLabel == nil ? 1 : 2)];
+                                                               }];
+          [self.alertController addAction:cancelAction];
+        }
+
+        dispatch_async(dispatch_get_main_queue(), ^{
+            if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
+              [self.alertController setModalPresentationStyle:UIModalPresentationPopover];
+              UIPopoverPresentationController *popPresenter = [self.alertController popoverPresentationController];
+              popPresenter.sourceView = self.webView.superview;
+              if (position == nil) {
+                NSLog(@"Because the 'postion' param is not set, on iPad the popup is shown in the center.");
+                [popPresenter setPermittedArrowDirections:0];
+                popPresenter.sourceView = self.webView.superview;
+                popPresenter.sourceRect = CGRectMake(CGRectGetMidX(self.webView.bounds), CGRectGetMidY(self.webView.bounds), 0, 0);
+              } else {
+                popPresenter.sourceRect = [self getPopupRectFromIPadPopupCoordinates:position];
+              }
+            }
+            [self.viewController presentViewController:self.alertController animated:YES completion:nil];
+        });
+
+      } else {
+
+        self.actionSheet = [[UIActionSheet alloc] initWithTitle:[self encodeString:title]
+                                                       delegate:self
+                                              cancelButtonTitle:nil
+                                         destructiveButtonTitle:[self encodeString:addDestructiveButtonWithLabel]
+                                              otherButtonTitles:nil];
+
+        for (NSUInteger i = 0; i < [buttons count]; i++) {
+          [self.actionSheet addButtonWithTitle:[self encodeString:buttons[i]]];
+        }
+
+        if (addCancelButtonWithLabel != nil) {
+          [self.actionSheet addButtonWithTitle:[self encodeString:addCancelButtonWithLabel]];
+          self.actionSheet.cancelButtonIndex = [buttons count] + (addDestructiveButtonWithLabel == nil ? 0 : 1);
+        }
+
+        dispatch_async(dispatch_get_main_queue(), ^{
+            if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
+              if (position != nil) {
+                CGRect rect = [self getPopupRectFromIPadPopupCoordinates:position];
+                [self.actionSheet showFromRect:rect inView:self.webView.superview animated:YES];
+              } else {
+                [self.actionSheet showInView:self.webView.superview];
+              }
+            } else {
+              // In this case the device is an iPhone/iPod Touch.
+              [self.actionSheet showInView:self.webView.superview];
+            }
+        });
+      }
+  }];
+}
+
+- (void)addDestructiveButton:(NSString *)title toAlertController:(UIAlertController *)alertController asLastItem:(BOOL)isLast relativeToButtons:(NSArray *)buttons
+{
+
+  [alertController addAction:[UIAlertAction actionWithTitle:title
+                                                      style:UIAlertActionStyleDestructive
+                                                    handler:^(UIAlertAction *action) {
+                                                        if (isLast) {
+                                                          [self respondWithButtonIndex:1 + (int) buttons.count];
+                                                        } else {
+                                                          [self respondWithButtonIndex:1];
+                                                        }
+                                                    }]];
+}
+
+- (void)respondWithButtonIndex:(int)index
+{
+  CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
+                                                       messageAsInt:index];
+  [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId];
+}
+
+- (void)hide:(CDVInvokedUrlCommand *)command
+{
+  dispatch_async(dispatch_get_main_queue(), ^{
+      if ([UIAlertController class]) {
+        [self.alertController dismissViewControllerAnimated:YES completion:nil];
+        [self respondWithButtonIndex:-1];
+        CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
+        [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+      } else {
+        // dismissing with -2 because it's +1'd by didDismissWithButtonIndex below and we want it to report -1
+        [self.actionSheet dismissWithClickedButtonIndex:-2 animated:true];
+        CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
+        [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+      }
+  });
+}
+
+#pragma mark - helper methods
+
+- (NSString *)encodeString:(NSString *)input
+{
+  if (input == nil) {
+    return nil;
+  } else {
+    return input;
+  }
+}
+
+- (CGRect)getPopupRectFromIPadPopupCoordinates:(NSArray *)comps
+{
+  CGRect rect = CGRectZero;
+  if ([comps count] == 2) {
+    rect = CGRectMake([comps[0] integerValue], [comps[1] integerValue], 0, 0);
+  } else if ([comps count] == 4) {
+    rect = CGRectMake([comps[0] integerValue], [comps[1] integerValue], [comps[2] integerValue], [comps[3] integerValue]);
+  }
+  return rect;
+}
+
+#pragma mark - UIActionSheetDelegate methods
+
+- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex
+{
+
+  // ActionSheet button index is 0-based, but other Cordova plugins are 1-based (prompt, confirm)
+  buttonIndex++;
+
+  [self respondWithButtonIndex:(int) buttonIndex];
+}
+
+@end

+ 217 - 0
miaomiao/plugins/cordova-plugin-actionsheet/src/windows/ActionSheetProxy.js

xqd
@@ -0,0 +1,217 @@
+/*
+@date  : 11.05.2015
+@author: Pavel Durov
+@note  :  In order to use ActionSheetProxy on Universal Windows Platform -
+		  Make sure that you are referencing base.js and ui.js 
+ */
+function ActionSheet() { /* CTOR...*/ }
+
+
+ActionSheet.prototype.show = function (options, successCallback, errorCallback) {
+	
+    ActionSheet.prototype.successCallBack = successCallback;
+    ActionSheet.prototype.errorCallback = errorCallback;
+
+    if (cordova.platformId == "windows") {
+        ActionSheet.prototype._injectWinJsFlyoutHTML();
+    }
+
+    if (options) {
+        var actionSheetProxyFlyoutDiv = document.getElementById("actionSheetProxyFlyoutDiv");
+        //Settings popup
+        this._clearChildren(actionSheetProxyFlyoutDiv);
+
+        if (options.title) {    //Append Title
+            this._addTitle(options.title, actionSheetProxyFlyoutDiv);
+        }
+
+        if (!options.destructiveButtonLast && options.addDestructiveButtonWithLabel) {    //Generate Desctructive Button
+            this._addDestructiveButton(options.addDestructiveButtonWithLabel, actionSheetProxyFlyoutDiv);
+        }
+
+        if (options.buttonLabels && options.buttonLabels instanceof Array) {    //Appending Buttons to main Flyout Div
+            this._addbuttons(options.buttonLabels, actionSheetProxyFlyoutDiv);
+        }
+
+        if (options.destructiveButtonLast && options.addDestructiveButtonWithLabel) {    //Generate Desctructive Button
+            this._addDestructiveButton(options.addDestructiveButtonWithLabel, actionSheetProxyFlyoutDiv);
+        }
+
+        if (options.winphoneEnableCancelButton && options.addCancelButtonWithLabel) {
+
+            this._addCancelButton(options.addCancelButtonWithLabel, actionSheetProxyFlyoutDiv);
+        }
+        
+        var fly = document.getElementById("fly-test");
+        WinJS.UI.process(fly).done(function () {
+
+            if (fly && fly.winControl) {
+                //var bodys = document.getElementsByClassName('bodyClass')[0];
+                var anchor = document.getElementById("actionSheetSetPoint");
+                if (anchor) {
+                    fly.winControl.show(anchor, "bottom");
+                }
+
+
+            } else {
+                console.log("winControl is undefined");
+            }
+        });
+    }
+
+    document.addEventListener('backbutton', window.plugins.actionsheet.hide, false)
+};
+
+
+ActionSheet.prototype.hide = function (options, successCallback, errorCallback) {
+    console.log("//\\//\\//\\//\\//\\ ActionSheet.prototype.hide ");
+
+    var fly = document.getElementById("fly-test");
+
+    WinJS.UI.process(fly).done(function () {
+        if (fly.winControl && fly.winControl.hide) {
+            //WinJS.UI.Animation.hidePopup(fly).done( /* Your success and error handlers */);
+            fly.winControl.hide();
+        }
+    });
+};
+
+
+
+ActionSheet.prototype.ANDROID_THEMES = {
+    THEME_TRADITIONAL: 1, // default
+    THEME_HOLO_DARK: 2,
+    THEME_HOLO_LIGHT: 3,
+    THEME_DEVICE_DEFAULT_DARK: 4,
+    THEME_DEVICE_DEFAULT_LIGHT: 5
+};
+
+ActionSheet.prototype.install = function () {
+    if (!window.plugins) {
+        window.plugins = {};
+    }
+    window.plugins.actionsheet = new ActionSheet();
+
+    return window.plugins.actionsheet;
+};
+
+cordova.addConstructor(ActionSheet.prototype.install);
+cordova.commandProxy.add("ActionSheet", ActionSheet);
+
+
+//Helpers
+
+
+ActionSheet.prototype._addTitle = function (label, destinationCtrl) {
+    var textCtrl = this._generateTitle(label)
+    destinationCtrl.appendChild(textCtrl);
+}
+
+
+ActionSheet.prototype._addDestructiveButton = function (label, destinationCtrl) {
+    if (label && destinationCtrl) {
+        var destructive_btn = this._generateButton(label, this._getDestructiveButtonStyle());
+        destinationCtrl.appendChild(destructive_btn);
+    }
+}
+
+ActionSheet.prototype._addCancelButton = function (label, destinationCtrl) {
+    if (label && destinationCtrl) {
+        var cancel_btn = this._generateButton(label, this._getCancelButtonStyle());
+        cancel_btn.onclick = function () {
+            ActionSheet.prototype.hide();
+        }
+
+        destinationCtrl.appendChild(cancel_btn);
+    }
+}
+
+ActionSheet.prototype._addbuttons = function (lables, destinationCtrl) {
+    if (lables && destinationCtrl) {
+        for (var i = 0; i < lables.length; i++) {
+            var btn = this._generateButton(lables[i], this._getButtonStyle());
+	    (function (i) {
+            	btn.onclick = function () {
+                    if (ActionSheet.prototype.successCallBack) {
+                    	ActionSheet.prototype.successCallBack(i + 1);
+                    	ActionSheet.prototype.hide();
+                    }                
+            	}
+            })(i);
+            destinationCtrl.appendChild(btn);
+        }
+    }
+}
+
+ActionSheet.prototype._clearChildren = function (element) {
+    if (element && element.hasChildNodes) {
+        while (element.hasChildNodes()) {
+            element.removeChild(element.lastChild);
+        }
+    }
+}
+
+ActionSheet.prototype._generateButton = function (content, style) {
+
+    var btn = document.createElement("input");
+    btn.setAttribute("type", "button");
+    btn.setAttribute("value", content);
+
+    btn.setAttribute("style", style);//;
+
+    return btn;
+}
+
+
+//Style
+ActionSheet.prototype._getButtonStyle = function () {
+    return "display: table-row; font-size: 20px; background-color :black;" +
+            " color: white; width: 98%; position: relative; margin: 1%; background: black; margin-top: 20px; height: 60px;"
+}
+//The only diffrence beweet regulat button and cancel vuttokn styles is WIDTH!!
+ActionSheet.prototype._getCancelButtonStyle = function () {
+    return "display: table-row; font-size: 20px; background-color :black;" +
+            " color: white; width: 49%; position: relative; margin: 1%; background: black; margin-top: 20px; height: 60px;"
+}
+//The only diffrence beweet destructive button and regular is its color (orange)!
+ActionSheet.prototype._getDestructiveButtonStyle = function () {
+    return "display: table-row; font-size: 20px; background-color : black;" +
+            " color: orange; width: 98%; position: relative; margin: 1%; background: black; margin-top: 20px; height: 60px;"
+}
+
+
+
+ActionSheet.prototype._getMainDivStyle = function () {
+    return "position:absolute; width:99%; display: table; background-color: #4F4F4F; padding: 15px; visibility:collapse ; text-align : center;";
+}
+
+ActionSheet.prototype._getTitleStyle = function () {
+    return "color:white; font-size: 30px; ";
+}
+
+ActionSheet.prototype._generateTitle = function (textLebel) {
+    var spanCtrl = document.createElement("span");
+    spanCtrl.setAttribute("style", this._getTitleStyle());
+    spanCtrl.innerHTML = textLebel;
+    return spanCtrl;
+}
+
+ActionSheet.prototype._injectWinJsFlyoutHTML = function () {
+    var divSetPoint = document.createElement("div");
+    divSetPoint.setAttribute("id", "actionSheetSetPoint");
+    divSetPoint.setAttribute("aria-haspopup", "true");
+    divSetPoint.setAttribute("style", "visibility:collapse");
+
+    var flyoutDiv = document.createElement("div");
+    flyoutDiv.setAttribute("data-win-control", "WinJS.UI.Flyout");
+    flyoutDiv.setAttribute("id", "fly-test");
+    flyoutDiv.setAttribute("style", this._getMainDivStyle());
+
+    var internalDiv = document.createElement("div");
+    internalDiv.setAttribute("id", "actionSheetProxyFlyoutDiv");
+
+    flyoutDiv.appendChild(internalDiv);
+
+    document.body.appendChild(flyoutDiv);
+    document.body.appendChild(divSetPoint);
+}

+ 209 - 0
miaomiao/plugins/cordova-plugin-actionsheet/src/wp8/ActionSheet.cs

xqd
@@ -0,0 +1,209 @@
+using Microsoft.Phone.Tasks;
+using Microsoft.Phone.Controls;
+using WPCordovaClassLib.Cordova;
+using WPCordovaClassLib.Cordova.Commands;
+using WPCordovaClassLib.Cordova.JSON;
+using System.Runtime.Serialization;
+using System;
+using System.Windows;
+using System.Windows.Media;
+using System.Windows.Controls;
+using System.Windows.Controls.Primitives;
+using WPCordovaClassLib;
+
+namespace Cordova.Extension.Commands
+{
+    public class ActionSheet : BaseCommand
+    {
+
+        [DataContract]
+        public class ActionSheetOptions
+        {
+            [DataMember(IsRequired = false, Name = "buttonLabels")]
+            public string[] buttonLabels { get; set; }
+
+            [DataMember(IsRequired = false, Name = "title")]
+            public string title { get; set; }
+
+            [DataMember(IsRequired = false, Name = "addCancelButtonWithLabel")]
+            public string addCancelButtonWithLabel { get; set; }
+
+            [DataMember(IsRequired = false, Name = "addDestructiveButtonWithLabel")]
+            public string addDestructiveButtonWithLabel { get; set; }
+
+            [DataMember(IsRequired = false, Name = "winphoneEnableCancelButton")]
+            public bool winphoneEnableCancelButton { get; set; }
+
+            [DataMember(IsRequired = false, Name = "destructiveButtonLast")]
+            public bool destructiveButtonLast { get; set; }
+        }
+
+        private ActionSheetOptions actionSheetOptions = null;
+
+        private Popup popup = new Popup();
+
+        private Brush darkBrush = new SolidColorBrush(Color.FromArgb(250, 40, 40, 40));
+
+        public void show(string options)
+        {
+            try
+            {
+                String jsonOptions = JsonHelper.Deserialize<string[]>(options)[0];
+                actionSheetOptions = JsonHelper.Deserialize<ActionSheetOptions>(jsonOptions);
+            }
+            catch (Exception)
+            {
+                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+                return;
+            }
+
+            Deployment.Current.Dispatcher.BeginInvoke(() =>
+            {
+                // attach a backbutton listener to the view and dim it a bit
+                CordovaView cView = getCordovaView();
+                cView.Browser.Dispatcher.BeginInvoke(() =>
+                {
+                    cView.Browser.InvokeScript("eval", "document.addEventListener('backbutton', window.plugins.actionsheet.hide, false)");
+                    cView.Browser.Opacity = 0.5d;
+                });
+
+                Border border = new Border();
+                border.Width = Application.Current.Host.Content.ActualWidth;
+                border.Background = darkBrush;
+                border.Padding = new Thickness(10, 10, 10, 10);
+
+
+                // container for the buttons
+                StackPanel panel = new StackPanel();
+                panel.HorizontalAlignment = HorizontalAlignment.Stretch;
+                panel.VerticalAlignment = VerticalAlignment.Center;
+                panel.Width = Application.Current.Host.Content.ActualWidth - 60;
+
+
+                // title
+                if (actionSheetOptions.title != null)
+                {
+                    TextBlock textblock1 = new TextBlock();
+                    textblock1.Text = actionSheetOptions.title;
+                    textblock1.TextWrapping = TextWrapping.Wrap;
+                    textblock1.Margin = new Thickness(20, 10, 20, 0); // left, top, right, bottom
+                    textblock1.FontSize = 22;
+                    textblock1.Foreground = new SolidColorBrush(Colors.White);
+                    panel.Children.Add(textblock1);
+                }
+
+                int buttonIndex = 1;
+
+                // destructive button
+                if (!actionSheetOptions.destructiveButtonLast && actionSheetOptions.addDestructiveButtonWithLabel != null)
+                {
+                    Button button = new Button();
+                    button.TabIndex = buttonIndex++;
+                    button.Content = actionSheetOptions.addDestructiveButtonWithLabel;
+                    button.Background = darkBrush; // new SolidColorBrush(Colors.White);
+                    button.Foreground = new SolidColorBrush(Color.FromArgb(255, 255, 69, 0));
+                    button.Padding = new Thickness(10);
+                    button.Margin = new Thickness(5);
+                    button.Click += new RoutedEventHandler(buttonClickListener);
+                    panel.Children.Add(button);
+                }
+
+
+                // regular buttons
+                if (actionSheetOptions.buttonLabels != null)
+                {
+                    foreach (String buttonLabel in actionSheetOptions.buttonLabels)
+                    {
+                        Button button = new Button();
+                        button.TabIndex = buttonIndex++;
+                        button.Content = buttonLabel;
+                        button.Background = darkBrush;
+                        button.Foreground = new SolidColorBrush(Colors.White);
+                        button.Padding = new Thickness(10);
+                        button.Margin = new Thickness(5);
+                        button.Click += new RoutedEventHandler(buttonClickListener);
+                        panel.Children.Add(button);
+                    }
+                }
+
+                // destructive button
+                if (actionSheetOptions.destructiveButtonLast && actionSheetOptions.addDestructiveButtonWithLabel != null)
+                {
+                    Button button = new Button();
+                    button.TabIndex = buttonIndex++;
+                    button.Content = actionSheetOptions.addDestructiveButtonWithLabel;
+                    button.Background = darkBrush; // new SolidColorBrush(Colors.White);
+                    button.Foreground = new SolidColorBrush(Color.FromArgb(255, 255, 69, 0));
+                    button.Padding = new Thickness(10);
+                    button.Margin = new Thickness(5);
+                    button.Click += new RoutedEventHandler(buttonClickListener);
+                    panel.Children.Add(button);
+                }
+
+                // cancel button
+                if (actionSheetOptions.winphoneEnableCancelButton && actionSheetOptions.addCancelButtonWithLabel != null)
+                {
+                    Button button = new Button();
+                    button.HorizontalAlignment = HorizontalAlignment.Left;
+                    button.TabIndex = buttonIndex++;
+                    button.Content = actionSheetOptions.addCancelButtonWithLabel;
+                    button.Padding = new Thickness(50, 10, 50, 10);
+                    button.Margin = new Thickness(5, 0, 20, 5);
+                    button.FontSize = 17;
+                    button.Background = darkBrush;
+                    button.Foreground = new SolidColorBrush(Colors.White);
+
+                    button.Click += new RoutedEventHandler(buttonClickListener);
+                    panel.Children.Add(button);
+
+                }
+
+                border.Child = panel;
+                popup.Child = border;
+
+                // Set where the popup will show up on the screen.
+                popup.VerticalOffset = 30;
+
+                // Open the popup.
+                popup.IsOpen = true;
+            });
+        }
+
+        void buttonClickListener(object sender, RoutedEventArgs e)
+        {
+            // Close the popup
+            hide(null);
+
+            // Get the clicked button index
+            Button button = (Button)sender;
+            DispatchCommandResult(new PluginResult(PluginResult.Status.OK, button.TabIndex));
+        }
+
+        public void hide(string options)
+        {
+            Deployment.Current.Dispatcher.BeginInvoke(() =>
+            {
+                // remove the backbutton listener from the view and undim it
+                CordovaView cView = getCordovaView();
+                getCordovaView().Browser.Dispatcher.BeginInvoke(() =>
+                {
+                    cView.Browser.InvokeScript("eval", "document.removeEventListener('backbutton', window.plugins.actionsheet.hide, false)");
+                    cView.Browser.Opacity = 1d;
+                });
+
+                if (popup.IsOpen)
+                {
+                    popup.IsOpen = false;
+                }
+            });
+        }
+
+        // note: needs to be invoked from within Deployment.Current.Dispatcher.BeginInvoke ..
+        private CordovaView getCordovaView()
+        {
+            PhoneApplicationFrame frame = (PhoneApplicationFrame)Application.Current.RootVisual;
+            PhoneApplicationPage page = (PhoneApplicationPage)frame.Content;
+            return (CordovaView)page.FindName("CordovaView");
+        }
+    }
+}

+ 30 - 0
miaomiao/plugins/cordova-plugin-actionsheet/www/ActionSheet.js

xqd
@@ -0,0 +1,30 @@
+function ActionSheet() {
+}
+
+ActionSheet.prototype.show = function (options, successCallback, errorCallback) {
+  cordova.exec(successCallback, errorCallback, "ActionSheet", "show", [options]);
+};
+
+ActionSheet.prototype.hide = function (options, successCallback, errorCallback) {
+  cordova.exec(successCallback, errorCallback, "ActionSheet", "hide", [options]);
+};
+
+ActionSheet.prototype.ANDROID_THEMES = {
+  THEME_TRADITIONAL          : 1, // default
+  THEME_HOLO_DARK            : 2,
+  THEME_HOLO_LIGHT           : 3,
+  THEME_DEVICE_DEFAULT_DARK  : 4,
+  THEME_DEVICE_DEFAULT_LIGHT : 5
+};
+
+ActionSheet.install = function () {
+  if (!window.plugins) {
+    window.plugins = {};
+  }
+
+  window.plugins.actionsheet = new ActionSheet();
+
+  return window.plugins.actionsheet;
+};
+
+cordova.addConstructor(ActionSheet.install);

+ 37 - 0
miaomiao/plugins/cordova-plugin-camera/CONTRIBUTING.md

xqd
@@ -0,0 +1,37 @@
+<!--
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+-->
+
+# Contributing to Apache Cordova
+
+Anyone can contribute to Cordova. And we need your contributions.
+
+There are multiple ways to contribute: report bugs, improve the docs, and
+contribute code.
+
+For instructions on this, start with the 
+[contribution overview](http://cordova.apache.org/contribute/).
+
+The details are explained there, but the important items are:
+ - Sign and submit an Apache ICLA (Contributor License Agreement).
+ - Have a Jira issue open that corresponds to your contribution.
+ - Run the tests so your patch doesn't break existing functionality.
+
+We look forward to your contributions!

+ 202 - 0
miaomiao/plugins/cordova-plugin-camera/LICENSE

xqd
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.

+ 5 - 0
miaomiao/plugins/cordova-plugin-camera/NOTICE

xqd
@@ -0,0 +1,5 @@
+Apache Cordova
+Copyright 2012 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).

+ 793 - 0
miaomiao/plugins/cordova-plugin-camera/README.md

xqd
@@ -0,0 +1,793 @@
+---
+title: Camera
+description: Take pictures with the device camera.
+---
+<!---
+# license: Licensed to the Apache Software Foundation (ASF) under one
+#         or more contributor license agreements.  See the NOTICE file
+#         distributed with this work for additional information
+#         regarding copyright ownership.  The ASF licenses this file
+#         to you under the Apache License, Version 2.0 (the
+#         "License"); you may not use this file except in compliance
+#         with the License.  You may obtain a copy of the License at
+#
+#           http://www.apache.org/licenses/LICENSE-2.0
+#
+#         Unless required by applicable law or agreed to in writing,
+#         software distributed under the License is distributed on an
+#         "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#         KIND, either express or implied.  See the License for the
+#         specific language governing permissions and limitations
+#         under the License.
+-->
+
+|Android|iOS| Windows 8.1 Store | Windows 8.1 Phone | Windows 10 Store | Travis CI |
+|:-:|:-:|:-:|:-:|:-:|:-:|
+|[![Build Status](http://cordova-ci.cloudapp.net:8080/buildStatus/icon?job=cordova-periodic-build/PLATFORM=android,PLUGIN=cordova-plugin-camera)](http://cordova-ci.cloudapp.net:8080/job/cordova-periodic-build/PLATFORM=android,PLUGIN=cordova-plugin-camera/)|[![Build Status](http://cordova-ci.cloudapp.net:8080/buildStatus/icon?job=cordova-periodic-build/PLATFORM=ios,PLUGIN=cordova-plugin-camera)](http://cordova-ci.cloudapp.net:8080/job/cordova-periodic-build/PLATFORM=ios,PLUGIN=cordova-plugin-camera/)|[![Build Status](http://cordova-ci.cloudapp.net:8080/buildStatus/icon?job=cordova-periodic-build/PLATFORM=windows-8.1-store,PLUGIN=cordova-plugin-camera)](http://cordova-ci.cloudapp.net:8080/job/cordova-periodic-build/PLATFORM=windows-8.1-store,PLUGIN=cordova-plugin-camera/)|[![Build Status](http://cordova-ci.cloudapp.net:8080/buildStatus/icon?job=cordova-periodic-build/PLATFORM=windows-8.1-phone,PLUGIN=cordova-plugin-camera)](http://cordova-ci.cloudapp.net:8080/job/cordova-periodic-build/PLATFORM=windows-8.1-phone,PLUGIN=cordova-plugin-camera/)|[![Build Status](http://cordova-ci.cloudapp.net:8080/buildStatus/icon?job=cordova-periodic-build/PLATFORM=windows-10-store,PLUGIN=cordova-plugin-camera)](http://cordova-ci.cloudapp.net:8080/job/cordova-periodic-build/PLATFORM=windows-10-store,PLUGIN=cordova-plugin-camera/)|[![Build Status](https://travis-ci.org/apache/cordova-plugin-camera.svg?branch=master)](https://travis-ci.org/apache/cordova-plugin-camera)
+
+# cordova-plugin-camera
+
+This plugin defines a global `navigator.camera` object, which provides an API for taking pictures and for choosing images from
+the system's image library.
+
+Although the object is attached to the global scoped `navigator`, it is not available until after the `deviceready` event.
+
+    document.addEventListener("deviceready", onDeviceReady, false);
+    function onDeviceReady() {
+        console.log(navigator.camera);
+    }
+
+
+## Installation
+
+This requires cordova 5.0+
+
+    cordova plugin add cordova-plugin-camera
+Older versions of cordova can still install via the __deprecated__ id
+
+    cordova plugin add org.apache.cordova.camera
+It is also possible to install via repo url directly ( unstable )
+
+    cordova plugin add https://github.com/apache/cordova-plugin-camera.git
+
+
+## How to Contribute
+
+Contributors are welcome! And we need your contributions to keep the project moving forward. You can [report bugs](https://issues.apache.org/jira/issues/?jql=project%20%3D%20CB%20AND%20status%20in%20(Open%2C%20%22In%20Progress%22%2C%20Reopened)%20AND%20resolution%20%3D%20Unresolved%20AND%20component%20%3D%20%22Plugin%20Camera%22%20ORDER%20BY%20priority%20DESC%2C%20summary%20ASC%2C%20updatedDate%20DESC), improve the documentation, or [contribute code](https://github.com/apache/cordova-plugin-camera/pulls).
+
+There is a specific [contributor workflow](http://wiki.apache.org/cordova/ContributorWorkflow) we recommend. Start reading there. More information is available on [our wiki](http://wiki.apache.org/cordova).
+
+:warning: **Found an issue?** File it on [JIRA issue tracker](https://issues.apache.org/jira/issues/?jql=project%20%3D%20CB%20AND%20status%20in%20(Open%2C%20%22In%20Progress%22%2C%20Reopened)%20AND%20resolution%20%3D%20Unresolved%20AND%20component%20%3D%20%22Plugin%20Camera%22%20ORDER%20BY%20priority%20DESC%2C%20summary%20ASC%2C%20updatedDate%20DESC).
+
+**Have a solution?** Send a [Pull Request](https://github.com/apache/cordova-plugin-camera/pulls).
+
+In order for your changes to be accepted, you need to sign and submit an Apache [ICLA](http://www.apache.org/licenses/#clas) (Individual Contributor License Agreement). Then your name will appear on the list of CLAs signed by [non-committers](https://people.apache.org/committer-index.html#unlistedclas) or [Cordova committers](http://people.apache.org/committers-by-project.html#cordova).
+
+**And don't forget to test and document your code.**
+
+
+## This documentation is generated by a tool
+
+:warning: Run `npm install` in the plugin repo to enable automatic docs generation if you plan to send a PR.  
+[jsdoc-to-markdown](https://www.npmjs.com/package/jsdoc-to-markdown) is used to generate the docs.  
+Documentation consists of template and API docs produced from the plugin JS code and should be regenerated before each commit (done automatically via [husky](https://github.com/typicode/husky), running `npm run gen-docs` script as a `precommit` hook - see `package.json` for details).
+
+
+
+### iOS Quirks
+
+Since iOS 10 it's mandatory to add a `NSCameraUsageDescription` and `NSPhotoLibraryUsageDescription` in the info.plist.
+
+- `NSCameraUsageDescription` describes the reason that the app accesses the user’s camera.
+- `NSPhotoLibraryUsageDescription` describes the reason the app accesses the user's photo library. 
+
+When the system prompts the user to allow access, this string is displayed as part of the dialog box. 
+
+To add this entry you can pass the following variables on plugin install.
+
+- `CAMERA_USAGE_DESCRIPTION` for `NSCameraUsageDescription`
+- `PHOTOLIBRARY_USAGE_DESCRIPTION` for `NSPhotoLibraryUsageDescription`
+
+Example:
+
+    cordova plugin add cordova-plugin-camera --variable CAMERA_USAGE_DESCRIPTION="your usage message" --variable PHOTOLIBRARY_USAGE_DESCRIPTION="your usage message"
+
+If you don't pass the variable, the plugin will add an empty string as value.
+
+---
+
+# API Reference <a name="reference"></a>
+
+
+* [camera](#module_camera)
+    * [.getPicture(successCallback, errorCallback, options)](#module_camera.getPicture)
+    * [.cleanup()](#module_camera.cleanup)
+    * [.onError](#module_camera.onError) : <code>function</code>
+    * [.onSuccess](#module_camera.onSuccess) : <code>function</code>
+    * [.CameraOptions](#module_camera.CameraOptions) : <code>Object</code>
+
+
+* [Camera](#module_Camera)
+    * [.DestinationType](#module_Camera.DestinationType) : <code>enum</code>
+    * [.EncodingType](#module_Camera.EncodingType) : <code>enum</code>
+    * [.MediaType](#module_Camera.MediaType) : <code>enum</code>
+    * [.PictureSourceType](#module_Camera.PictureSourceType) : <code>enum</code>
+    * [.PopoverArrowDirection](#module_Camera.PopoverArrowDirection) : <code>enum</code>
+    * [.Direction](#module_Camera.Direction) : <code>enum</code>
+
+* [CameraPopoverHandle](#module_CameraPopoverHandle)
+* [CameraPopoverOptions](#module_CameraPopoverOptions)
+
+---
+
+<a name="module_camera"></a>
+
+## camera
+<a name="module_camera.getPicture"></a>
+
+### camera.getPicture(successCallback, errorCallback, options)
+Takes a photo using the camera, or retrieves a photo from the device's
+image gallery.  The image is passed to the success callback as a
+Base64-encoded `String`, or as the URI for the image file.
+
+The `camera.getPicture` function opens the device's default camera
+application that allows users to snap pictures by default - this behavior occurs,
+when `Camera.sourceType` equals [`Camera.PictureSourceType.CAMERA`](#module_Camera.PictureSourceType).
+Once the user snaps the photo, the camera application closes and the application is restored.
+
+If `Camera.sourceType` is `Camera.PictureSourceType.PHOTOLIBRARY` or
+`Camera.PictureSourceType.SAVEDPHOTOALBUM`, then a dialog displays
+that allows users to select an existing image.
+
+The return value is sent to the [`cameraSuccess`](#module_camera.onSuccess) callback function, in
+one of the following formats, depending on the specified
+`cameraOptions`:
+
+- A `String` containing the Base64-encoded photo image.
+- A `String` representing the image file location on local storage (default).
+
+You can do whatever you want with the encoded image or URI, for
+example:
+
+- Render the image in an `<img>` tag, as in the example below
+- Save the data locally (`LocalStorage`, [Lawnchair](http://brianleroux.github.com/lawnchair/), etc.)
+- Post the data to a remote server
+
+__NOTE__: Photo resolution on newer devices is quite good. Photos
+selected from the device's gallery are not downscaled to a lower
+quality, even if a `quality` parameter is specified.  To avoid common
+memory problems, set `Camera.destinationType` to `FILE_URI` rather
+than `DATA_URL`.
+
+__Supported Platforms__
+
+- Android
+- BlackBerry
+- Browser
+- Firefox
+- FireOS
+- iOS
+- Windows
+- WP8
+- Ubuntu
+
+More examples [here](#camera-getPicture-examples). Quirks [here](#camera-getPicture-quirks).
+
+**Kind**: static method of <code>[camera](#module_camera)</code>  
+
+| Param | Type | Description |
+| --- | --- | --- |
+| successCallback | <code>[onSuccess](#module_camera.onSuccess)</code> |  |
+| errorCallback | <code>[onError](#module_camera.onError)</code> |  |
+| options | <code>[CameraOptions](#module_camera.CameraOptions)</code> | CameraOptions |
+
+**Example**  
+```js
+navigator.camera.getPicture(cameraSuccess, cameraError, cameraOptions);
+```
+<a name="module_camera.cleanup"></a>
+
+### camera.cleanup()
+Removes intermediate image files that are kept in temporary storage
+after calling [`camera.getPicture`](#module_camera.getPicture). Applies only when the value of
+`Camera.sourceType` equals `Camera.PictureSourceType.CAMERA` and the
+`Camera.destinationType` equals `Camera.DestinationType.FILE_URI`.
+
+__Supported Platforms__
+
+- iOS
+
+**Kind**: static method of <code>[camera](#module_camera)</code>  
+**Example**  
+```js
+navigator.camera.cleanup(onSuccess, onFail);
+
+function onSuccess() {
+    console.log("Camera cleanup success.")
+}
+
+function onFail(message) {
+    alert('Failed because: ' + message);
+}
+```
+<a name="module_camera.onError"></a>
+
+### camera.onError : <code>function</code>
+Callback function that provides an error message.
+
+**Kind**: static typedef of <code>[camera](#module_camera)</code>  
+
+| Param | Type | Description |
+| --- | --- | --- |
+| message | <code>string</code> | The message is provided by the device's native code. |
+
+<a name="module_camera.onSuccess"></a>
+
+### camera.onSuccess : <code>function</code>
+Callback function that provides the image data.
+
+**Kind**: static typedef of <code>[camera](#module_camera)</code>  
+
+| Param | Type | Description |
+| --- | --- | --- |
+| imageData | <code>string</code> | Base64 encoding of the image data, _or_ the image file URI, depending on [`cameraOptions`](#module_camera.CameraOptions) in effect. |
+
+**Example**  
+```js
+// Show image
+//
+function cameraCallback(imageData) {
+   var image = document.getElementById('myImage');
+   image.src = "data:image/jpeg;base64," + imageData;
+}
+```
+<a name="module_camera.CameraOptions"></a>
+
+### camera.CameraOptions : <code>Object</code>
+Optional parameters to customize the camera settings.
+* [Quirks](#CameraOptions-quirks)
+
+**Kind**: static typedef of <code>[camera](#module_camera)</code>  
+**Properties**
+
+| Name | Type | Default | Description |
+| --- | --- | --- | --- |
+| quality | <code>number</code> | <code>50</code> | Quality of the saved image, expressed as a range of 0-100, where 100 is typically full resolution with no loss from file compression. (Note that information about the camera's resolution is unavailable.) |
+| destinationType | <code>[DestinationType](#module_Camera.DestinationType)</code> | <code>FILE_URI</code> | Choose the format of the return value. |
+| sourceType | <code>[PictureSourceType](#module_Camera.PictureSourceType)</code> | <code>CAMERA</code> | Set the source of the picture. |
+| allowEdit | <code>Boolean</code> | <code>true</code> | Allow simple editing of image before selection. |
+| encodingType | <code>[EncodingType](#module_Camera.EncodingType)</code> | <code>JPEG</code> | Choose the  returned image file's encoding. |
+| targetWidth | <code>number</code> |  | Width in pixels to scale image. Must be used with `targetHeight`. Aspect ratio remains constant. |
+| targetHeight | <code>number</code> |  | Height in pixels to scale image. Must be used with `targetWidth`. Aspect ratio remains constant. |
+| mediaType | <code>[MediaType](#module_Camera.MediaType)</code> | <code>PICTURE</code> | Set the type of media to select from.  Only works when `PictureSourceType` is `PHOTOLIBRARY` or `SAVEDPHOTOALBUM`. |
+| correctOrientation | <code>Boolean</code> |  | Rotate the image to correct for the orientation of the device during capture. |
+| saveToPhotoAlbum | <code>Boolean</code> |  | Save the image to the photo album on the device after capture. |
+| popoverOptions | <code>[CameraPopoverOptions](#module_CameraPopoverOptions)</code> |  | iOS-only options that specify popover location in iPad. |
+| cameraDirection | <code>[Direction](#module_Camera.Direction)</code> | <code>BACK</code> | Choose the camera to use (front- or back-facing). |
+
+---
+
+<a name="module_Camera"></a>
+
+## Camera
+<a name="module_Camera.DestinationType"></a>
+
+### Camera.DestinationType : <code>enum</code>
+Defines the output format of `Camera.getPicture` call.
+_Note:_ On iOS passing `DestinationType.NATIVE_URI` along with
+`PictureSourceType.PHOTOLIBRARY` or `PictureSourceType.SAVEDPHOTOALBUM` will
+disable any image modifications (resize, quality change, cropping, etc.) due
+to implementation specific.
+
+**Kind**: static enum property of <code>[Camera](#module_Camera)</code>  
+**Properties**
+
+| Name | Type | Default | Description |
+| --- | --- | --- | --- |
+| DATA_URL | <code>number</code> | <code>0</code> | Return base64 encoded string. DATA_URL can be very memory intensive and cause app crashes or out of memory errors. Use FILE_URI or NATIVE_URI if possible |
+| FILE_URI | <code>number</code> | <code>1</code> | Return file uri (content://media/external/images/media/2 for Android) |
+| NATIVE_URI | <code>number</code> | <code>2</code> | Return native uri (eg. asset-library://... for iOS) |
+
+<a name="module_Camera.EncodingType"></a>
+
+### Camera.EncodingType : <code>enum</code>
+**Kind**: static enum property of <code>[Camera](#module_Camera)</code>  
+**Properties**
+
+| Name | Type | Default | Description |
+| --- | --- | --- | --- |
+| JPEG | <code>number</code> | <code>0</code> | Return JPEG encoded image |
+| PNG | <code>number</code> | <code>1</code> | Return PNG encoded image |
+
+<a name="module_Camera.MediaType"></a>
+
+### Camera.MediaType : <code>enum</code>
+**Kind**: static enum property of <code>[Camera](#module_Camera)</code>  
+**Properties**
+
+| Name | Type | Default | Description |
+| --- | --- | --- | --- |
+| PICTURE | <code>number</code> | <code>0</code> | Allow selection of still pictures only. DEFAULT. Will return format specified via DestinationType |
+| VIDEO | <code>number</code> | <code>1</code> | Allow selection of video only, ONLY RETURNS URL |
+| ALLMEDIA | <code>number</code> | <code>2</code> | Allow selection from all media types |
+
+<a name="module_Camera.PictureSourceType"></a>
+
+### Camera.PictureSourceType : <code>enum</code>
+Defines the output format of `Camera.getPicture` call.
+_Note:_ On iOS passing `PictureSourceType.PHOTOLIBRARY` or `PictureSourceType.SAVEDPHOTOALBUM`
+along with `DestinationType.NATIVE_URI` will disable any image modifications (resize, quality
+change, cropping, etc.) due to implementation specific.
+
+**Kind**: static enum property of <code>[Camera](#module_Camera)</code>  
+**Properties**
+
+| Name | Type | Default | Description |
+| --- | --- | --- | --- |
+| PHOTOLIBRARY | <code>number</code> | <code>0</code> | Choose image from the device's photo library (same as SAVEDPHOTOALBUM for Android) |
+| CAMERA | <code>number</code> | <code>1</code> | Take picture from camera |
+| SAVEDPHOTOALBUM | <code>number</code> | <code>2</code> | Choose image only from the device's Camera Roll album (same as PHOTOLIBRARY for Android) |
+
+<a name="module_Camera.PopoverArrowDirection"></a>
+
+### Camera.PopoverArrowDirection : <code>enum</code>
+Matches iOS UIPopoverArrowDirection constants to specify arrow location on popover.
+
+**Kind**: static enum property of <code>[Camera](#module_Camera)</code>  
+**Properties**
+
+| Name | Type | Default |
+| --- | --- | --- |
+| ARROW_UP | <code>number</code> | <code>1</code> | 
+| ARROW_DOWN | <code>number</code> | <code>2</code> | 
+| ARROW_LEFT | <code>number</code> | <code>4</code> | 
+| ARROW_RIGHT | <code>number</code> | <code>8</code> | 
+| ARROW_ANY | <code>number</code> | <code>15</code> | 
+
+<a name="module_Camera.Direction"></a>
+
+### Camera.Direction : <code>enum</code>
+**Kind**: static enum property of <code>[Camera](#module_Camera)</code>  
+**Properties**
+
+| Name | Type | Default | Description |
+| --- | --- | --- | --- |
+| BACK | <code>number</code> | <code>0</code> | Use the back-facing camera |
+| FRONT | <code>number</code> | <code>1</code> | Use the front-facing camera |
+
+---
+
+<a name="module_CameraPopoverOptions"></a>
+
+## CameraPopoverOptions
+iOS-only parameters that specify the anchor element location and arrow
+direction of the popover when selecting images from an iPad's library
+or album.
+Note that the size of the popover may change to adjust to the
+direction of the arrow and orientation of the screen.  Make sure to
+account for orientation changes when specifying the anchor element
+location.
+
+
+| Param | Type | Default | Description |
+| --- | --- | --- | --- |
+| [x] | <code>Number</code> | <code>0</code> | x pixel coordinate of screen element onto which to anchor the popover. |
+| [y] | <code>Number</code> | <code>32</code> | y pixel coordinate of screen element onto which to anchor the popover. |
+| [width] | <code>Number</code> | <code>320</code> | width, in pixels, of the screen element onto which to anchor the popover. |
+| [height] | <code>Number</code> | <code>480</code> | height, in pixels, of the screen element onto which to anchor the popover. |
+| [arrowDir] | <code>[PopoverArrowDirection](#module_Camera.PopoverArrowDirection)</code> | <code>ARROW_ANY</code> | Direction the arrow on the popover should point. |
+
+---
+
+<a name="module_CameraPopoverHandle"></a>
+
+## CameraPopoverHandle
+A handle to an image picker popover.
+
+__Supported Platforms__
+
+- iOS
+
+**Example**  
+```js
+navigator.camera.getPicture(onSuccess, onFail,
+{
+    destinationType: Camera.DestinationType.FILE_URI,
+    sourceType: Camera.PictureSourceType.PHOTOLIBRARY,
+    popoverOptions: new CameraPopoverOptions(300, 300, 100, 100, Camera.PopoverArrowDirection.ARROW_ANY)
+});
+
+// Reposition the popover if the orientation changes.
+window.onorientationchange = function() {
+    var cameraPopoverHandle = new CameraPopoverHandle();
+    var cameraPopoverOptions = new CameraPopoverOptions(0, 0, 100, 100, Camera.PopoverArrowDirection.ARROW_ANY);
+    cameraPopoverHandle.setPosition(cameraPopoverOptions);
+}
+```
+---
+
+
+## `camera.getPicture` Errata
+
+#### Example <a name="camera-getPicture-examples"></a>
+
+Take a photo and retrieve the image's file location:
+
+    navigator.camera.getPicture(onSuccess, onFail, { quality: 50,
+        destinationType: Camera.DestinationType.FILE_URI });
+
+    function onSuccess(imageURI) {
+        var image = document.getElementById('myImage');
+        image.src = imageURI;
+    }
+
+    function onFail(message) {
+        alert('Failed because: ' + message);
+    }
+
+Take a photo and retrieve it as a Base64-encoded image:
+
+    /**
+     * Warning: Using DATA_URL is not recommended! The DATA_URL destination
+     * type is very memory intensive, even with a low quality setting. Using it
+     * can result in out of memory errors and application crashes. Use FILE_URI
+     * or NATIVE_URI instead.
+     */
+    navigator.camera.getPicture(onSuccess, onFail, { quality: 25,
+        destinationType: Camera.DestinationType.DATA_URL
+    });
+
+    function onSuccess(imageData) {
+        var image = document.getElementById('myImage');
+        image.src = "data:image/jpeg;base64," + imageData;
+    }
+
+    function onFail(message) {
+        alert('Failed because: ' + message);
+    }
+
+#### Preferences (iOS)
+
+-  __CameraUsesGeolocation__ (boolean, defaults to false). For capturing JPEGs, set to true to get geolocation data in the EXIF header. This will trigger a request for geolocation permissions if set to true.
+
+        <preference name="CameraUsesGeolocation" value="false" />
+
+#### Amazon Fire OS Quirks <a name="camera-getPicture-quirks"></a>
+
+Amazon Fire OS uses intents to launch the camera activity on the device to capture
+images, and on phones with low memory, the Cordova activity may be killed.  In this
+scenario, the image may not appear when the Cordova activity is restored.
+
+#### Android Quirks
+
+Android uses intents to launch the camera activity on the device to capture
+images, and on phones with low memory, the Cordova activity may be killed.  In this
+scenario, the result from the plugin call will be delivered via the resume event.
+See [the Android Lifecycle guide][android_lifecycle]
+for more information. The `pendingResult.result` value will contain the value that
+would be passed to the callbacks (either the URI/URL or an error message). Check
+the `pendingResult.pluginStatus` to determine whether or not the call was
+successful.
+
+#### Browser Quirks
+
+Can only return photos as Base64-encoded image.
+
+#### Firefox OS Quirks
+
+Camera plugin is currently implemented using [Web Activities][web_activities].
+
+#### iOS Quirks
+
+Including a JavaScript `alert()` in either of the callback functions
+can cause problems.  Wrap the alert within a `setTimeout()` to allow
+the iOS image picker or popover to fully close before the alert
+displays:
+
+    setTimeout(function() {
+        // do your thing here!
+    }, 0);
+
+#### Windows Phone 7 Quirks
+
+Invoking the native camera application while the device is connected
+via Zune does not work, and triggers an error callback.
+
+#### Windows quirks
+
+On Windows Phone 8.1 using `SAVEDPHOTOALBUM` or `PHOTOLIBRARY` as a source type causes application to suspend until file picker returns the selected image and
+then restore with start page as defined in app's `config.xml`. In case when `camera.getPicture` was called from different page, this will lead to reloading
+start page from scratch and success and error callbacks will never be called.
+
+To avoid this we suggest using SPA pattern or call `camera.getPicture` only from your app's start page.
+
+More information about Windows Phone 8.1 picker APIs is here: [How to continue your Windows Phone app after calling a file picker](https://msdn.microsoft.com/en-us/library/windows/apps/dn720490.aspx)
+
+#### Tizen Quirks
+
+Tizen only supports a `destinationType` of
+`Camera.DestinationType.FILE_URI` and a `sourceType` of
+`Camera.PictureSourceType.PHOTOLIBRARY`.
+
+
+## `CameraOptions` Errata <a name="CameraOptions-quirks"></a>
+
+#### Amazon Fire OS Quirks
+
+- Any `cameraDirection` value results in a back-facing photo.
+
+- Ignores the `allowEdit` parameter.
+
+- `Camera.PictureSourceType.PHOTOLIBRARY` and `Camera.PictureSourceType.SAVEDPHOTOALBUM` both display the same photo album.
+
+#### Android Quirks
+
+- Any `cameraDirection` value results in a back-facing photo.
+
+- **`allowEdit` is unpredictable on Android and it should not be used!** The Android implementation of this plugin tries to find and use an application on the user's device to do image cropping. The plugin has no control over what application the user selects to perform the image cropping and it is very possible that the user could choose an incompatible option and cause the plugin to fail. This sometimes works because most devices come with an application that handles cropping in a way that is compatible with this plugin (Google Plus Photos), but it is unwise to rely on that being the case. If image editing is essential to your application, consider seeking a third party library or plugin that provides its own image editing utility for a more robust solution.
+
+- `Camera.PictureSourceType.PHOTOLIBRARY` and `Camera.PictureSourceType.SAVEDPHOTOALBUM` both display the same photo album.
+
+- Ignores the `encodingType` parameter if the image is unedited (i.e. `quality` is 100, `correctOrientation` is false, and no `targetHeight` or `targetWidth` are specified). The `CAMERA` source will always return the JPEG file given by the native camera and the `PHOTOLIBRARY` and `SAVEDPHOTOALBUM` sources will return the selected file in its existing encoding.
+
+#### BlackBerry 10 Quirks
+
+- Ignores the `quality` parameter.
+
+- Ignores the `allowEdit` parameter.
+
+- `Camera.MediaType` is not supported.
+
+- Ignores the `correctOrientation` parameter.
+
+- Ignores the `cameraDirection` parameter.
+
+#### Firefox OS Quirks
+
+- Ignores the `quality` parameter.
+
+- `Camera.DestinationType` is ignored and equals `1` (image file URI)
+
+- Ignores the `allowEdit` parameter.
+
+- Ignores the `PictureSourceType` parameter (user chooses it in a dialog window)
+
+- Ignores the `encodingType`
+
+- Ignores the `targetWidth` and `targetHeight`
+
+- `Camera.MediaType` is not supported.
+
+- Ignores the `correctOrientation` parameter.
+
+- Ignores the `cameraDirection` parameter.
+
+#### iOS Quirks
+
+- When using `destinationType.FILE_URI`, photos are saved in the application's temporary directory. The contents of the application's temporary directory is deleted when the application ends.
+
+- When using `destinationType.NATIVE_URI` and `sourceType.CAMERA`, photos are saved in the saved photo album regardless on the value of `saveToPhotoAlbum` parameter.
+
+- When using `destinationType.NATIVE_URI` and `sourceType.PHOTOLIBRARY` or `sourceType.SAVEDPHOTOALBUM`, all editing options are ignored and link is returned to original picture.
+
+#### Tizen Quirks
+
+- options not supported
+
+- always returns a FILE URI
+
+#### Windows Phone 7 and 8 Quirks
+
+- Ignores the `allowEdit` parameter.
+
+- Ignores the `correctOrientation` parameter.
+
+- Ignores the `cameraDirection` parameter.
+
+- Ignores the `saveToPhotoAlbum` parameter.  IMPORTANT: All images taken with the WP8/8 Cordova camera API are always copied to the phone's camera roll.  Depending on the user's settings, this could also mean the image is auto-uploaded to their OneDrive.  This could potentially mean the image is available to a wider audience than your app intended. If this is a blocker for your application, you will need to implement the CameraCaptureTask as [documented on MSDN][msdn_wp8_docs]. You may also comment or up-vote the related issue in the [issue tracker][wp8_bug].
+
+- Ignores the `mediaType` property of `cameraOptions` as the Windows Phone SDK does not provide a way to choose videos from PHOTOLIBRARY.
+
+[android_lifecycle]: http://cordova.apache.org/docs/en/dev/guide/platforms/android/lifecycle.html
+[web_activities]: https://hacks.mozilla.org/2013/01/introducing-web-activities/
+[wp8_bug]: https://issues.apache.org/jira/browse/CB-2083
+[msdn_wp8_docs]: http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh394006.aspx
+
+## Sample: Take Pictures, Select Pictures from the Picture Library, and Get Thumbnails <a name="sample"></a>
+
+The Camera plugin allows you to do things like open the device's Camera app and take a picture, or open the file picker and select one. The code snippets in this section demonstrate different tasks including:
+
+* Open the Camera app and [take a Picture](#takePicture)
+* Take a picture and [return thumbnails](#getThumbnails) (resized picture)
+* Take a picture and [generate a FileEntry object](#convert)
+* [Select a file](#selectFile) from the picture library
+* Select a JPEG image and [return thumbnails](#getFileThumbnails) (resized image)
+* Select an image and [generate a FileEntry object](#convert)
+
+## Take a Picture <a name="takePicture"></a>
+
+Before you can take a picture, you need to set some Camera plugin options to pass into the Camera plugin's `getPicture` function. Here is a common set of recommendations. In this example, you create the object that you will use for the Camera options, and set the `sourceType` dynamically to support both the Camera app and the file picker.
+
+```js
+function setOptions(srcType) {
+    var options = {
+        // Some common settings are 20, 50, and 100
+        quality: 50,
+        destinationType: Camera.DestinationType.FILE_URI,
+        // In this app, dynamically set the picture source, Camera or photo gallery
+        sourceType: srcType,
+        encodingType: Camera.EncodingType.JPEG,
+        mediaType: Camera.MediaType.PICTURE,
+        allowEdit: true,
+        correctOrientation: true  //Corrects Android orientation quirks
+    }
+    return options;
+}
+```
+
+Typically, you want to use a FILE_URI instead of a DATA_URL to avoid most memory issues. JPEG is the recommended encoding type for Android.
+
+You take a picture by passing in the options object to `getPicture`, which takes a CameraOptions object as the third argument. When you call `setOptions`, pass `Camera.PictureSourceType.CAMERA` as the picture source.
+
+```js
+function openCamera(selection) {
+
+    var srcType = Camera.PictureSourceType.CAMERA;
+    var options = setOptions(srcType);
+    var func = createNewFileEntry;
+
+    navigator.camera.getPicture(function cameraSuccess(imageUri) {
+
+        displayImage(imageUri);
+        // You may choose to copy the picture, save it somewhere, or upload.
+        func(imageUri);
+
+    }, function cameraError(error) {
+        console.debug("Unable to obtain picture: " + error, "app");
+
+    }, options);
+}
+```
+
+Once you take the picture, you can display it or do something else. In this example, call the app's `displayImage` function from the preceding code.
+
+```js
+function displayImage(imgUri) {
+
+    var elem = document.getElementById('imageFile');
+    elem.src = imgUri;
+}
+```
+
+To display the image on some platforms, you might need to include the main part of the URI in the Content-Security-Policy `<meta>` element in index.html. For example, on Windows 10, you can include `ms-appdata:` in your `<meta>` element. Here is an example.
+
+```html
+<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: ms-appdata: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *">
+```
+
+## Take a Picture and Return Thumbnails (Resize the Picture) <a name="getThumbnails"></a>
+
+To get smaller images, you can return a resized image by passing both `targetHeight` and `targetWidth` values with your CameraOptions object. In this example, you resize the returned image to fit in a 100px by 100px box (the aspect ratio is maintained, so 100px is either the height or width, whichever is greater in the source).
+
+```js
+function openCamera(selection) {
+
+    var srcType = Camera.PictureSourceType.CAMERA;
+    var options = setOptions(srcType);
+    var func = createNewFileEntry;
+
+    if (selection == "camera-thmb") {
+        options.targetHeight = 100;
+        options.targetWidth = 100;
+    }
+
+    navigator.camera.getPicture(function cameraSuccess(imageUri) {
+
+        // Do something
+
+    }, function cameraError(error) {
+        console.debug("Unable to obtain picture: " + error, "app");
+
+    }, options);
+}
+```
+
+## Select a File from the Picture Library <a name="selectFile"></a>
+
+When selecting a file using the file picker, you also need to set the CameraOptions object. In this example, set the `sourceType` to `Camera.PictureSourceType.SAVEDPHOTOALBUM`. To open the file picker, call `getPicture` just as you did in the previous example, passing in the success and error callbacks along with CameraOptions object.
+
+```js
+function openFilePicker(selection) {
+
+    var srcType = Camera.PictureSourceType.SAVEDPHOTOALBUM;
+    var options = setOptions(srcType);
+    var func = createNewFileEntry;
+
+    navigator.camera.getPicture(function cameraSuccess(imageUri) {
+
+        // Do something
+
+    }, function cameraError(error) {
+        console.debug("Unable to obtain picture: " + error, "app");
+
+    }, options);
+}
+```
+
+## Select an Image and Return Thumbnails (resized images) <a name="getFileThumbnails"></a>
+
+Resizing a file selected with the file picker works just like resizing using the Camera app; set the `targetHeight` and `targetWidth` options.
+
+```js
+function openFilePicker(selection) {
+
+    var srcType = Camera.PictureSourceType.SAVEDPHOTOALBUM;
+    var options = setOptions(srcType);
+    var func = createNewFileEntry;
+
+    if (selection == "picker-thmb") {
+        // To downscale a selected image,
+        // Camera.EncodingType (e.g., JPEG) must match the selected image type.
+        options.targetHeight = 100;
+        options.targetWidth = 100;
+    }
+
+    navigator.camera.getPicture(function cameraSuccess(imageUri) {
+
+        // Do something with image
+
+    }, function cameraError(error) {
+        console.debug("Unable to obtain picture: " + error, "app");
+
+    }, options);
+}
+```
+
+## Take a picture and get a FileEntry Object <a name="convert"></a>
+
+If you want to do something like copy the image to another location, or upload it somewhere using the FileTransfer plugin, you need to get a FileEntry object for the returned picture. To do that, call `window.resolveLocalFileSystemURL` on the file URI returned by the Camera app. If you need to use a FileEntry object, set the `destinationType` to `Camera.DestinationType.FILE_URI` in your CameraOptions object (this is also the default value).
+
+>*Note* You need the [File plugin](https://www.npmjs.com/package/cordova-plugin-file) to call `window.resolveLocalFileSystemURL`.
+
+Here is the call to `window.resolveLocalFileSystemURL`. The image URI is passed to this function from the success callback of `getPicture`. The success handler of `resolveLocalFileSystemURL` receives the FileEntry object.
+
+```js
+function getFileEntry(imgUri) {
+    window.resolveLocalFileSystemURL(imgUri, function success(fileEntry) {
+
+        // Do something with the FileEntry object, like write to it, upload it, etc.
+        // writeFile(fileEntry, imgUri);
+        console.log("got file: " + fileEntry.fullPath);
+        // displayFileData(fileEntry.nativeURL, "Native URL");
+
+    }, function () {
+      // If don't get the FileEntry (which may happen when testing
+      // on some emulators), copy to a new FileEntry.
+        createNewFileEntry(imgUri);
+    });
+}
+```
+
+In the example shown in the preceding code, you call the app's `createNewFileEntry` function if you don't get a valid FileEntry object. The image URI returned from the Camera app should result in a valid FileEntry, but platform behavior on some emulators may be different for files returned from the file picker.
+
+>*Note* To see an example of writing to a FileEntry, see the [File plugin README](https://www.npmjs.com/package/cordova-plugin-file).
+
+The code shown here creates a file in your app's cache (in sandboxed storage) named `tempFile.jpeg`. With the new FileEntry object, you can copy the image to the file or do something else like upload it.
+
+```js
+function createNewFileEntry(imgUri) {
+    window.resolveLocalFileSystemURL(cordova.file.cacheDirectory, function success(dirEntry) {
+
+        // JPEG file
+        dirEntry.getFile("tempFile.jpeg", { create: true, exclusive: false }, function (fileEntry) {
+
+            // Do something with it, like write to it, upload it, etc.
+            // writeFile(fileEntry, imgUri);
+            console.log("got file: " + fileEntry.fullPath);
+            // displayFileData(fileEntry.fullPath, "File copied to");
+
+        }, onErrorCreateFile);
+
+    }, onErrorResolveUrl);
+}
+```

+ 360 - 0
miaomiao/plugins/cordova-plugin-camera/RELEASENOTES.md

xqd
@@ -0,0 +1,360 @@
+<!--
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+# http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+-->
+# Release Notes
+
+### 2.4.0 (Feb 28, 2017)
+* [CB-12501](https://issues.apache.org/jira/browse/CB-12501) **Android**: Appium tests don't use `XPath` selectors anymore
+* [CB-12469](https://issues.apache.org/jira/browse/CB-12469) Appium tests can now run on **iOS 10**
+* [CB-12005](https://issues.apache.org/jira/browse/CB-12005) Changing the `getOrientation` method to return the defined enumerated `EXIF` instead of orientation in degrees for Consistency
+* [CB-12368](https://issues.apache.org/jira/browse/CB-12368) Fix permission check on **Android**
+* [CB-12353](https://issues.apache.org/jira/browse/CB-12353) Corrected merges usage in `plugin.xml`
+* [CB-12369](https://issues.apache.org/jira/browse/CB-12369) Add plugin typings from `DefinitelyTyped`
+* [CB-12363](https://issues.apache.org/jira/browse/CB-12363) Added build badges for **iOS 9.3** and **iOS 10.0**
+* [CB-12312](https://issues.apache.org/jira/browse/CB-12312) [Appium] [Android] A few changes to the tests:  - updated comments on how to run the tests. extra comments around functionality at certain points in the automation.  - stub of a resolution checker on test startup - still need to figure out acceptable values.  - moved session shutdown to an afterAll clause.  - changed resolution determiner from using webview-based values to using the native windows dimensions - this helps as the webview values may be scaled down intentionally by manufacturers (via changing devicePixelRatio). furthermore, since the screen dimension automation is used purely for native UI automation, better to use the dimensions reported by the native context rather than the web context.  - when finding elements by XPath, use multiple calls to avoid a Windows emulator + Android bug. Made this pattern consistent in the entire test.
+* [CB-12236](https://issues.apache.org/jira/browse/CB-12236) - Fixed RELEASENOTES for cordova-plugin-camera
+* [CB-12230](https://issues.apache.org/jira/browse/CB-12230) Removed Windows 8.1 build badges
+
+### 2.3.1 (Dec 07, 2016)
+* [CB-12224](https://issues.apache.org/jira/browse/CB-12224) Updated version and RELEASENOTES.md for release 2.3.1
+* Fix missing license headers.
+* [CB-12086](https://issues.apache.org/jira/browse/CB-12086) Regenerate README.md from template
+* Added NSPhotoLibraryUsageDescription parameter to example install command Fixing some usages of NSPhotoLibraryUsageDescriptionentry
+* Updating compat dependency to 1.1.0 or better
+* [CB-11625](https://issues.apache.org/jira/browse/CB-11625) Forgot to add CordovaUri.java to plugin.xml
+* [CB-11625](https://issues.apache.org/jira/browse/CB-11625) Files Provider does not work with Android 4.4.4 or lower, and I have no idea why.  Working around with CordovaUri
+* [CB-11625](https://issues.apache.org/jira/browse/CB-11625) (Android) : Make this work with previous versions of Cordova via cordova-plugin-compat
+* BuildConfig from test project crept in source code thanks to Android Studio, removing
+* [CB-11625](https://issues.apache.org/jira/browse/CB-11625) Managed to get Content Providers to work with a weird mix of Content Providers and non-Content Providers
+* [CB-11625](https://issues.apache.org/jira/browse/CB-11625) Working on fix to API 24 no longer allowing File URIs to be passed across intents
+* [CB-11917](https://issues.apache.org/jira/browse/CB-11917) - Remove pull request template checklist item: "iCLA has been submitted…"
+* [CB-11832](https://issues.apache.org/jira/browse/CB-11832) Incremented plugin version.
+
+### 2.3.0 (Sep 08, 2016)
+* [CB-11795](https://issues.apache.org/jira/browse/CB-11795) Add 'protective' entry to cordovaDependencies
+* [CB-11661](https://issues.apache.org/jira/browse/CB-11661) Add mandatory **iOS 10** privacy description
+* [CB-11714](https://issues.apache.org/jira/browse/CB-11714) **windows** added more explicit content-type when converting to target data on canvas
+* [CB-11295](https://issues.apache.org/jira/browse/CB-11295) Add **WP8.1** quirk when choosing image from `photoalbum`
+* [CB-10067](https://issues.apache.org/jira/browse/CB-10067) Update `PictureSourceType` JSDoc to reflect `README` update
+* [CB-9070](https://issues.apache.org/jira/browse/CB-9070) Update `CameraPopoverHandle` docs to reflect `README` update
+* Plugin uses `Android Log class` and not `Cordova LOG class`
+* [CB-11631](https://issues.apache.org/jira/browse/CB-11631) Appium tests: A working fix for a flaky `selection canceled` failure
+* [CB-11709](https://issues.apache.org/jira/browse/CB-11709) Tests should use `resolveLocalFileSystemURL()` instead of deprecated `resolveFileSystemURI()`
+* [CB-11695](https://issues.apache.org/jira/browse/CB-11695) Increased session creation timeout for Appium tests
+* [CB-11656](https://issues.apache.org/jira/browse/CB-11656) (**Android**) Appium tests: Fixed side menu opening on some more resolutions
+* [CB-11376](https://issues.apache.org/jira/browse/CB-11376) (**ios**): fix `CameraUsesGeolocation` error
+* [CB-10067](https://issues.apache.org/jira/browse/CB-10067) (**ios**) clarifications on `PictureSourceType`
+* [CB-11410](https://issues.apache.org/jira/browse/CB-11410) (**ios**) fix `cameraPopoverHandle.setPosition`
+* [CB-9070](https://issues.apache.org/jira/browse/CB-9070) (**ios**) Fixed `CameraPopoverHandle` documentation
+* [CB-11447](https://issues.apache.org/jira/browse/CB-11447) Respect output format when retrieving images from gallery
+* [CB-11447](https://issues.apache.org/jira/browse/CB-11447) Resolve **iOS** tests failures due to **iOS** quirks
+* [CB-11553](https://issues.apache.org/jira/browse/CB-11553) Pend failing Appium tests on Sauce Labs for the time being (reverted from commit b69571724035f41642f3ee612c5b66e1f0c4386c)
+* [CB-11553](https://issues.apache.org/jira/browse/CB-11553) Pend failing Appium tests on Sauce Labs for the time being
+* [CB-11498](https://issues.apache.org/jira/browse/CB-11498) [**Android**] Appium tests should not fail when there is no camera
+* Add badges for paramedic builds on Jenkins
+* [CB-11296](https://issues.apache.org/jira/browse/CB-11296) Appium: Better element clicking and session error handling
+* [CB-11232](https://issues.apache.org/jira/browse/CB-11232) Appium tests: fixed element tapping on **iOS 9**
+* [CB-11183](https://issues.apache.org/jira/browse/CB-11183) Appium tests: Added image verification
+* fixed some bad formatting that hid `HTML` tags and added link to sample
+* Set **android** quality default value to 50 on the java code
+* Moving message in PR template to a comment
+* Add pull request template. This closes #213
+* [CB-11228](https://issues.apache.org/jira/browse/CB-11228) **browser**: Add classes for styling purposes
+* [CB-10139](https://issues.apache.org/jira/browse/CB-10139) **browser**: Respect target width and height
+* [CB-11227](https://issues.apache.org/jira/browse/CB-11227) **browser**: Fix incorrect `mime type`
+* [CB-11162](https://issues.apache.org/jira/browse/CB-11162) Appium tests: retry spec on failure
+* [CB-4078](https://issues.apache.org/jira/browse/CB-4078) Fix for `orientation/scaling` on **Android 4.4+** devices
+* [CB-11165](https://issues.apache.org/jira/browse/CB-11165) removed peer dependency
+* [CB-11147](https://issues.apache.org/jira/browse/CB-11147) Appium tests: generate descriptive spec names
+* [CB-10996](https://issues.apache.org/jira/browse/CB-10996) Adding front matter to `README.md`
+* [CB-11128](https://issues.apache.org/jira/browse/CB-11128) Appum tests: Fixed some of the flaky failures
+* [CB-11003](https://issues.apache.org/jira/browse/CB-11003) Added Sample section to the Camera plugin README
+
+### 2.2.0 (Apr 15, 2016)
+* [CB-10873](https://issues.apache.org/jira/browse/CB-10873) Avoid crash due to usage of uninitialized variable when writing geolocation data to image destination. Properly handle 'CameraUsesGeolocation' option by properly setting geolocation data in EXIF header in all cases
+* [CB-11073](https://issues.apache.org/jira/browse/CB-11073) Appium tests stability improvements
+* Replace `PermissionHelper.java` with `cordova-plugin-compat`
+* Making focus handler work only for **windows 10** phone
+* [CB-10865](https://issues.apache.org/jira/browse/CB-10865) Run **ios** native tests on **Travis**
+* [CB-10120](https://issues.apache.org/jira/browse/CB-10120) Fixing use of constants and `PermissionHelper`
+* [CB-10120](https://issues.apache.org/jira/browse/CB-10120) Fix missing CAMERA permission for **Android M**
+* [CB-10756](https://issues.apache.org/jira/browse/CB-10756) Adding sterner warnings about `DATA_URL`
+* [CB-10460](https://issues.apache.org/jira/browse/CB-10460) `getRealPath` return null in some cases
+
+### 2.1.1 (Mar 09, 2016)
+* [CB-10825](https://issues.apache.org/jira/browse/CB-10825) **Android** should request READ permission for gallery source
+* added apache license header to appium files
+* [CB-10720](https://issues.apache.org/jira/browse/CB-10720) Fixed spelling, capitalization, and other small issues.
+* [CB-10414](https://issues.apache.org/jira/browse/CB-10414) Adding focus handler to resume video when user comes back on leaving the app while preview was running
+* Appium tests: adjust swipe distance on **Android**
+* [CB-10750](https://issues.apache.org/jira/browse/CB-10750) Appium tests: fail fast if session is irrecoverable
+* Adding missing semi colon
+* Adding focus handler to make sure filepicker gets launched when app is active on **Windows**
+* [CB-10128](https://issues.apache.org/jira/browse/CB-10128) **iOS** Fixed how checks access authorization to camera & library. This closes #146
+* [CB-10636](https://issues.apache.org/jira/browse/CB-10636) Add JSHint for plugins
+* [CB-10639](https://issues.apache.org/jira/browse/CB-10639) Appium tests: Added some timeouts, Taking a screenshot on failure, Retry taking a picture up to 3 times, Try to restart the Appium session if it's lost
+* [CB-10552](https://issues.apache.org/jira/browse/CB-10552) Replacing images in README.md.
+* Added a lot of more cases to get the real path on **Android** 
+* [CB-10625](https://issues.apache.org/jira/browse/CB-10625) **Android** getPicture fails when getting a photo from the Photo Library - Google Photos
+* [CB-10619](https://issues.apache.org/jira/browse/CB-10619) Appium tests: Properly switch to webview on **Android**
+* [CB-10397](https://issues.apache.org/jira/browse/CB-10397) Added Appium tests
+* [CB-10576](https://issues.apache.org/jira/browse/CB-10576) MobileSpec can't get results for **Windows**-Store 8.1 Builds
+* chore: edit package.json license to match SPDX id
+* [CB-10539](https://issues.apache.org/jira/browse/CB-10539) Commenting out the verySmallQvga maxResolution option on **Windows**
+* [CB-10541](https://issues.apache.org/jira/browse/CB-10541) Changing default maxResoltion to be highestAvailable for CameraCaptureUI on **Windows**
+* [CB-10113](https://issues.apache.org/jira/browse/CB-10113) **Browse** - Layer camera UI on top of all! 
+* [CB-10502](https://issues.apache.org/jira/browse/CB-10502) **Browser** - Fix camera plugin exception in Chrome when click capture.
+* Adding comments
+* Camera tapping fix on **Windows**
+
+### 2.1.0 (Jan 15, 2016)
+* added `.ratignore`
+* [CB-10319](https://issues.apache.org/jira/browse/CB-10319) **Android** Adding reflective helper methods for permission requests
+* [CB-9189](https://issues.apache.org/jira/browse/CB-9189) **Android** Implementing `save/restore` API to handle Activity destruction
+* [CB-10241](https://issues.apache.org/jira/browse/CB-10241) App Crash cause by Camera Plugin **iOS 7**
+* [CB-8940](https://issues.apache.org/jira/browse/CB-8940) Setting `z-index` values to maximum for UI buttons.
+
+### 2.0.0 (Nov 18, 2015)
+* [CB-10035](https://issues.apache.org/jira/browse/CB-10035) Updated `RELEASENOTES` to be newest to oldest
+* [CB-8863](https://issues.apache.org/jira/browse/CB-8863) correct block usage for `async` calls
+* [CB-5479](https://issues.apache.org/jira/browse/CB-5479) changed `saveToPhotoAlbum` to save uncompressed images for **Android**
+* [CB-9169](https://issues.apache.org/jira/browse/CB-9169) Fixed `filetype` for uncompressed images and added quirk for **Android**
+* [CB-9446](https://issues.apache.org/jira/browse/CB-9446) Removing `CordovaResource` library code in favour of the code we're supposed to be deprecating because that at least works.
+* [CB-9942](https://issues.apache.org/jira/browse/CB-9942) Normalize line endings in Camera plugin docs
+* [CB-9910](https://issues.apache.org/jira/browse/CB-9910) Add permission request for some gallery requests for **Android**
+* [CB-7668](https://issues.apache.org/jira/browse/CB-7668) Adding a sterner warning for `allowedit` on **Android**
+* Fixing contribute link.
+* Using the `CordovaResourceApi` to fine paths of files in the background thread.  If the file doesn't exist, return the content `URI`. 
+* Add engine tag for **Cordova-Android 5.0.x**
+* [CB-9583](https://issues.apache.org/jira/browse/CB-9583): Added support for **Marshmallow** permissions (**Android 6.0**)
+* Try to use `realpath` filename instead of default `modified.jpg`
+* [CB-6190](https://issues.apache.org/jira/browse/CB-6190) **iOS** camera plugin ignores quality parameter
+* [CB-9633](https://issues.apache.org/jira/browse/CB-9633) **iOS** Taking a Picture With Option `destinationType:NATIVE_URI` doesn't show image
+* [CB-9745](https://issues.apache.org/jira/browse/CB-9745) Camera plugin docs should be generated from the source
+* [CB-9622](https://issues.apache.org/jira/browse/CB-9622) **WP8** Camera Option `destinationType:NATIVE_URI` is a `NO-OP`
+* [CB-9623](https://issues.apache.org/jira/browse/CB-9623) Fixes various issues when `encodingType` set to `png`
+* [CB-9591](https://issues.apache.org/jira/browse/CB-9591) Retaining aspect ratio when resizing
+* [CB-9443](https://issues.apache.org/jira/browse/CB-9443) Pick correct `maxResolution` 
+* [CB-9151](https://issues.apache.org/jira/browse/CB-9151) Trigger `captureAction` only once
+* [CB-9413](https://issues.apache.org/jira/browse/CB-9413) Close `RandomAccessStream` once copied
+* [CB-5661](https://issues.apache.org/jira/browse/CB-5661) Remove outdated **iOS** quirks about memory
+* [CB-9349](https://issues.apache.org/jira/browse/CB-9349) Focus control and nice UI
+* [CB-9259](https://issues.apache.org/jira/browse/CB-9259) Forgot to add another check on which `URI` we're using when fixing this thing the first time
+* [CB-9247](https://issues.apache.org/jira/browse/CB-9247) Added macro to conditionally add `NSData+Base64.h`
+* [CB-9247](https://issues.apache.org/jira/browse/CB-9247) Fixes compilation errors with **cordova-ios 4.x**
+* Fix returning native url on **Windows**.
+
+### 1.2.0 (Jun 17, 2015)
+* Closing stale pull request: close #84
+* Closing stale pull request: close #66
+* [CB-9128](https://issues.apache.org/jira/browse/CB-9128) cordova-plugin-camera documentation translation: cordova-plugin-camera
+* Update docs. This closes #100
+* attempt to fix npm markdown issue
+* [CB-8883](https://issues.apache.org/jira/browse/CB-8883) fix picture rotation issue
+* one more alias
+* Fixed some nit white-space issues, aliased a little more
+* major refactor : readability
+* Patch for [CB-8498](https://issues.apache.org/jira/browse/CB-8498), this closes #64
+* [CB-8879](https://issues.apache.org/jira/browse/CB-8879) fix stripe issue with correct aspect ratio
+* [CB-8601](https://issues.apache.org/jira/browse/CB-8601) - iOS camera unit tests broken
+* [CB-7667](https://issues.apache.org/jira/browse/CB-7667) iOS8: Handle case where camera is not authorized (closes #49)
+* add missing license header
+
+### 1.1.0 (May 06, 2015)
+* [CB-8943](https://issues.apache.org/jira/browse/CB-8943) fix `PickAndContinue` issue on *Win10Phone*
+* [CB-8253](https://issues.apache.org/jira/browse/CB-8253) Fix potential unreleased resources
+* [CB-8909](https://issues.apache.org/jira/browse/CB-8909): Remove unused import from File
+* [CB-8404](https://issues.apache.org/jira/browse/CB-8404) typo fix `cameraproxy.js`
+* [CB-8404](https://issues.apache.org/jira/browse/CB-8404) Rotate camera feed with device orientation
+* [CB-8054](https://issues.apache.org/jira/browse/CB-8054) Support taking pictures from file for *WP8*
+* [CB-8405](https://issues.apache.org/jira/browse/CB-8405) Use `z-index` instead of `z-order`
+
+### 1.0.0 (Apr 15, 2015)
+* [CB-8780](https://issues.apache.org/jira/browse/CB-8780) - Display popover using main thread. Fixes popover slowness (closes #81)
+* [CB-8746](https://issues.apache.org/jira/browse/CB-8746) bumped version of file dependency
+* [CB-8746](https://issues.apache.org/jira/browse/CB-8746) gave plugin major version bump
+* [CB-8707](https://issues.apache.org/jira/browse/CB-8707) refactoring windows code to improve readability
+* [CB-8706](https://issues.apache.org/jira/browse/CB-8706) use filePicker if saveToPhotoAlbum is true
+* [CB-8706](https://issues.apache.org/jira/browse/CB-8706) remove unnecessary capabilities from xml
+* [CB-8747](https://issues.apache.org/jira/browse/CB-8747) updated dependency, added peer dependency
+* [CB-8683](https://issues.apache.org/jira/browse/CB-8683) updated blackberry specific references of org.apache.cordova.camera to cordova-plugin-camera
+* [CB-8782](https://issues.apache.org/jira/browse/CB-8782): Updated the docs to talk about the allowEdit quirks, it's not 100% working, but better than it was
+* [CB-8782](https://issues.apache.org/jira/browse/CB-8782): Fixed the flow so that we save the cropped image and use it, not the original non-cropped.  Crop only supports G+ Photos Crop, other crops may not work, depending on the OEM
+* [CB-8740](https://issues.apache.org/jira/browse/CB-8740): Removing FileHelper call that was failing on Samsung Galaxy S3, now that we have a real path, we only need to update the MediaStore, not pull from it in this case
+* [CB-8740](https://issues.apache.org/jira/browse/CB-8740): Partial fix for Save Image to Gallery error found in MobileSpec
+* [CB-8683](https://issues.apache.org/jira/browse/CB-8683) changed plugin-id to pacakge-name
+* [CB-8653](https://issues.apache.org/jira/browse/CB-8653) properly updated translated docs to use new id
+* [CB-8653](https://issues.apache.org/jira/browse/CB-8653) updated translated docs to use new id
+* [CB-8351](https://issues.apache.org/jira/browse/CB-8351) Fix custom implementation of integerValueForKey (close #79)
+* Fix cordova-paramedic path change, build with TRAVIS_BUILD_DIR, use npm to install paramedic
+* docs: added 'Windows' to supported platforms
+* [CB-8653](https://issues.apache.org/jira/browse/CB-8653) Updated Readme
+* [CB-8659](https://issues.apache.org/jira/browse/CB-8659): ios: 4.0.x Compatibility: Remove use of deprecated headers
+
+### 0.3.6 (Mar 10, 2015)
+* Fix localize key for Videos. This closes #58
+* [CB-8235](https://issues.apache.org/jira/browse/CB-8235) android: Fix crash when selecting images from DropBox with spaces in path (close #65)
+* add try ... catch for getting image orientation
+* [CB-8599](https://issues.apache.org/jira/browse/CB-8599) fix threading issue with cameraPicker (fixes #72)
+* [CB-8559](https://issues.apache.org/jira/browse/CB-8559) Integrate TravisCI
+* [CB-8438](https://issues.apache.org/jira/browse/CB-8438) cordova-plugin-camera documentation translation: cordova-plugin-camera
+* [CB-8538](https://issues.apache.org/jira/browse/CB-8538) Added package.json file
+
+### 0.3.5 (Feb 04, 2015)
+* [CB-8351](https://issues.apache.org/jira/browse/CB-8351) ios: Stop using now-deprecated [NSData base64EncodedString]
+* [CB-8351](https://issues.apache.org/jira/browse/CB-8351) ios: Stop using now-deprecated integerValueForKey: class extension
+* [CB-8351](https://issues.apache.org/jira/browse/CB-8351) ios: Use argumentForIndex rather than NSArray extension
+* [CB-8032](https://issues.apache.org/jira/browse/CB-8032) ios: Add nativeURL external method support for CDVFileSystem->makeEntryForPath:isDirectory:
+* [CB-7938](https://issues.apache.org/jira/browse/CB-7938) ios: Added XCTest unit tests project, with stubs (adapted from SplashScreen unit test setup)
+* [CB-7937](https://issues.apache.org/jira/browse/CB-7937) ios: Re-factor iOS Camera plugin so that it is testable
+
+### 0.3.4 (Dec 02, 2014)
+* [CB-7977](https://issues.apache.org/jira/browse/CB-7977) Mention `deviceready` in plugin docs
+* [CB-7979](https://issues.apache.org/jira/browse/CB-7979) Each plugin doc should have a ## Installation section
+* Fix memory leak of image data in `imagePickerControllerReturnImageResult`
+* Pass uri to crop instead of pulling the low resolution image out of the intent return (close #43)
+* Add orientation support for PNG to Android (closes #45)
+* [CB-7700](https://issues.apache.org/jira/browse/CB-7700) cordova-plugin-camera documentation translation: cordova-plugin-camera
+
+### 0.3.3 (Oct 03, 2014)
+* [CB-7600](https://issues.apache.org/jira/browse/CB-7600) Adds informative message to error callback in manual test.
+
+### 0.3.2 (Sep 17, 2014)
+* [CB-7551](https://issues.apache.org/jira/browse/CB-7551) [Camera][iOS 8] Scaled images show a white line
+* [CB-7558](https://issues.apache.org/jira/browse/CB-7558) hasPendingOperation flag in Camera plugin's takePicture should be reversed to fix memory errors
+* [CB-7557](https://issues.apache.org/jira/browse/CB-7557) Camera plugin tests is missing a File dependency
+* [CB-7423](https://issues.apache.org/jira/browse/CB-7423) do cleanup after copyImage manual test
+* [CB-7471](https://issues.apache.org/jira/browse/CB-7471) cordova-plugin-camera documentation translation: cordova-plugin-camera
+* [CB-7413](https://issues.apache.org/jira/browse/CB-7413) Resolve 'ms-appdata' URIs with File plugin
+* Fixed minor bugs with the browser
+* [CB-7433](https://issues.apache.org/jira/browse/CB-7433) Adds missing window reference to prevent manual tests failure on Android and iOS
+* [CB-7249](https://issues.apache.org/jira/browse/CB-7249) cordova-plugin-camera documentation translation: cordova-plugin-camera
+* [CB-4003](https://issues.apache.org/jira/browse/CB-4003) Add config option to not use location information in Camera plugin (and default to not use it)
+* [CB-7461](https://issues.apache.org/jira/browse/CB-7461) Geolocation fails in Camera plugin in iOS 8
+* [CB-7378](https://issues.apache.org/jira/browse/CB-7378) Use single Proxy for both windows8 and windows.
+* [CB-7378](https://issues.apache.org/jira/browse/CB-7378) Adds support for windows platform
+* [CB-7433](https://issues.apache.org/jira/browse/CB-7433) Fixes manual tests failure on windows
+* [CB-6958](https://issues.apache.org/jira/browse/CB-6958) Get the correct default for "quality" in the test
+* add documentation for manual tests
+* [CB-7249](https://issues.apache.org/jira/browse/CB-7249) cordova-plugin-camera documentation translation: cordova-plugin-camera
+* [CB-4003](https://issues.apache.org/jira/browse/CB-4003) Add config option to not use location information in Camera plugin (and default to not use it)
+* [CB-7461](https://issues.apache.org/jira/browse/CB-7461) Geolocation fails in Camera plugin in iOS 8
+* [CB-7433](https://issues.apache.org/jira/browse/CB-7433) Fixes manual tests failure on windows
+* [CB-7378](https://issues.apache.org/jira/browse/CB-7378) Use single Proxy for both windows8 and windows.
+* [CB-7378](https://issues.apache.org/jira/browse/CB-7378) Adds support for windows platform
+* [CB-6958](https://issues.apache.org/jira/browse/CB-6958) Get the correct default for "quality" in the test
+* add documentation for manual tests
+* Updated docs for browser
+* Added support for the browser
+* [CB-7286](https://issues.apache.org/jira/browse/CB-7286) [BlackBerry10] Use getUserMedia if camera card is unavailable
+* [CB-7180](https://issues.apache.org/jira/browse/CB-7180) Update Camera plugin to support generic plugin webView UIView (which can be either a UIWebView or WKWebView)
+* Renamed test dir, added nested plugin.xml
+* [CB-6958](https://issues.apache.org/jira/browse/CB-6958) added manual tests
+* [CB-6958](https://issues.apache.org/jira/browse/CB-6958) Port camera tests to plugin-test-framework
+
+### 0.3.1 (Aug 06, 2014)
+* **FFOS** update CameraProxy.js
+* [CB-7187](https://issues.apache.org/jira/browse/CB-7187) ios: Add explicit dependency on CoreLocation.framework
+* [BlackBerry10] Doc correction - sourceType is supported
+* [CB-7071](https://issues.apache.org/jira/browse/CB-7071) android: Fix callback firing before CROP intent is sent when allowEdit=true
+* [CB-6875](https://issues.apache.org/jira/browse/CB-6875) android: Handle exception when SDCard is not mounted
+* ios: Delete postImage (dead code)
+* Prevent NPE on processResiultFromGallery when intent comes null
+* Remove iOS doc reference to non-existing navigator.fileMgr API
+* Docs updated with some default values
+* Removes File plugin dependency from windows8 code.
+* Use WinJS functionality to resize image instead of File plugin functionality
+* [CB-6127](https://issues.apache.org/jira/browse/CB-6127) Updated translations for docs
+
+### 0.3.0 (Jun 05, 2014)
+* [CB-5895](https://issues.apache.org/jira/browse/CB-5895) documented saveToPhotoAlbum quirk on WP8
+* Remove deprecated symbols for iOS < 6
+* documentation translation: cordova-plugin-camera
+* ubuntu: use application directory for images
+* [CB-6795](https://issues.apache.org/jira/browse/CB-6795) Add license
+* Little fix in code formatting
+* [CB-6613](https://issues.apache.org/jira/browse/CB-6613) Use WinJS functionality to get base64-encoded content of image instead of File plugin functionality
+* [CB-6612](https://issues.apache.org/jira/browse/CB-6612) camera.getPicture now always returns encoded JPEG image
+* Removed invalid note from [CB-5398](https://issues.apache.org/jira/browse/CB-5398)
+* [CB-6576](https://issues.apache.org/jira/browse/CB-6576) - Returns a specific error message when app has no access to library.
+* [CB-6491](https://issues.apache.org/jira/browse/CB-6491) add CONTRIBUTING.md
+* [CB-6546](https://issues.apache.org/jira/browse/CB-6546) android: Fix a couple bugs with allowEdit pull request
+* [CB-6546](https://issues.apache.org/jira/browse/CB-6546) android: Add support for allowEdit Camera option
+
+### 0.2.9 (Apr 17, 2014)
+* [CB-6460](https://issues.apache.org/jira/browse/CB-6460): Update license headers
+* [CB-6422](https://issues.apache.org/jira/browse/CB-6422): [windows8] use cordova/exec/proxy
+* [WP8] When only targetWidth or targetHeight is provided, use it as the only bound
+* [CB-4027](https://issues.apache.org/jira/browse/CB-4027), [CB-5102](https://issues.apache.org/jira/browse/CB-5102), [CB-2737](https://issues.apache.org/jira/browse/CB-2737), [CB-2387](https://issues.apache.org/jira/browse/CB-2387): [WP] Fix camera issues, cropping, memory leaks
+* [CB-6212](https://issues.apache.org/jira/browse/CB-6212): [iOS] fix warnings compiled under arm64 64-bit
+* [BlackBerry10] Add rim xml namespaces declaration
+* Add NOTICE file
+
+### 0.2.8 (Feb 26, 2014)
+* [CB-1826](https://issues.apache.org/jira/browse/CB-1826) Catch OOM on gallery image resize
+
+### 0.2.7 (Feb 05, 2014)
+* [CB-4919](https://issues.apache.org/jira/browse/CB-4919) firefox os quirks added and supported platforms list is updated
+* getPicture via web activities
+* Documented quirk for [CB-5335](https://issues.apache.org/jira/browse/CB-5335) + [CB-5206](https://issues.apache.org/jira/browse/CB-5206) for WP7+8
+* reference the correct firefoxos implementation
+* [BlackBerry10] Add permission to access_shared
+
+### 0.2.6 (Jan 02, 2014)
+* [CB-5658](https://issues.apache.org/jira/browse/CB-5658) Add doc/index.md for Camera plugin
+* [CB-2442](https://issues.apache.org/jira/browse/CB-2442) [CB-2419](https://issues.apache.org/jira/browse/CB-2419) Use Windows.Storage.ApplicationData.current.localFolder, instead of writing to app package.
+* [BlackBerry10] Adding platform level permissions
+* [CB-5599](https://issues.apache.org/jira/browse/CB-5599) Android: Catch and ignore OutOfMemoryError in getRotatedBitmap()
+
+### 0.2.5 (Dec 4, 2013)
+* fix camera for firefox os
+* getPicture via web activities
+* [ubuntu] specify policy_group
+* add ubuntu platform
+* 1. User Agent detection now detects AmazonWebView. 2. Change to use amazon-fireos as the platform if user agent string contains 'cordova-amazon-fireos'
+* Added amazon-fireos platform.
+
+### 0.2.4 (Oct 28, 2013)
+* [CB-5128](https://issues.apache.org/jira/browse/CB-5128): added repo + issue tag to plugin.xml for camera plugin
+* [CB-4958](https://issues.apache.org/jira/browse/CB-4958) - iOS - Camera plugin should not show the status bar
+* [CB-4919](https://issues.apache.org/jira/browse/CB-4919) updated plugin.xml for FxOS
+* [CB-4915](https://issues.apache.org/jira/browse/CB-4915) Incremented plugin version on dev branch.
+
+### 0.2.3 (Sept 25, 2013)
+* [CB-4889](https://issues.apache.org/jira/browse/CB-4889) bumping&resetting version
+* [CB-4889](https://issues.apache.org/jira/browse/CB-4889) forgot index.html
+* [CB-4889](https://issues.apache.org/jira/browse/CB-4889) renaming core inside cameraProxy
+* [Windows8] commandProxy has moved
+* [Windows8] commandProxy has moved
+* added Camera API for FirefoxOS
+* Rename CHANGELOG.md -> RELEASENOTES.md
+* [CB-4823](https://issues.apache.org/jira/browse/CB-4823) Fix XCode 5 camera plugin warnings
+* Fix compiler warnings
+* [CB-4765](https://issues.apache.org/jira/browse/CB-4765) Move ExifHelper.java into Camera Plugin
+* [CB-4764](https://issues.apache.org/jira/browse/CB-4764) Remove reference to DirectoryManager from CameraLauncher
+* [CB-4763](https://issues.apache.org/jira/browse/CB-4763) Use a copy of FileHelper.java within camera-plugin.
+* [CB-4752](https://issues.apache.org/jira/browse/CB-4752) Incremented plugin version on dev branch.
+* [CB-4633](https://issues.apache.org/jira/browse/CB-4633): We really should close cursors.  It's just the right thing to do.
+* No longer causes a stack trace, but it doesn't cause the error to be called.
+* [CB-4889](https://issues.apache.org/jira/browse/CB-4889) renaming org.apache.cordova.core.camera to org.apache.cordova.camera
+
+### 0.2.1 (Sept 5, 2013)
+* [CB-4656](https://issues.apache.org/jira/browse/CB-4656) Don't add line-breaks to base64-encoded images (Fixes type=DataURI)
+* [CB-4432](https://issues.apache.org/jira/browse/CB-4432) copyright notice change

+ 628 - 0
miaomiao/plugins/cordova-plugin-camera/appium-tests/android/android.spec.js

xqd
@@ -0,0 +1,628 @@
+/*jshint node: true, jasmine: true */
+
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+// these tests are meant to be executed by Cordova ParaMedic Appium runner
+// you can find it here: https://github.com/apache/cordova-paramedic/
+// it is not necessary to do a full CI setup to run these tests
+// Run:
+//      node cordova-paramedic/main.js --platform android --plugin cordova-plugin-camera --skipMainTests --target <emulator name>
+// Please note only Android 5.1 and 4.4 are supported at this point.
+
+'use strict';
+
+var wdHelper = global.WD_HELPER;
+var screenshotHelper = global.SCREENSHOT_HELPER;
+var wd = wdHelper.getWD();
+var cameraConstants = require('../../www/CameraConstants');
+var cameraHelper = require('../helpers/cameraHelper');
+
+var MINUTE = 60 * 1000;
+var BACK_BUTTON = 4;
+var DEFAULT_SCREEN_WIDTH = 360;
+var DEFAULT_SCREEN_HEIGHT = 567;
+var DEFAULT_WEBVIEW_CONTEXT = 'WEBVIEW';
+var PROMISE_PREFIX = 'appium_camera_promise_';
+var CONTEXT_NATIVE_APP = 'NATIVE_APP';
+
+describe('Camera tests Android.', function () {
+    var driver;
+    // the name of webview context, it will be changed to match needed context if there are named ones:
+    var webviewContext = DEFAULT_WEBVIEW_CONTEXT;
+    // this indicates that the device library has the test picture:
+    var isTestPictureSaved = false;
+    // we need to know the screen width and height to properly click on an image in the gallery:
+    var screenWidth = DEFAULT_SCREEN_WIDTH;
+    var screenHeight = DEFAULT_SCREEN_HEIGHT;
+    // promise count to use in promise ID
+    var promiseCount = 0;
+    // determine if Appium session is created successfully
+    var appiumSessionStarted = false;
+    // determine if camera is present on the device/emulator
+    var cameraAvailable = false;
+    // determine if emulator is within a range of acceptable resolutions able to run these tests
+    var isResolutionBad = true;
+    // a path to the image we add to the gallery before test run
+    var fillerImagePath;
+
+    function getNextPromiseId() {
+        promiseCount += 1;
+        return getCurrentPromiseId();
+    }
+
+    function getCurrentPromiseId() {
+        return PROMISE_PREFIX + promiseCount;
+    }
+
+    function gracefullyFail(error) {
+        fail(error);
+        return driver
+            .quit()
+            .then(function () {
+                return getDriver();
+            });
+    }
+
+    // combinines specified options in all possible variations
+    // you can add more options to test more scenarios
+    function generateOptions() {
+        var sourceTypes = [
+                cameraConstants.PictureSourceType.CAMERA,
+                cameraConstants.PictureSourceType.PHOTOLIBRARY
+            ];
+        var destinationTypes = cameraConstants.DestinationType;
+        var encodingTypes = cameraConstants.EncodingType;
+        var allowEditOptions = [ true, false ];
+        var correctOrientationOptions = [ true, false ];
+
+        return cameraHelper.generateSpecs(sourceTypes, destinationTypes, encodingTypes, allowEditOptions, correctOrientationOptions);
+    }
+
+    // invokes Camera.getPicture() with the specified options
+    // and goes through all UI interactions unless 'skipUiInteractions' is true
+    function getPicture(options, skipUiInteractions) {
+        var promiseId = getNextPromiseId();
+        if (!options) {
+            options = {};
+        }
+
+        return driver
+            .context(webviewContext)
+            .execute(cameraHelper.getPicture, [options, promiseId])
+            .context(CONTEXT_NATIVE_APP)
+            .then(function () {
+                if (skipUiInteractions) {
+                    return;
+                }
+                // selecting a picture from gallery
+                if (options.hasOwnProperty('sourceType') &&
+                        (options.sourceType === cameraConstants.PictureSourceType.PHOTOLIBRARY ||
+                        options.sourceType === cameraConstants.PictureSourceType.SAVEDPHOTOALBUM)) {
+                    var tapTile = new wd.TouchAction();
+                    var swipeRight = new wd.TouchAction();
+                    tapTile
+                        .tap({
+                            x: Math.round(screenWidth / 4),
+                            y: Math.round(screenHeight / 4)
+                        });
+                    swipeRight
+                        .press({x: 10, y: Math.round(screenHeight / 4)})
+                        .wait(300)
+                        .moveTo({x: Math.round(screenWidth - (screenWidth / 8)), y: 0})
+                        .wait(1500)
+                        .release()
+                        .wait(1000);
+                    if (options.allowEdit) {
+                        return driver
+                            // always wait before performing touchAction
+                            .sleep(7000)
+                            .performTouchAction(tapTile);
+                    }
+                    return driver
+                        .waitForElementByAndroidUIAutomator('new UiSelector().text("Gallery");', 20000)
+                        .fail(function () {
+                            // If the Gallery button is not present, swipe right to reveal the Gallery button!
+                            return driver
+                                .performTouchAction(swipeRight)
+                                .waitForElementByAndroidUIAutomator('new UiSelector().text("Gallery");', 20000)
+                        })
+                        .click()
+                        // always wait before performing touchAction
+                        .sleep(7000)
+                        .performTouchAction(tapTile);
+                }
+                // taking a picture from camera
+                return driver
+                    .waitForElementByAndroidUIAutomator('new UiSelector().resourceIdMatches(".*shutter.*")', MINUTE / 2)
+                    .click()
+                    .waitForElementByAndroidUIAutomator('new UiSelector().resourceIdMatches(".*done.*")', MINUTE / 2)
+                    .click();
+            })
+            .then(function () {
+                if (skipUiInteractions) {
+                    return;
+                }
+                if (options.allowEdit) {
+                    return driver
+                        .waitForElementByAndroidUIAutomator('new UiSelector().text("Save")', MINUTE)
+                        .click();
+                }
+            })
+            .fail(function (failure) {
+                throw failure;
+            });
+    }
+
+    // checks if the picture was successfully taken
+    // if shouldLoad is falsy, ensures that the error callback was called
+    function checkPicture(shouldLoad, options) {
+        if (!options) {
+            options = {};
+        }
+        return driver
+            .context(webviewContext)
+            .setAsyncScriptTimeout(MINUTE / 2)
+            .executeAsync(cameraHelper.checkPicture, [getCurrentPromiseId(), options])
+            .then(function (result) {
+                if (shouldLoad) {
+                    if (result !== 'OK') {
+                        fail(result);
+                    }
+                } else if (result.indexOf('ERROR') === -1) {
+                    throw 'Unexpected success callback with result: ' + result;
+                }
+            });
+    }
+
+    // deletes the latest image from the gallery
+    function deleteImage() {
+        var holdTile = new wd.TouchAction();
+        holdTile
+            .press({x: Math.round(screenWidth / 4), y: Math.round(screenHeight / 5)})
+            .wait(1000)
+            .release();
+        return driver
+            // always wait before performing touchAction
+            .sleep(7000)
+            .performTouchAction(holdTile)
+            .elementByAndroidUIAutomator('new UiSelector().text("Delete")')
+            .then(function (element) {
+                return element
+                    .click()
+                    .elementByAndroidUIAutomator('new UiSelector().text("OK")')
+                    .click();
+            }, function () {
+                // couldn't find Delete menu item. Possibly there is no image.
+                return driver;
+            });
+    }
+
+    function getDriver() {
+        driver = wdHelper.getDriver('Android');
+        return driver.getWebviewContext()
+            .then(function(context) {
+                webviewContext = context;
+                return driver.context(webviewContext);
+            })
+            .waitForDeviceReady()
+            .injectLibraries()
+            .deleteFillerImage(fillerImagePath)
+            .then(function () {
+                fillerImagePath = null;
+            })
+            .addFillerImage()
+            .then(function (result) {
+                if (result && result.indexOf('ERROR:') === 0) {
+                    throw new Error(result);
+                } else {
+                    fillerImagePath = result;
+                }
+            });
+    }
+
+    function recreateSession() {
+        return driver
+            .quit()
+            .finally(function () {
+                return getDriver();
+            });
+    }
+
+    function tryRunSpec(spec) {
+        return driver
+            .then(spec)
+            .fail(function () {
+                return recreateSession()
+                    .then(spec)
+                    .fail(function() {
+                        return recreateSession()
+                            .then(spec);
+                    });
+            })
+            .fail(gracefullyFail);
+    }
+
+    // produces a generic spec function which
+    // takes a picture with specified options
+    // and then verifies it
+    function generateSpec(options) {
+        return function () {
+            return driver
+                .then(function () {
+                    return getPicture(options);
+                })
+                .then(function () {
+                    return checkPicture(true, options);
+                });
+        };
+    }
+
+    function checkSession(done, skipResolutionCheck) {
+        if (!appiumSessionStarted) {
+            fail('Failed to start a session ' + (lastFailureReason ? lastFailureReason : ''));
+            done();
+        }
+        if (!skipResolutionCheck && isResolutionBad) {
+            fail('The resolution of this target device is not within the appropriate range of width: blah-blah and height: bleh-bleh. The target\'s current resolution is: ' + isResolutionBad);
+        }
+    }
+
+    function checkCamera(pending) {
+        if (!cameraAvailable) {
+            pending('This test requires a functioning camera on the Android device/emulator, and this test suite\'s functional camera test failed on your target environment.');
+        }
+    }
+    afterAll(function (done) {
+        checkSession(done);
+        driver
+            .quit()
+            .done(done);
+    }, MINUTE);
+
+    it('camera.ui.util configuring driver and starting a session', function (done) {
+        getDriver()
+            .then(function () {
+                appiumSessionStarted = true;
+            }, fail)
+            .done(done);
+    }, 10 * MINUTE);
+
+    it('camera.ui.util determine screen dimensions', function (done) {
+        checkSession(done, /*skipResolutionCheck?*/ true); // skip the resolution check here since we are about to find out in this spec!
+        driver
+            .context(CONTEXT_NATIVE_APP)
+            .getWindowSize()
+            .then(function (size) {
+                screenWidth = Number(size.width);
+                screenHeight = Number(size.height);
+                isResolutionBad = false;
+                /*
+                TODO: what are acceptable resolution values?
+                need to check what the emulators used in CI return.
+                and also what local device definitions work and dont
+                */
+            })
+            .done(done);
+    }, MINUTE);
+
+    it('camera.ui.util determine camera availability', function (done) {
+        checkSession(done);
+        var opts = {
+            sourceType: cameraConstants.PictureSourceType.CAMERA,
+            saveToPhotoAlbum: false
+        };
+
+        return driver
+            .then(function () {
+                return getPicture(opts);
+            })
+            .then(function () {
+                cameraAvailable = true;
+            }, function () {
+                return recreateSession();
+            })
+            .done(done);
+    }, 5 * MINUTE);
+
+    describe('Specs.', function () {
+        // getPicture() with saveToPhotoLibrary = true
+        it('camera.ui.spec.1 Saving a picture to the photo library', function (done) {
+            checkSession(done);
+            checkCamera(pending);
+            var spec = generateSpec({
+                quality: 50,
+                allowEdit: false,
+                sourceType: cameraConstants.PictureSourceType.CAMERA,
+                saveToPhotoAlbum: true
+            });
+
+            tryRunSpec(spec)
+                .then(function () {
+                    isTestPictureSaved = true;
+                })
+                .done(done);
+        }, 10 * MINUTE);
+
+        // getPicture() with mediaType: VIDEO, sourceType: PHOTOLIBRARY
+        it('camera.ui.spec.2 Selecting only videos', function (done) {
+            checkSession(done);
+            var spec = function () {
+                var options = { sourceType: cameraConstants.PictureSourceType.PHOTOLIBRARY,
+                                mediaType: cameraConstants.MediaType.VIDEO };
+                return driver
+                    .then(function () {
+                        return getPicture(options, true);
+                    })
+                    .context(CONTEXT_NATIVE_APP)
+                    .then(function () {
+                        // try to find "Gallery" menu item
+                        // if there's none, the gallery should be already opened
+                        return driver
+                            .waitForElementByAndroidUIAutomator('new UiSelector().text("Gallery")', 20000)
+                            .then(function (element) {
+                                return element.click();
+                            }, function () {
+                                return driver;
+                            });
+                    })
+                    .then(function () {
+                        // if the gallery is opened on the videos page,
+                        // there should be a "Choose video" caption
+                        return driver
+                            .elementByAndroidUIAutomator('new UiSelector().text("Choose video")')
+                            .fail(function () {
+                                throw 'Couldn\'t find "Choose video" element.';
+                            });
+                    })
+                    .deviceKeyEvent(BACK_BUTTON)
+                    .elementByAndroidUIAutomator('new UiSelector().text("Gallery")')
+                    .deviceKeyEvent(BACK_BUTTON)
+                    .finally(function () {
+                        return driver
+                            .elementById('action_bar_title')
+                            .then(function () {
+                                // success means we're still in native app
+                                return driver
+                                    .deviceKeyEvent(BACK_BUTTON)
+                                    // give native app some time to close
+                                    .sleep(2000)
+                                    // try again! because every ~30th build
+                                    // on Sauce Labs this backbutton doesn't work
+                                    .elementById('action_bar_title')
+                                    .then(function () {
+                                        // success means we're still in native app
+                                        return driver
+                                            .deviceKeyEvent(BACK_BUTTON);
+                                        }, function () {
+                                            // error means we're already in webview
+                                            return driver;
+                                        });
+                            }, function () {
+                                // error means we're already in webview
+                                return driver;
+                            });
+                    });
+            };
+            tryRunSpec(spec).done(done);
+        }, 10 * MINUTE);
+
+        // getPicture(), then dismiss
+        // wait for the error callback to be called
+        it('camera.ui.spec.3 Dismissing the camera', function (done) {
+            checkSession(done);
+            checkCamera(pending);
+            var spec = function () {
+                var options = {
+                    quality: 50,
+                    allowEdit: true,
+                    sourceType: cameraConstants.PictureSourceType.CAMERA,
+                    destinationType: cameraConstants.DestinationType.FILE_URI
+                };
+                return driver
+                    .then(function () {
+                        return getPicture(options, true);
+                    })
+                    .context(CONTEXT_NATIVE_APP)
+                    .waitForElementByAndroidUIAutomator('new UiSelector().resourceIdMatches(".*cancel.*")', MINUTE / 2)
+                    .click()
+                    .then(function () {
+                        return checkPicture(false);
+                    });
+            };
+
+            tryRunSpec(spec).done(done);
+        }, 10 * MINUTE);
+
+        // getPicture(), then take picture but dismiss the edit
+        // wait for the error callback to be called
+        it('camera.ui.spec.4 Dismissing the edit', function (done) {
+            checkSession(done);
+            checkCamera(pending);
+            var spec = function () {
+                var options = {
+                    quality: 50,
+                    allowEdit: true,
+                    sourceType: cameraConstants.PictureSourceType.CAMERA,
+                    destinationType: cameraConstants.DestinationType.FILE_URI
+                };
+                return driver
+                    .then(function () {
+                        return getPicture(options, true);
+                    })
+                    .waitForElementByAndroidUIAutomator('new UiSelector().resourceIdMatches(".*shutter.*")', MINUTE / 2)
+                    .click()
+                    .waitForElementByAndroidUIAutomator('new UiSelector().resourceIdMatches(".*done.*")', MINUTE / 2)
+                    .click()
+                    .waitForElementByAndroidUIAutomator('new UiSelector().resourceIdMatches(".*discard.*")', MINUTE / 2)
+                    .click()
+                    .then(function () {
+                        return checkPicture(false);
+                    });
+            };
+
+            tryRunSpec(spec).done(done);
+        }, 10 * MINUTE);
+
+        it('camera.ui.spec.5 Verifying target image size, sourceType=CAMERA', function (done) {
+            checkSession(done);
+            checkCamera(pending);
+            var spec = generateSpec({
+                quality: 50,
+                allowEdit: false,
+                sourceType: cameraConstants.PictureSourceType.CAMERA,
+                saveToPhotoAlbum: false,
+                targetWidth: 210,
+                targetHeight: 210
+            });
+
+            tryRunSpec(spec).done(done);
+        }, 10 * MINUTE);
+
+        it('camera.ui.spec.6 Verifying target image size, sourceType=PHOTOLIBRARY', function (done) {
+            checkSession(done);
+            var spec = generateSpec({
+                quality: 50,
+                allowEdit: false,
+                sourceType: cameraConstants.PictureSourceType.PHOTOLIBRARY,
+                saveToPhotoAlbum: false,
+                targetWidth: 210,
+                targetHeight: 210
+            });
+
+            tryRunSpec(spec).done(done);
+        }, 10 * MINUTE);
+
+        it('camera.ui.spec.7 Verifying target image size, sourceType=CAMERA, DestinationType=NATIVE_URI', function (done) {
+            checkSession(done);
+            checkCamera(pending);
+            var spec = generateSpec({
+                quality: 50,
+                allowEdit: false,
+                sourceType: cameraConstants.PictureSourceType.CAMERA,
+                destinationType: cameraConstants.DestinationType.NATIVE_URI,
+                saveToPhotoAlbum: false,
+                targetWidth: 210,
+                targetHeight: 210
+            });
+
+            tryRunSpec(spec).done(done);
+        }, 10 * MINUTE);
+
+        it('camera.ui.spec.8 Verifying target image size, sourceType=PHOTOLIBRARY, DestinationType=NATIVE_URI', function (done) {
+            checkSession(done);
+            var spec = generateSpec({
+                quality: 50,
+                allowEdit: false,
+                sourceType: cameraConstants.PictureSourceType.PHOTOLIBRARY,
+                destinationType: cameraConstants.DestinationType.NATIVE_URI,
+                saveToPhotoAlbum: false,
+                targetWidth: 210,
+                targetHeight: 210
+            });
+
+            tryRunSpec(spec).done(done);
+        }, 10 * MINUTE);
+
+        it('camera.ui.spec.9 Verifying target image size, sourceType=CAMERA, DestinationType=NATIVE_URI, quality=100', function (done) {
+            checkSession(done);
+            checkCamera(pending);
+            var spec = generateSpec({
+                quality: 100,
+                allowEdit: true,
+                sourceType: cameraConstants.PictureSourceType.CAMERA,
+                destinationType: cameraConstants.DestinationType.NATIVE_URI,
+                saveToPhotoAlbum: false,
+                targetWidth: 305,
+                targetHeight: 305
+            });
+
+            tryRunSpec(spec).done(done);
+        }, 10 * MINUTE);
+
+        it('camera.ui.spec.10 Verifying target image size, sourceType=PHOTOLIBRARY, DestinationType=NATIVE_URI, quality=100', function (done) {
+            checkSession(done);
+            var spec = generateSpec({
+                quality: 100,
+                allowEdit: true,
+                sourceType: cameraConstants.PictureSourceType.PHOTOLIBRARY,
+                destinationType: cameraConstants.DestinationType.NATIVE_URI,
+                saveToPhotoAlbum: false,
+                targetWidth: 305,
+                targetHeight: 305
+            });
+
+            tryRunSpec(spec).done(done);
+        }, 10 * MINUTE);
+
+        // combine various options for getPicture()
+        generateOptions().forEach(function (spec) {
+            it('camera.ui.spec.11.' + spec.id + ' Combining options. ' + spec.description, function (done) {
+                checkSession(done);
+                if (spec.options.sourceType == cameraConstants.PictureSourceType.CAMERA) {
+                    checkCamera(pending);
+                }
+                var s = generateSpec(spec.options);
+                tryRunSpec(s).done(done);
+            }, 10 * MINUTE);
+        });
+
+        it('camera.ui.util Delete filler picture from device library', function (done) {
+            driver
+                .context(webviewContext)
+                .deleteFillerImage(fillerImagePath)
+                .done(done);
+        }, MINUTE);
+
+        it('camera.ui.util Delete taken picture from device library', function (done) {
+            checkSession(done);
+            if (!isTestPictureSaved) {
+                // couldn't save test picture earlier, so nothing to delete here
+                done();
+                return;
+            }
+            // delete exactly one latest picture
+            // this should be the picture we've taken in the first spec
+            driver
+                .context(CONTEXT_NATIVE_APP)
+                .deviceKeyEvent(BACK_BUTTON)
+                .sleep(1000)
+                .deviceKeyEvent(BACK_BUTTON)
+                .sleep(1000)
+                .deviceKeyEvent(BACK_BUTTON)
+                .elementById('Apps')
+                .click()
+                .elementByAndroidUIAutomator('new UiSelector().text("Gallery")')
+                .click()
+                .elementByAndroidUIAutomator('new UiSelector().textContains("Pictures")')
+                .click()
+                .then(deleteImage)
+                .deviceKeyEvent(BACK_BUTTON)
+                .sleep(1000)
+                .deviceKeyEvent(BACK_BUTTON)
+                .sleep(1000)
+                .deviceKeyEvent(BACK_BUTTON)
+                .fail(fail)
+                .finally(done);
+        }, 3 * MINUTE);
+    });
+
+});

+ 305 - 0
miaomiao/plugins/cordova-plugin-camera/appium-tests/helpers/cameraHelper.js

xqd
@@ -0,0 +1,305 @@
+/*jshint node: true */
+/* global Q, resolveLocalFileSystemURL, Camera, cordova */
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+'use strict';
+
+var cameraConstants = require('../../www/CameraConstants');
+
+function findKeyByValue(set, value) {
+   for (var k in set) {
+      if (set.hasOwnProperty(k)) {
+         if (set[k] == value) {
+            return k;
+         }
+      }
+   }
+   return undefined;
+}
+
+function getDescription(spec) {
+    var desc = '';
+
+    desc += 'sourceType: ' + findKeyByValue(cameraConstants.PictureSourceType, spec.options.sourceType);
+    desc += ', destinationType: ' + findKeyByValue(cameraConstants.DestinationType, spec.options.destinationType);
+    desc += ', encodingType: ' + findKeyByValue(cameraConstants.EncodingType, spec.options.encodingType);
+    desc += ', allowEdit: ' + spec.options.allowEdit.toString();
+    desc += ', correctOrientation: ' + spec.options.correctOrientation.toString();
+
+    return desc;
+}
+
+module.exports.generateSpecs = function (sourceTypes, destinationTypes, encodingTypes, allowEditOptions, correctOrientationOptions) {
+    var destinationType,
+        sourceType,
+        encodingType,
+        allowEdit,
+        correctOrientation,
+        specs = [],
+        id = 1;
+    for (destinationType in destinationTypes) {
+        if (destinationTypes.hasOwnProperty(destinationType)) {
+            for (sourceType in sourceTypes) {
+                if (sourceTypes.hasOwnProperty(sourceType)) {
+                    for (encodingType in encodingTypes) {
+                        if (encodingTypes.hasOwnProperty(encodingType)) {
+                            for (allowEdit in allowEditOptions) {
+                                if (allowEditOptions.hasOwnProperty(allowEdit)) {
+                                    for (correctOrientation in correctOrientationOptions) {
+                                        // if taking picture from photolibrary, don't vary 'correctOrientation' option
+                                        if ((sourceTypes[sourceType] === cameraConstants.PictureSourceType.PHOTOLIBRARY ||
+                                            sourceTypes[sourceType] === cameraConstants.PictureSourceType.SAVEDPHOTOALBUM) &&
+                                            correctOrientation === true) { continue; }
+                                        var spec = {
+                                            'id': id++,
+                                            'options': {
+                                                'destinationType': destinationTypes[destinationType],
+                                                'sourceType': sourceTypes[sourceType],
+                                                'encodingType': encodingTypes[encodingType],
+                                                'allowEdit': allowEditOptions[allowEdit],
+                                                'saveToPhotoAlbum': false,
+                                                'correctOrientation': correctOrientationOptions[correctOrientation]
+                                            }
+                                        };
+                                        spec.description = getDescription(spec);
+                                        specs.push(spec);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return specs;
+};
+
+// calls getPicture() and saves the result in promise
+// note that this function is executed in the context of tested app
+// and not in the context of tests
+module.exports.getPicture = function (opts, pid) {
+    if (navigator._appiumPromises[pid - 1]) {
+        navigator._appiumPromises[pid - 1] = null;
+    }
+    navigator._appiumPromises[pid] = Q.defer();
+    navigator.camera.getPicture(function (result) {
+        navigator._appiumPromises[pid].resolve(result);
+    }, function (err) {
+        navigator._appiumPromises[pid].reject(err);
+    }, opts);
+};
+
+// verifies taken picture when the promise is resolved,
+// calls a callback with 'OK' if everything is good,
+// calls a callback with 'ERROR: <error message>' if something is wrong
+// note that this function is executed in the context of tested app
+// and not in the context of tests
+module.exports.checkPicture = function (pid, options, cb) {
+    var isIos = cordova.platformId === "ios";
+    var isAndroid = cordova.platformId === "android";
+    // skip image type check if it's unmodified on Android:
+    // https://github.com/apache/cordova-plugin-camera/#android-quirks-1
+    var skipFileTypeCheckAndroid = isAndroid && options.quality === 100 &&
+        !options.targetWidth && !options.targetHeight &&
+        !options.correctOrientation;
+
+    // Skip image type check if destination is NATIVE_URI and source - device's photoalbum
+    // https://github.com/apache/cordova-plugin-camera/#ios-quirks-1
+    var skipFileTypeCheckiOS = isIos && options.destinationType === Camera.DestinationType.NATIVE_URI &&
+        (options.sourceType === Camera.PictureSourceType.PHOTOLIBRARY ||
+         options.sourceType === Camera.PictureSourceType.SAVEDPHOTOALBUM);
+
+    var skipFileTypeCheck = skipFileTypeCheckAndroid || skipFileTypeCheckiOS;
+
+    var desiredType = 'JPEG';
+    var mimeType = 'image/jpeg';
+    if (options.encodingType === Camera.EncodingType.PNG) {
+        desiredType = 'PNG';
+        mimeType = 'image/png';
+    }
+
+    function errorCallback(msg) {
+        if (msg.hasOwnProperty('message')) {
+            msg = msg.message;
+        }
+        cb('ERROR: ' + msg);
+    }
+
+    // verifies the image we get from plugin
+    function verifyResult(result) {
+        if (result.length === 0) {
+            errorCallback('The result is empty.');
+            return;
+        } else if (isIos && options.destinationType === Camera.DestinationType.NATIVE_URI && result.indexOf('assets-library:') !== 0) {
+            errorCallback('Expected "' + result.substring(0, 150) + '"to start with "assets-library:"');
+            return;
+        } else if (isIos && options.destinationType === Camera.DestinationType.FILE_URI && result.indexOf('file:') !== 0) {
+            errorCallback('Expected "' + result.substring(0, 150) + '"to start with "file:"');
+            return;
+        }
+
+        try {
+            window.atob(result);
+            // if we got here it is a base64 string (DATA_URL)
+            result = "data:" + mimeType + ";base64," + result;
+        } catch (e) {
+            // not DATA_URL
+            if (options.destinationType === Camera.DestinationType.DATA_URL) {
+                errorCallback('Expected ' + result.substring(0, 150) + 'not to be DATA_URL');
+                return;
+            }
+        }
+        try {
+            if (result.indexOf('file:') === 0 ||
+                result.indexOf('content:') === 0 ||
+                result.indexOf('assets-library:') === 0) {
+
+                if (!window.resolveLocalFileSystemURL) {
+                    errorCallback('Cannot read file. Please install cordova-plugin-file to fix this.');
+                    return;
+                }
+                resolveLocalFileSystemURL(result, function (entry) {
+                    if (skipFileTypeCheck) {
+                        displayFile(entry);
+                    } else {
+                        verifyFile(entry);
+                    }
+                });
+            } else {
+                displayImage(result);
+            }
+        } catch (e) {
+            errorCallback(e);
+        }
+    }
+
+    // verifies that the file type matches the requested type
+    function verifyFile(entry) {
+        try {
+            var reader = new FileReader();
+            reader.onloadend = function(e) {
+                var arr = (new Uint8Array(e.target.result)).subarray(0, 4);
+                var header = '';
+                for(var i = 0; i < arr.length; i++) {
+                    header += arr[i].toString(16);
+                }
+                var actualType = 'unknown';
+
+                switch (header) {
+                    case "89504e47":
+                        actualType = 'PNG';
+                        break;
+                    case 'ffd8ffe0':
+                    case 'ffd8ffe1':
+                    case 'ffd8ffe2':
+                        actualType = 'JPEG';
+                        break;
+                }
+
+                if (actualType === desiredType) {
+                    displayFile(entry);
+                } else {
+                    errorCallback('File type mismatch. Expected ' + desiredType + ', got ' + actualType);
+                }
+            };
+            reader.onerror = function (e) {
+                errorCallback(e);
+            };
+            entry.file(function (file) {
+                reader.readAsArrayBuffer(file);
+            }, function (e) {
+                errorCallback(e);
+            });
+        } catch (e) {
+            errorCallback(e);
+        }
+    }
+
+    // reads the file, then displays the image
+    function displayFile(entry) {
+        function onFileReceived(file) {
+            var reader = new FileReader();
+            reader.onerror = function (e) {
+                errorCallback(e);
+            };
+            reader.onloadend = function (evt) {
+                displayImage(evt.target.result);
+            };
+            reader.readAsDataURL(file);
+        }
+
+        entry.file(onFileReceived, function (e) {
+            errorCallback(e);
+        });
+    }
+
+    function displayImage(image) {
+        try {
+            var imgEl = document.getElementById('camera_test_image');
+            if (!imgEl) {
+                imgEl = document.createElement('img');
+                imgEl.id = 'camera_test_image';
+                document.body.appendChild(imgEl);
+            }
+            var timedOut = false;
+            var loadTimeout = setTimeout(function () {
+                timedOut = true;
+                imgEl.src = '';
+                errorCallback('The image did not load: ' + image.substring(0, 150));
+            }, 10000);
+            var done = function (status) {
+                if (!timedOut) {
+                    clearTimeout(loadTimeout);
+                    imgEl.src = '';
+                    cb(status);
+                }
+            };
+            imgEl.onload = function () {
+                try {
+                    // aspect ratio is preserved so only one dimension should match
+                    if ((typeof options.targetWidth === 'number' && imgEl.naturalWidth !== options.targetWidth) &&
+                        (typeof options.targetHeight === 'number' && imgEl.naturalHeight !== options.targetHeight))
+                    {
+                        done('ERROR: Wrong image size: ' + imgEl.naturalWidth + 'x' + imgEl.naturalHeight +
+                            '. Requested size: ' + options.targetWidth + 'x' + options.targetHeight);
+                    } else {
+                        done('OK');
+                    }
+                } catch (e) {
+                    errorCallback(e);
+                }
+            };
+            imgEl.src = image;
+        } catch (e) {
+            errorCallback(e);
+        }
+    }
+
+    navigator._appiumPromises[pid].promise
+        .then(function (result) {
+            verifyResult(result);
+        })
+        .fail(function (e) {
+            errorCallback(e);
+        });
+};

+ 489 - 0
miaomiao/plugins/cordova-plugin-camera/appium-tests/ios/ios.spec.js

xqd
@@ -0,0 +1,489 @@
+/*jshint node: true, jasmine: true */
+
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+// these tests are meant to be executed by Cordova Paramedic test runner
+// you can find it here: https://github.com/apache/cordova-paramedic/
+// it is not necessary to do a full CI setup to run these tests
+// just run "node cordova-paramedic/main.js --platform ios --plugin cordova-plugin-camera"
+
+'use strict';
+
+var wdHelper = global.WD_HELPER;
+var screenshotHelper = global.SCREENSHOT_HELPER;
+var isDevice = global.DEVICE;
+var cameraConstants = require('../../www/CameraConstants');
+var cameraHelper = require('../helpers/cameraHelper');
+
+var MINUTE = 60 * 1000;
+var DEFAULT_WEBVIEW_CONTEXT = 'WEBVIEW_1';
+var PROMISE_PREFIX = 'appium_camera_promise_';
+var CONTEXT_NATIVE_APP = 'NATIVE_APP';
+
+describe('Camera tests iOS.', function () {
+    var driver;
+    var webviewContext = DEFAULT_WEBVIEW_CONTEXT;
+    // promise count to use in promise ID
+    var promiseCount = 0;
+    // going to set this to false if session is created successfully
+    var failedToStart = true;
+    // points out which UI automation to use
+    var isXCUI = false;
+    // spec counter to restart the session
+    var specsRun = 0;
+
+    function getNextPromiseId() {
+        promiseCount += 1;
+        return getCurrentPromiseId();
+    }
+
+    function getCurrentPromiseId() {
+        return PROMISE_PREFIX + promiseCount;
+    }
+
+    function gracefullyFail(error) {
+        fail(error);
+        return driver
+            .quit()
+            .then(function () {
+                return getDriver();
+            });
+    }
+
+    // generates test specs by combining all the specified options
+    // you can add more options to test more scenarios
+    function generateOptions() {
+        var sourceTypes = cameraConstants.PictureSourceType;
+        var destinationTypes = cameraConstants.DestinationType;
+        var encodingTypes = cameraConstants.EncodingType;
+        var allowEditOptions = [ true, false ];
+        var correctOrientationOptions = [ true, false ];
+
+        return cameraHelper.generateSpecs(sourceTypes, destinationTypes, encodingTypes, allowEditOptions, correctOrientationOptions);
+    }
+
+    function usePicture() {
+        return driver
+            .elementByXPath('//*[@label="Use"]')
+            .click()
+            .fail(function () {
+                if (isXCUI) {
+                    return driver
+                        .waitForElementByAccessibilityId('Choose', MINUTE / 3)
+                        .click();
+                }
+                // For some reason "Choose" element is not clickable by standard Appium methods on iOS <= 9
+                return wdHelper.tapElementByXPath('//UIAButton[@label="Choose"]', driver);
+            });
+    }
+
+    function clickPhoto() {
+        if (isXCUI) {
+            // iOS >=10
+            return driver
+                .context(CONTEXT_NATIVE_APP)
+                .elementsByXPath('//XCUIElementTypeCell')
+                .then(function(photos) {
+                    if (photos.length == 0) {
+                        return driver
+                            .sleep(0) // driver.source is not a function o.O
+                            .source()
+                            .then(function (src) {
+                                console.log(src);
+                                gracefullyFail('Couldn\'t find an image to click');
+                            });
+                    }
+                    // intentionally clicking the second photo here
+                    // the first one is not clickable for some reason
+                    return photos[1].click();
+                });
+        }
+        // iOS <10
+        return driver
+            .elementByXPath('//UIACollectionCell')
+            .click();
+    }
+
+    function getPicture(options, cancelCamera, skipUiInteractions) {
+        var promiseId = getNextPromiseId();
+        if (!options) {
+            options = {};
+        }
+
+        return driver
+            .context(webviewContext)
+            .execute(cameraHelper.getPicture, [options, promiseId])
+            .context(CONTEXT_NATIVE_APP)
+            .then(function () {
+                if (skipUiInteractions) {
+                    return;
+                }
+                if (options.hasOwnProperty('sourceType') && options.sourceType === cameraConstants.PictureSourceType.PHOTOLIBRARY) {
+                    return driver
+                        .waitForElementByAccessibilityId('Camera Roll', MINUTE / 2)
+                        .click()
+                        .then(function () {
+                            return clickPhoto();
+                        })
+                        .then(function () {
+                            if (!options.allowEdit) {
+                                return driver;
+                            }
+                            return usePicture();
+                        });
+                }
+                if (options.hasOwnProperty('sourceType') && options.sourceType === cameraConstants.PictureSourceType.SAVEDPHOTOALBUM) {
+                    return clickPhoto()
+                        .then(function () {
+                            if (!options.allowEdit) {
+                                return driver;
+                            }
+                            return usePicture();
+                        });
+                }
+                if (cancelCamera) {
+                    return driver
+                        .waitForElementByAccessibilityId('Cancel', MINUTE / 2)
+                        .click();
+                }
+                return driver
+                    .waitForElementByAccessibilityId('Take Picture', MINUTE / 2)
+                    .click()
+                    .waitForElementByAccessibilityId('Use Photo', MINUTE / 2)
+                    .click();
+            })
+            .fail(fail);
+    }
+
+    // checks if the picture was successfully taken
+    // if shouldLoad is falsy, ensures that the error callback was called
+    function checkPicture(shouldLoad, options) {
+        if (!options) {
+            options = {};
+        }
+        return driver
+            .context(webviewContext)
+            .setAsyncScriptTimeout(MINUTE / 2)
+            .executeAsync(cameraHelper.checkPicture, [getCurrentPromiseId(), options])
+            .then(function (result) {
+                if (shouldLoad) {
+                    if (result !== 'OK') {
+                        fail(result);
+                    }
+                } else if (result.indexOf('ERROR') === -1) {
+                    throw 'Unexpected success callback with result: ' + result;
+                }
+            });
+    }
+
+    // takes a picture with the specified options
+    // and then verifies it
+    function runSpec(options, done, pending) {
+        if (options.sourceType === cameraConstants.PictureSourceType.CAMERA && !isDevice) {
+            pending('Camera is not available on iOS simulator');
+        }
+        checkSession(done);
+        specsRun += 1;
+        return driver
+            .then(function () {
+                return getPicture(options);
+            })
+            .then(function () {
+                return checkPicture(true, options);
+            })
+            .fail(gracefullyFail);
+    }
+
+    function getDriver() {
+        failedToStart = true;
+        driver = wdHelper.getDriver('iOS');
+        return wdHelper.getWebviewContext(driver)
+            .then(function(context) {
+                webviewContext = context;
+                return driver.context(webviewContext);
+            })
+            .then(function () {
+                return wdHelper.waitForDeviceReady(driver);
+            })
+            .then(function () {
+                return wdHelper.injectLibraries(driver);
+            })
+            .sessionCapabilities()
+            .then(function (caps) {
+                var platformVersion = parseFloat(caps.platformVersion);
+                isXCUI = platformVersion >= 10.0;
+            })
+            .then(function () {
+                var options = {
+                    quality: 50,
+                    allowEdit: false,
+                    sourceType: cameraConstants.PictureSourceType.SAVEDPHOTOALBUM,
+                    saveToPhotoAlbum: false,
+                    targetWidth: 210,
+                    targetHeight: 210
+                };
+                return driver
+                    .then(function () { return getPicture(options, false, true); })
+                    .context(CONTEXT_NATIVE_APP)
+                    .acceptAlert()
+                    .then(function alertDismissed() {
+                        // TODO: once we move to only XCUITest-based (which is force on you in either iOS 10+ or Xcode 8+)
+                        // UI tests, we will have to:
+                        // a) remove use of autoAcceptAlerts appium capability since it no longer functions in XCUITest
+                        // b) can remove this entire then() clause, as we do not need to explicitly handle the acceptAlert
+                        //    failure callback, since we will be guaranteed to hit the permission dialog on startup.
+                    }, function noAlert() {
+                        // in case the contacts permission alert never showed up: no problem, don't freak out.
+                        // This can happen if:
+                        // a) The application-under-test already had photos permissions granted to it
+                        // b) Appium's autoAcceptAlerts capability is provided (and functioning)
+                    })
+                    .elementByAccessibilityId('Cancel', 10000)
+                    .click();
+            })
+            .then(function () {
+                failedToStart = false;
+            });
+    }
+
+    function checkSession(done) {
+        if (failedToStart) {
+            fail('Failed to start a session');
+            done();
+        }
+    }
+
+    it('camera.ui.util configure driver and start a session', function (done) {
+        getDriver()
+            .fail(fail)
+            .done(done);
+    }, 15 * MINUTE);
+
+    describe('Specs.', function () {
+        afterEach(function (done) {
+            if (specsRun >= 15) {
+                specsRun = 0;
+                // we need to restart the session regularly because for some reason
+                // when running against iOS 10 simulator on SauceLabs, 
+                // Appium cannot handle more than ~20 specs at one session
+                // the error would be as follows:
+                // "Could not proxy command to remote server. Original error: Error: connect ECONNREFUSED 127.0.0.1:8100"
+                checkSession(done);
+                return driver
+                    .quit()
+                    .then(function () {
+                        return getDriver();
+                    })
+                    .done(done);
+            } else {
+                done();
+            }
+        }, 15 * MINUTE);
+
+        // getPicture() with mediaType: VIDEO, sourceType: PHOTOLIBRARY
+        it('camera.ui.spec.1 Selecting only videos', function (done) {
+            checkSession(done);
+            specsRun += 1;
+            var options = { sourceType: cameraConstants.PictureSourceType.PHOTOLIBRARY,
+                            mediaType: cameraConstants.MediaType.VIDEO };
+            driver
+                // skip ui unteractions
+                .then(function () { return getPicture(options, false, true); })
+                .waitForElementByXPath('//*[contains(@label,"Videos")]', MINUTE / 2)
+                .elementByAccessibilityId('Cancel')
+                .click()
+                .fail(gracefullyFail)
+                .done(done);
+        }, 7 * MINUTE);
+
+        // getPicture(), then dismiss
+        // wait for the error callback to be called
+        it('camera.ui.spec.2 Dismissing the camera', function (done) {
+            checkSession(done);
+            if (!isDevice) {
+                pending('Camera is not available on iOS simulator');
+            }
+            specsRun += 1;
+            var options = { sourceType: cameraConstants.PictureSourceType.CAMERA,
+                            saveToPhotoAlbum: false };
+            driver
+                .then(function () {
+                    return getPicture(options, true);
+                })
+                .then(function () {
+                    return checkPicture(false);
+                })
+                .fail(gracefullyFail)
+                .done(done);
+        }, 7 * MINUTE);
+
+        it('camera.ui.spec.3 Verifying target image size, sourceType=CAMERA', function (done) {
+            var options = {
+                quality: 50,
+                allowEdit: false,
+                sourceType: cameraConstants.PictureSourceType.CAMERA,
+                saveToPhotoAlbum: false,
+                targetWidth: 210,
+                targetHeight: 210
+            };
+
+            runSpec(options, done, pending).done(done);
+        }, 7 * MINUTE);
+
+        it('camera.ui.spec.4 Verifying target image size, sourceType=SAVEDPHOTOALBUM', function (done) {
+            var options = {
+                quality: 50,
+                allowEdit: false,
+                sourceType: cameraConstants.PictureSourceType.SAVEDPHOTOALBUM,
+                saveToPhotoAlbum: false,
+                targetWidth: 210,
+                targetHeight: 210
+            };
+
+            runSpec(options, done, pending).done(done);
+        }, 7 * MINUTE);
+
+        it('camera.ui.spec.5 Verifying target image size, sourceType=PHOTOLIBRARY', function (done) {
+            var options = {
+                quality: 50,
+                allowEdit: false,
+                sourceType: cameraConstants.PictureSourceType.PHOTOLIBRARY,
+                saveToPhotoAlbum: false,
+                targetWidth: 210,
+                targetHeight: 210
+            };
+
+            runSpec(options, done, pending).done(done);
+        }, 7 * MINUTE);
+
+        it('camera.ui.spec.6 Verifying target image size, sourceType=CAMERA, destinationType=FILE_URL', function (done) {
+            // remove this line if you don't mind the tests leaving a photo saved on device
+            pending('Cannot prevent iOS from saving the picture to photo library');
+
+            var options = {
+                quality: 50,
+                allowEdit: false,
+                sourceType: cameraConstants.PictureSourceType.CAMERA,
+                destinationType: cameraConstants.DestinationType.FILE_URL,
+                saveToPhotoAlbum: false,
+                targetWidth: 210,
+                targetHeight: 210
+            };
+
+            runSpec(options, done, pending).done(done);
+        }, 7 * MINUTE);
+
+        it('camera.ui.spec.7 Verifying target image size, sourceType=SAVEDPHOTOALBUM, destinationType=FILE_URL', function (done) {
+            var options = {
+                quality: 50,
+                allowEdit: false,
+                sourceType: cameraConstants.PictureSourceType.SAVEDPHOTOALBUM,
+                destinationType: cameraConstants.DestinationType.FILE_URL,
+                saveToPhotoAlbum: false,
+                targetWidth: 210,
+                targetHeight: 210
+            };
+
+            runSpec(options, done, pending).done(done);
+        }, 7 * MINUTE);
+
+        it('camera.ui.spec.8 Verifying target image size, sourceType=PHOTOLIBRARY, destinationType=FILE_URL', function (done) {
+            var options = {
+                quality: 50,
+                allowEdit: false,
+                sourceType: cameraConstants.PictureSourceType.PHOTOLIBRARY,
+                destinationType: cameraConstants.DestinationType.FILE_URL,
+                saveToPhotoAlbum: false,
+                targetWidth: 210,
+                targetHeight: 210
+            };
+
+            runSpec(options, done, pending).done(done);
+        }, 7 * MINUTE);
+
+        it('camera.ui.spec.9 Verifying target image size, sourceType=CAMERA, destinationType=FILE_URL, quality=100', function (done) {
+            // remove this line if you don't mind the tests leaving a photo saved on device
+            pending('Cannot prevent iOS from saving the picture to photo library');
+
+            var options = {
+                quality: 100,
+                allowEdit: false,
+                sourceType: cameraConstants.PictureSourceType.CAMERA,
+                destinationType: cameraConstants.DestinationType.FILE_URL,
+                saveToPhotoAlbum: false,
+                targetWidth: 305,
+                targetHeight: 305
+            };
+            runSpec(options, done, pending).done(done);
+        }, 7 * MINUTE);
+
+        it('camera.ui.spec.10 Verifying target image size, sourceType=SAVEDPHOTOALBUM, destinationType=FILE_URL, quality=100', function (done) {
+            var options = {
+                quality: 100,
+                allowEdit: false,
+                sourceType: cameraConstants.PictureSourceType.SAVEDPHOTOALBUM,
+                destinationType: cameraConstants.DestinationType.FILE_URL,
+                saveToPhotoAlbum: false,
+                targetWidth: 305,
+                targetHeight: 305
+            };
+
+            runSpec(options, done, pending).done(done);
+        }, 7 * MINUTE);
+
+        it('camera.ui.spec.11 Verifying target image size, sourceType=PHOTOLIBRARY, destinationType=FILE_URL, quality=100', function (done) {
+            var options = {
+                quality: 100,
+                allowEdit: false,
+                sourceType: cameraConstants.PictureSourceType.PHOTOLIBRARY,
+                destinationType: cameraConstants.DestinationType.FILE_URL,
+                saveToPhotoAlbum: false,
+                targetWidth: 305,
+                targetHeight: 305
+            };
+
+            runSpec(options, done, pending).done(done);
+        }, 7 * MINUTE);
+
+        // combine various options for getPicture()
+        generateOptions().forEach(function (spec) {
+            it('camera.ui.spec.12.' + spec.id + ' Combining options. ' + spec.description, function (done) {
+                // remove this check if you don't mind the tests leaving a photo saved on device
+                if (spec.options.sourceType === cameraConstants.PictureSourceType.CAMERA &&
+                    spec.options.destinationType === cameraConstants.DestinationType.NATIVE_URI) {
+                    pending('Skipping: cannot prevent iOS from saving the picture to photo library and cannot delete it. ' +
+                        'For more info, see iOS quirks here: https://github.com/apache/cordova-plugin-camera#ios-quirks-1');
+                }
+
+                runSpec(spec.options, done, pending).done(done);
+            }, 7 * MINUTE);
+        });
+
+    });
+
+    it('camera.ui.util Destroy the session', function (done) {
+        checkSession(done);
+        driver
+            .quit()
+            .done(done);
+    }, 5 * MINUTE);
+});

+ 421 - 0
miaomiao/plugins/cordova-plugin-camera/doc/de/README.md

xqd
@@ -0,0 +1,421 @@
+<!---
+# license: Licensed to the Apache Software Foundation (ASF) under one
+#         or more contributor license agreements.  See the NOTICE file
+#         distributed with this work for additional information
+#         regarding copyright ownership.  The ASF licenses this file
+#         to you under the Apache License, Version 2.0 (the
+#         "License"); you may not use this file except in compliance
+#         with the License.  You may obtain a copy of the License at
+#
+#           http://www.apache.org/licenses/LICENSE-2.0
+#
+#         Unless required by applicable law or agreed to in writing,
+#         software distributed under the License is distributed on an
+#         "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#         KIND, either express or implied.  See the License for the
+#         specific language governing permissions and limitations
+#         under the License.
+-->
+
+# cordova-plugin-camera
+
+[![Build Status](https://travis-ci.org/apache/cordova-plugin-camera.svg)](https://travis-ci.org/apache/cordova-plugin-camera)
+
+Dieses Plugin definiert eine globale `navigator.camera`-Objekt, das eine API für Aufnahmen und für die Auswahl der Bilder aus dem System-Image-Library bietet.
+
+Obwohl das Objekt mit der globalen Gültigkeitsbereich `navigator` verbunden ist, steht es nicht bis nach dem `Deviceready`-Ereignis.
+
+    document.addEventListener("deviceready", onDeviceReady, false);
+    function onDeviceReady() {
+        console.log(navigator.camera);
+    }
+    
+
+## Installation
+
+    cordova plugin add cordova-plugin-camera
+    
+
+## API
+
+  * Kamera 
+      * navigator.camera.getPicture(success, fail, options)
+      * CameraOptions
+      * CameraPopoverHandle
+      * CameraPopoverOptions
+      * navigator.camera.cleanup
+
+## navigator.camera.getPicture
+
+Nimmt ein Foto mit der Kamera, oder ein Foto aus dem Gerät Bildergalerie abgerufen. Das Bild wird an den Erfolg-Rückruf als base64-codierte `String` oder als URI für die Image-Datei übergeben. Die Methode selbst gibt ein `CameraPopoverHandle`-Objekt, das verwendet werden kann, um die Datei-Auswahl-Popover neu zu positionieren.
+
+    navigator.camera.getPicture(cameraSuccess, cameraError, cameraOptions);
+    
+
+#### Beschreibung
+
+Die `camera.getPicture`-Funktion öffnet das Gerät Standard-Kamera-Anwendung, die Benutzern ermöglicht, Bilder ausrichten. Dieses Verhalten tritt in der Standardeinstellung, wenn `Camera.sourceType` `Camera.PictureSourceType.CAMERA` entspricht. Sobald der Benutzer die Fotoschnäpper, die Kameraanwendung geschlossen wird und die Anwendung wird wiederhergestellt.
+
+Wenn `Camera.sourceType` `Camera.PictureSourceType.PHOTOLIBRARY` oder `Camera.PictureSourceType.SAVEDPHOTOALBUM` ist, dann wird ein Dialogfeld angezeigt, das Benutzern ermöglicht, ein vorhandenes Bild auszuwählen. Die `camera.getPicture`-Funktion gibt ein `CameraPopoverHandle`-Objekt, das verwendet werden kann, um die Bild-Auswahl-Dialog, z. B. beim ändert sich der Orientierung des Geräts neu positionieren.
+
+Der Rückgabewert wird an die `cameraSuccess`-Callback-Funktion in einem der folgenden Formate, je nach dem angegebenen `cameraOptions` gesendet:
+
+  * A `String` mit dem base64-codierte Foto-Bild.
+
+  * A `String` , die die Bild-Datei-Stelle auf lokalem Speicher (Standard).
+
+Sie können tun, was Sie wollen, mit dem codierten Bildes oder URI, zum Beispiel:
+
+  * Rendern Sie das Bild in ein `<img>` Tag, wie im folgenden Beispiel
+
+  * Die Daten lokal zu speichern ( `LocalStorage` , [Lawnchair](http://brianleroux.github.com/lawnchair/), etc..)
+
+  * Post die Daten an einen entfernten server
+
+**Hinweis**: Fotoauflösung auf neueren Geräten ist ganz gut. Fotos aus dem Gerät Galerie ausgewählt sind nicht zu einer niedrigeren Qualität herunterskaliert, selbst wenn ein `Qualität`-Parameter angegeben wird. Um Speicherprobleme zu vermeiden, legen Sie `Camera.destinationType` auf `FILE_URI` statt `DATA_URL`.
+
+#### Unterstützte Plattformen
+
+![](doc/img/android-success.png) ![](doc/img/blackberry-success.png) ![](doc/img/browser-success.png) ![](doc/img/firefox-success.png) ![](doc/img/fireos-success.png) ![](doc/img/ios-success.png) ![](doc/img/windows-success.png) ![](doc/img/wp8-success.png) ![](doc/img/ubuntu-success.png)
+
+#### Beispiel
+
+Nehmen Sie ein Foto und rufen Sie sie als base64-codierte Bild:
+
+    navigator.camera.getPicture(onSuccess, onFail, { quality: 50,
+        destinationType: Camera.DestinationType.DATA_URL
+    });
+    
+    function onSuccess(imageData) {
+        var image = document.getElementById('myImage');
+        image.src = "data:image/jpeg;base64," + imageData;
+    }
+    
+    function onFail(message) {
+        alert('Failed because: ' + message);
+    }
+    
+
+Nehmen Sie ein Foto und rufen Sie das Bild-Datei-Speicherort:
+
+    navigator.camera.getPicture(onSuccess, onFail, { quality: 50,
+        destinationType: Camera.DestinationType.FILE_URI });
+    
+    function onSuccess(imageURI) {
+        var image = document.getElementById('myImage');
+        image.src = imageURI;
+    }
+    
+    function onFail(message) {
+        alert('Failed because: ' + message);
+    }
+    
+
+#### "Einstellungen" (iOS)
+
+  * **CameraUsesGeolocation** (Boolean, Standardwert ist False). Zur Erfassung von JPEGs, auf true festgelegt, um Geolocation-Daten im EXIF-Header zu erhalten. Dies löst einen Antrag auf Geolocation-Berechtigungen, wenn auf True festgelegt.
+    
+        <preference name="CameraUsesGeolocation" value="false" />
+        
+
+#### Amazon Fire OS Macken
+
+Amazon Fire OS verwendet Absichten zum Starten von der Kamera-Aktivität auf dem Gerät, um Bilder zu erfassen und auf Handys mit wenig Speicher, Cordova Tätigkeit getötet werden kann. In diesem Szenario kann das Bild nicht angezeigt, wenn die Aktivität von Cordova wiederhergestellt wird.
+
+#### Android Eigenarten
+
+Android verwendet Absichten zum Starten von der Kamera-Aktivität auf dem Gerät, um Bilder zu erfassen und auf Handys mit wenig Speicher, Cordova Tätigkeit getötet werden kann. In diesem Szenario kann das Bild nicht angezeigt, wenn die Aktivität von Cordova wiederhergestellt wird.
+
+#### Browser-Eigenheiten
+
+Fotos können nur als base64-codierte Bild zurückgeben werden.
+
+#### Firefox OS Macken
+
+Kamera-Plugin ist derzeit implementiert mithilfe von [Web-Aktivitäten](https://hacks.mozilla.org/2013/01/introducing-web-activities/).
+
+#### iOS Macken
+
+Einschließlich einer JavaScript-`alert()` entweder Rückruffunktionen kann Probleme verursachen. Wickeln Sie die Warnung innerhalb eine `setTimeout()` erlauben die iOS-Bild-Picker oder Popover vollständig zu schließen, bevor die Warnung angezeigt:
+
+    setTimeout(function() {
+        // do your thing here!
+    }, 0);
+    
+
+#### Windows Phone 7 Macken
+
+Die native Kameraanwendung aufrufen, während das Gerät via Zune angeschlossen ist funktioniert nicht und löst eine Fehler-Callback.
+
+#### Tizen Macken
+
+Tizen unterstützt nur ein `DestinationType` von `Camera.DestinationType.FILE_URI` und ein `SourceType` von `Camera.PictureSourceType.PHOTOLIBRARY`.
+
+## CameraOptions
+
+Optionale Parameter die Kameraeinstellungen anpassen.
+
+    { quality : 75,
+      destinationType : Camera.DestinationType.DATA_URL,
+      sourceType : Camera.PictureSourceType.CAMERA,
+      allowEdit : true,
+      encodingType: Camera.EncodingType.JPEG,
+      targetWidth: 100,
+      targetHeight: 100,
+      popoverOptions: CameraPopoverOptions,
+      saveToPhotoAlbum: false };
+    
+
+  * **Qualität**: Qualität des gespeicherten Bildes, ausgedrückt als ein Bereich von 0-100, wo 100 in der Regel voller Auflösung ohne Verlust aus der Dateikomprimierung ist. Der Standardwert ist 50. *(Anzahl)* (Beachten Sie, dass Informationen über die Kamera Auflösung nicht verfügbar ist.)
+
+  * **DestinationType**: Wählen Sie das Format des Rückgabewerts. Der Standardwert ist FILE_URI. Im Sinne `navigator.camera.DestinationType` *(Anzahl)*
+    
+        Camera.DestinationType = {
+            DATA_URL : 0,      // Return image as base64-encoded string
+            FILE_URI : 1,      // Return image file URI
+            NATIVE_URI : 2     // Return image native URI (e.g., assets-library:// on iOS or content:// on Android)
+        };
+        
+
+  * **SourceType**: Legen Sie die Quelle des Bildes. Der Standardwert ist die Kamera. Im Sinne `navigator.camera.PictureSourceType` *(Anzahl)*
+    
+        Camera.PictureSourceType = {
+            PHOTOLIBRARY : 0,
+            CAMERA : 1,
+            SAVEDPHOTOALBUM : 2
+        };
+        
+
+  * **AllowEdit**: einfache Bearbeitung des Bildes vor Auswahl zu ermöglichen. *(Boolesch)*
+
+  * **EncodingType**: die zurückgegebene Image-Datei ist Codierung auswählen. Standardwert ist JPEG. Im Sinne `navigator.camera.EncodingType` *(Anzahl)*
+    
+        Camera.EncodingType = {
+            JPEG : 0,               // Return JPEG encoded image
+            PNG : 1                 // Return PNG encoded image
+        };
+        
+
+  * **TargetWidth**: Breite in Pixel zum Bild skalieren. Muss mit **TargetHeight**verwendet werden. Seitenverhältnis bleibt konstant. *(Anzahl)*
+
+  * **TargetHeight**: Höhe in Pixel zum Bild skalieren. Muss mit **TargetWidth**verwendet werden. Seitenverhältnis bleibt konstant. *(Anzahl)*
+
+  * **MediaType**: Legen Sie den Typ der Medien zur Auswahl. Funktioniert nur, wenn `PictureSourceType` ist `PHOTOLIBRARY` oder `SAVEDPHOTOALBUM` . Im Sinne `nagivator.camera.MediaType` *(Anzahl)*
+    
+        Camera.MediaType = {
+            PICTURE: 0,    // allow selection of still pictures only. STANDARD. Will return format specified via DestinationType
+            VIDEO: 1,      // allow selection of video only, WILL ALWAYS RETURN FILE_URI
+            ALLMEDIA : 2   // allow selection from all media types
+        };
+        
+
+  * **CorrectOrientation**: Drehen Sie das Bild um die Ausrichtung des Geräts während der Aufnahme zu korrigieren. *(Boolesch)*
+
+  * **SaveToPhotoAlbum**: das Bild auf das Fotoalbum auf dem Gerät zu speichern, nach Einnahme. *(Boolesch)*
+
+  * **PopoverOptions**: iOS-nur Optionen, die Popover Lage in iPad angeben. In definierten`CameraPopoverOptions`.
+
+  * **CameraDirection**: Wählen Sie die Kamera (vorn oder hinten-gerichtete) verwenden. Der Standardwert ist zurück. Im Sinne `navigator.camera.Direction` *(Anzahl)*
+    
+        Camera.Direction = {
+            BACK : 0,      // Use the back-facing camera
+            FRONT : 1      // Use the front-facing camera
+        };
+        
+
+#### Amazon Fire OS Macken
+
+  * `cameraDirection`Ergebnisse in einem hinten gerichteter Foto Wert.
+
+  * Ignoriert die `allowEdit` Parameter.
+
+  * `Camera.PictureSourceType.PHOTOLIBRARY`und `Camera.PictureSourceType.SAVEDPHOTOALBUM` beide das gleiche Fotoalbum anzuzeigen.
+
+#### Android Eigenarten
+
+  * `cameraDirection`Ergebnisse in einem hinten gerichteter Foto Wert.
+
+  * Android verwendet auch die Ernte-Aktivität für AllowEdit, obwohl Ernte sollte arbeiten und das zugeschnittene Bild zurück zu Cordova, das einzige, dass Werke konsequent die gebündelt mit der Google-Plus-Fotos-Anwendung ist tatsächlich zu übergeben. Andere Kulturen funktioniert möglicherweise nicht.
+
+  * `Camera.PictureSourceType.PHOTOLIBRARY`und `Camera.PictureSourceType.SAVEDPHOTOALBUM` beide das gleiche Fotoalbum anzuzeigen.
+
+#### BlackBerry 10 Macken
+
+  * Ignoriert die `quality` Parameter.
+
+  * Ignoriert die `allowEdit` Parameter.
+
+  * `Camera.MediaType`wird nicht unterstützt.
+
+  * Ignoriert die `correctOrientation` Parameter.
+
+  * Ignoriert die `cameraDirection` Parameter.
+
+#### Firefox OS Macken
+
+  * Ignoriert die `quality` Parameter.
+
+  * `Camera.DestinationType`wird ignoriert, und gleich `1` (Bilddatei-URI)
+
+  * Ignoriert die `allowEdit` Parameter.
+
+  * Ignoriert die `PictureSourceType` Parameter (Benutzer wählt es in einem Dialogfenster)
+
+  * Ignoriert die`encodingType`
+
+  * Ignoriert die `targetWidth` und`targetHeight`
+
+  * `Camera.MediaType`wird nicht unterstützt.
+
+  * Ignoriert die `correctOrientation` Parameter.
+
+  * Ignoriert die `cameraDirection` Parameter.
+
+#### iOS Macken
+
+  * Legen Sie `quality` unter 50 Speicherfehler auf einigen Geräten zu vermeiden.
+
+  * Bei der Verwendung `destinationType.FILE_URI` , Fotos werden im temporären Verzeichnis der Anwendung gespeichert. Den Inhalt des temporären Verzeichnis der Anwendung wird gelöscht, wenn die Anwendung beendet.
+
+#### Tizen Macken
+
+  * nicht unterstützte Optionen
+
+  * gibt immer einen Datei-URI
+
+#### Windows Phone 7 und 8 Eigenarten
+
+  * Ignoriert die `allowEdit` Parameter.
+
+  * Ignoriert die `correctOrientation` Parameter.
+
+  * Ignoriert die `cameraDirection` Parameter.
+
+  * Ignoriert die `saveToPhotoAlbum` Parameter. WICHTIG: Alle Aufnahmen die wp7/8 Cordova-Kamera-API werden immer in Kamerarolle des Telefons kopiert. Abhängig von den Einstellungen des Benutzers könnte dies auch bedeuten, dass das Bild in ihre OneDrive automatisch hochgeladen ist. Dies könnte möglicherweise bedeuten, dass das Bild für ein breiteres Publikum als Ihre Anwendung vorgesehen ist. Wenn diese einen Blocker für Ihre Anwendung, Sie müssen die CameraCaptureTask zu implementieren, wie im Msdn dokumentiert: <http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh394006.aspx> Sie können kommentieren oder Up-Abstimmung das Beiträge zu diesem Thema im [Bugtracker](https://issues.apache.org/jira/browse/CB-2083)
+
+  * Ignoriert die `mediaType` -Eigenschaft des `cameraOptions` wie das Windows Phone SDK keine Möglichkeit, Fotothek Videos wählen.
+
+## CameraError
+
+onError-Callback-Funktion, die eine Fehlermeldung bereitstellt.
+
+    function(message) {
+        // Show a helpful message
+    }
+    
+
+#### Beschreibung
+
+  * **Meldung**: die Nachricht wird durch das Gerät systemeigenen Code bereitgestellt. *(String)*
+
+## cameraSuccess
+
+onSuccess Callback-Funktion, die die Bilddaten bereitstellt.
+
+    function(imageData) {
+        // Do something with the image
+    }
+    
+
+#### Beschreibung
+
+  * **CMYK**: Base64-Codierung der Bilddaten, *oder* die Image-Datei-URI, je nach `cameraOptions` in Kraft. *(String)*
+
+#### Beispiel
+
+    // Show image
+    //
+    function cameraCallback(imageData) {
+        var image = document.getElementById('myImage');
+        image.src = "data:image/jpeg;base64," + imageData;
+    }
+    
+
+## CameraPopoverHandle
+
+Ein Handle für das Dialogfeld "Popover" erstellt von `navigator.camera.getPicture`.
+
+#### Beschreibung
+
+  * **setPosition**: Set the position of the popover. Takes the `CameraPopoverOptions` that specify the new position.
+
+#### Unterstützte Plattformen
+
+![](doc/img/android-fail.png) ![](doc/img/blackberry-fail.png) ![](doc/img/browser-fail.png) ![](doc/img/firefox-fail.png) ![](doc/img/fireos-fail.png) ![](doc/img/ios-success.png) ![](doc/img/windows-fail.png) ![](doc/img/wp8-fail.png) ![](doc/img/ubuntu-fail.png)
+
+#### Beispiel
+
+     var cameraPopoverHandle = navigator.camera.getPicture(onSuccess, onFail,
+         { destinationType: Camera.DestinationType.FILE_URI,
+           sourceType: Camera.PictureSourceType.PHOTOLIBRARY,
+           popoverOptions: new CameraPopoverOptions(300, 300, 100, 100, Camera.PopoverArrowDirection.ARROW_ANY)
+         });
+    
+     // Reposition the popover if the orientation changes.
+     window.onorientationchange = function() {
+         var cameraPopoverOptions = new CameraPopoverOptions(0, 0, 100, 100, Camera.PopoverArrowDirection.ARROW_ANY);
+         cameraPopoverHandle.setPosition(cameraPopoverOptions);
+     }
+    
+
+## CameraPopoverOptions
+
+nur iOS-Parametern, die Anker-Element Lage und Pfeil Richtung der Popover angeben, bei der Auswahl von Bildern aus einem iPad Bibliothek oder Album.
+
+    { x : 0,
+      y :  32,
+      width : 320,
+      height : 480,
+      arrowDir : Camera.PopoverArrowDirection.ARROW_ANY
+    };
+    
+
+#### Beschreibung
+
+  * **X**: x Pixelkoordinate des Bildschirmelement auf dem der Popover zu verankern. *(Anzahl)*
+
+  * **y**: y Pixelkoordinate des Bildschirmelement auf dem der Popover zu verankern. *(Anzahl)*
+
+  * **width**: Breite in Pixeln, das Bildschirmelement auf dem der Popover zu verankern. *(Anzahl)*
+
+  * **height**: Höhe in Pixeln, das Bildschirmelement auf dem der Popover zu verankern. *(Anzahl)*
+
+  * **arrowDir**: Richtung der Pfeil auf der Popover zeigen sollte. Im Sinne `Camera.PopoverArrowDirection` *(Anzahl)*
+    
+            Camera.PopoverArrowDirection = {
+                ARROW_UP : 1,        // matches iOS UIPopoverArrowDirection constants
+                ARROW_DOWN : 2,
+                ARROW_LEFT : 4,
+                ARROW_RIGHT : 8,
+                ARROW_ANY : 15
+            };
+        
+
+Beachten Sie, dass die Größe der Popover ändern kann, um die Richtung des Pfeils und Ausrichtung des Bildschirms anzupassen. Achten Sie darauf, um Orientierung zu berücksichtigen, wenn Sie den Anker-Element-Speicherort angeben.
+
+## navigator.camera.cleanup
+
+Entfernt Mittelstufe Fotos von der Kamera aus der vorübergehenden Verwahrung genommen.
+
+    navigator.camera.cleanup( cameraSuccess, cameraError );
+    
+
+#### Beschreibung
+
+Fortgeschrittene Image-Dateien, die in vorübergehender Verwahrung gehalten werden, nach dem Aufruf von `camera.getPicture` entfernt. Gilt nur wenn der Wert von `Camera.sourceType` gleich `Camera.PictureSourceType.CAMERA` und `Camera.destinationType` gleich `Camera.DestinationType.FILE_URI`.
+
+#### Unterstützte Plattformen
+
+![](doc/img/android-fail.png) ![](doc/img/blackberry-fail.png) ![](doc/img/browser-fail.png) ![](doc/img/firefox-fail.png) ![](doc/img/fireos-fail.png) ![](doc/img/ios-success.png) ![](doc/img/windows-fail.png) ![](doc/img/wp8-fail.png) ![](doc/img/ubuntu-fail.png)
+
+#### Beispiel
+
+    navigator.camera.cleanup(onSuccess, onFail);
+    
+    function onSuccess() {
+        console.log("Camera cleanup success.")
+    }
+    
+    function onFail(message) {
+        alert('Failed because: ' + message);
+    }

+ 434 - 0
miaomiao/plugins/cordova-plugin-camera/doc/de/index.md

xqd
@@ -0,0 +1,434 @@
+<!---
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+-->
+
+# cordova-plugin-camera
+
+Dieses Plugin definiert eine globale `navigator.camera`-Objekt, das eine API für Aufnahmen und für die Auswahl der Bilder aus dem System-Image-Library bietet.
+
+Obwohl das Objekt mit der globalen Gültigkeitsbereich `navigator` verbunden ist, steht es nicht bis nach dem `Deviceready`-Ereignis.
+
+    document.addEventListener("deviceready", onDeviceReady, false);
+    function onDeviceReady() {
+        console.log(navigator.camera);
+    }
+    
+
+## Installation
+
+    cordova plugin add cordova-plugin-camera
+    
+
+## navigator.camera.getPicture
+
+Nimmt ein Foto mit der Kamera, oder ein Foto aus dem Gerät Bildergalerie abgerufen. Das Bild wird an den Erfolg-Rückruf als base64-codierte `String` oder als URI für die Image-Datei übergeben. Die Methode selbst gibt ein `CameraPopoverHandle`-Objekt, das verwendet werden kann, um die Datei-Auswahl-Popover neu zu positionieren.
+
+    navigator.camera.getPicture( cameraSuccess, cameraError, cameraOptions );
+    
+
+### Beschreibung
+
+Die `camera.getPicture`-Funktion öffnet das Gerät Standard-Kamera-Anwendung, die Benutzern ermöglicht, Bilder ausrichten. Dieses Verhalten tritt in der Standardeinstellung, wenn `Camera.sourceType` `Camera.PictureSourceType.CAMERA` entspricht. Sobald der Benutzer die Fotoschnäpper, die Kameraanwendung geschlossen wird und die Anwendung wird wiederhergestellt.
+
+Wenn `Camera.sourceType` `Camera.PictureSourceType.PHOTOLIBRARY` oder `Camera.PictureSourceType.SAVEDPHOTOALBUM` ist, dann wird ein Dialogfeld angezeigt, das Benutzern ermöglicht, ein vorhandenes Bild auszuwählen. Die `camera.getPicture`-Funktion gibt ein `CameraPopoverHandle`-Objekt, das verwendet werden kann, um die Bild-Auswahl-Dialog, z. B. beim ändert sich der Orientierung des Geräts neu positionieren.
+
+Der Rückgabewert wird an die `cameraSuccess`-Callback-Funktion in einem der folgenden Formate, je nach dem angegebenen `cameraOptions` gesendet:
+
+*   A `String` mit dem base64-codierte Foto-Bild.
+
+*   A `String` , die die Bild-Datei-Stelle auf lokalem Speicher (Standard).
+
+Sie können tun, was Sie wollen, mit dem codierten Bildes oder URI, zum Beispiel:
+
+*   Rendern Sie das Bild in ein `<img>` Tag, wie im folgenden Beispiel
+
+*   Die Daten lokal zu speichern ( `LocalStorage` , [Lawnchair][1], etc..)
+
+*   Post die Daten an einen entfernten server
+
+ [1]: http://brianleroux.github.com/lawnchair/
+
+**Hinweis**: Fotoauflösung auf neueren Geräten ist ganz gut. Fotos aus dem Gerät Galerie ausgewählt sind nicht zu einer niedrigeren Qualität herunterskaliert, selbst wenn ein `Qualität`-Parameter angegeben wird. Um Speicherprobleme zu vermeiden, legen Sie `Camera.destinationType` auf `FILE_URI` statt `DATA_URL`.
+
+### Unterstützte Plattformen
+
+*   Amazon Fire OS
+*   Android
+*   BlackBerry 10
+*   Browser
+*   Firefox OS
+*   iOS
+*   Tizen
+*   Windows Phone 7 und 8
+*   Windows 8
+
+### "Einstellungen" (iOS)
+
+*   **CameraUsesGeolocation** (Boolean, Standardwert ist False). Zur Erfassung von JPEGs, auf true festgelegt, um Geolocation-Daten im EXIF-Header zu erhalten. Dies löst einen Antrag auf Geolocation-Berechtigungen, wenn auf True festgelegt.
+    
+        <preference name="CameraUsesGeolocation" value="false" />
+        
+
+### Amazon Fire OS Macken
+
+Amazon Fire OS verwendet Absichten zum Starten von der Kamera-Aktivität auf dem Gerät, um Bilder zu erfassen und auf Handys mit wenig Speicher, Cordova Tätigkeit getötet werden kann. In diesem Szenario kann das Bild nicht angezeigt, wenn die Aktivität von Cordova wiederhergestellt wird.
+
+### Android Eigenarten
+
+Android verwendet Absichten zum Starten von der Kamera-Aktivität auf dem Gerät, um Bilder zu erfassen und auf Handys mit wenig Speicher, Cordova Tätigkeit getötet werden kann. In diesem Szenario kann das Bild nicht angezeigt, wenn die Aktivität von Cordova wiederhergestellt wird.
+
+### Browser-Eigenheiten
+
+Fotos können nur als base64-codierte Bild zurückgeben werden.
+
+### Firefox OS Macken
+
+Kamera-Plugin ist derzeit implementiert mithilfe von [Web-Aktivitäten][2].
+
+ [2]: https://hacks.mozilla.org/2013/01/introducing-web-activities/
+
+### iOS Macken
+
+Einschließlich einer JavaScript-`alert()` entweder Rückruffunktionen kann Probleme verursachen. Wickeln Sie die Warnung innerhalb eine `setTimeout()` erlauben die iOS-Bild-Picker oder Popover vollständig zu schließen, bevor die Warnung angezeigt:
+
+    setTimeout(function() {
+        // do your thing here!
+    }, 0);
+    
+
+### Windows Phone 7 Macken
+
+Die native Kameraanwendung aufrufen, während das Gerät via Zune angeschlossen ist funktioniert nicht und löst eine Fehler-Callback.
+
+### Tizen Macken
+
+Tizen unterstützt nur ein `DestinationType` von `Camera.DestinationType.FILE_URI` und ein `SourceType` von `Camera.PictureSourceType.PHOTOLIBRARY`.
+
+### Beispiel
+
+Nehmen Sie ein Foto und rufen Sie sie als base64-codierte Bild:
+
+    navigator.camera.getPicture(onSuccess, onFail, { quality: 50,
+        destinationType: Camera.DestinationType.DATA_URL
+    });
+    
+    function onSuccess(imageData) {
+        var image = document.getElementById('myImage');
+        image.src = "data:image/jpeg;base64," + imageData;
+    }
+    
+    function onFail(message) {
+        alert('Failed because: ' + message);
+    }
+    
+
+Nehmen Sie ein Foto und rufen Sie das Bild-Datei-Speicherort:
+
+    navigator.camera.getPicture(onSuccess, onFail, { quality: 50,
+        destinationType: Camera.DestinationType.FILE_URI });
+    
+    function onSuccess(imageURI) {
+        var image = document.getElementById('myImage');
+        image.src = imageURI;
+    }
+    
+    function onFail(message) {
+        alert('Failed because: ' + message);
+    }
+    
+
+## CameraOptions
+
+Optionale Parameter die Kameraeinstellungen anpassen.
+
+    { quality : 75,
+      destinationType : Camera.DestinationType.DATA_URL,
+      sourceType : Camera.PictureSourceType.CAMERA,
+      allowEdit : true,
+      encodingType: Camera.EncodingType.JPEG,
+      targetWidth: 100,
+      targetHeight: 100,
+      popoverOptions: CameraPopoverOptions,
+      saveToPhotoAlbum: false };
+    
+
+### Optionen
+
+*   **Qualität**: Qualität des gespeicherten Bildes, ausgedrückt als ein Bereich von 0-100, wo 100 in der Regel voller Auflösung ohne Verlust aus der Dateikomprimierung ist. Der Standardwert ist 50. *(Anzahl)* (Beachten Sie, dass Informationen über die Kamera Auflösung nicht verfügbar ist.)
+
+*   **DestinationType**: Wählen Sie das Format des Rückgabewerts. Der Standardwert ist FILE_URI. Im Sinne `navigator.camera.DestinationType` *(Anzahl)*
+    
+        Camera.DestinationType = {
+            DATA_URL : 0,      // Return image as base64-encoded string
+            FILE_URI : 1,      // Return image file URI
+            NATIVE_URI : 2     // Return image native URI (e.g., assets-library:// on iOS or content:// on Android)
+        };
+        
+
+*   **SourceType**: Legen Sie die Quelle des Bildes. Der Standardwert ist die Kamera. Im Sinne `navigator.camera.PictureSourceType` *(Anzahl)*
+    
+        Camera.PictureSourceType = {
+            PHOTOLIBRARY : 0,
+            CAMERA : 1,
+            SAVEDPHOTOALBUM : 2
+        };
+        
+
+*   **AllowEdit**: einfache Bearbeitung des Bildes vor Auswahl zu ermöglichen. *(Boolesch)*
+
+*   **EncodingType**: die zurückgegebene Image-Datei ist Codierung auswählen. Standardwert ist JPEG. Im Sinne `navigator.camera.EncodingType` *(Anzahl)*
+    
+        Camera.EncodingType = {
+            JPEG : 0,               // Return JPEG encoded image
+            PNG : 1                 // Return PNG encoded image
+        };
+        
+
+*   **TargetWidth**: Breite in Pixel zum Bild skalieren. Muss mit **TargetHeight**verwendet werden. Seitenverhältnis bleibt konstant. *(Anzahl)*
+
+*   **TargetHeight**: Höhe in Pixel zum Bild skalieren. Muss mit **TargetWidth**verwendet werden. Seitenverhältnis bleibt konstant. *(Anzahl)*
+
+*   **MediaType**: Legen Sie den Typ der Medien zur Auswahl. Funktioniert nur, wenn `PictureSourceType` ist `PHOTOLIBRARY` oder `SAVEDPHOTOALBUM` . Im Sinne `nagivator.camera.MediaType` *(Anzahl)*
+    
+        Camera.MediaType = {
+            PICTURE: 0,    // allow selection of still pictures only. STANDARD. Will return format specified via DestinationType
+            VIDEO: 1,      // allow selection of video only, WILL ALWAYS RETURN FILE_URI
+            ALLMEDIA : 2   // allow selection from all media types
+        };
+        
+
+*   **CorrectOrientation**: Drehen Sie das Bild um die Ausrichtung des Geräts während der Aufnahme zu korrigieren. *(Boolesch)*
+
+*   **SaveToPhotoAlbum**: das Bild auf das Fotoalbum auf dem Gerät zu speichern, nach Einnahme. *(Boolesch)*
+
+*   **PopoverOptions**: iOS-nur Optionen, die Popover Lage in iPad angeben. In definierten`CameraPopoverOptions`.
+
+*   **CameraDirection**: Wählen Sie die Kamera (vorn oder hinten-gerichtete) verwenden. Der Standardwert ist zurück. Im Sinne `navigator.camera.Direction` *(Anzahl)*
+    
+        Camera.Direction = {
+            BACK : 0,      // Use the back-facing camera
+            FRONT : 1      // Use the front-facing camera
+        };
+        
+
+### Amazon Fire OS Macken
+
+*   `cameraDirection`Ergebnisse in einem hinten gerichteter Foto Wert.
+
+*   Ignoriert die `allowEdit` Parameter.
+
+*   `Camera.PictureSourceType.PHOTOLIBRARY`und `Camera.PictureSourceType.SAVEDPHOTOALBUM` beide das gleiche Fotoalbum anzuzeigen.
+
+### Android Eigenarten
+
+*   `cameraDirection`Ergebnisse in einem hinten gerichteter Foto Wert.
+
+*   Ignoriert die `allowEdit` Parameter.
+
+*   `Camera.PictureSourceType.PHOTOLIBRARY`und `Camera.PictureSourceType.SAVEDPHOTOALBUM` beide das gleiche Fotoalbum anzuzeigen.
+
+### BlackBerry 10 Macken
+
+*   Ignoriert die `quality` Parameter.
+
+*   Ignoriert die `allowEdit` Parameter.
+
+*   `Camera.MediaType`wird nicht unterstützt.
+
+*   Ignoriert die `correctOrientation` Parameter.
+
+*   Ignoriert die `cameraDirection` Parameter.
+
+### Firefox OS Macken
+
+*   Ignoriert die `quality` Parameter.
+
+*   `Camera.DestinationType`wird ignoriert, und gleich `1` (Bilddatei-URI)
+
+*   Ignoriert die `allowEdit` Parameter.
+
+*   Ignoriert die `PictureSourceType` Parameter (Benutzer wählt es in einem Dialogfenster)
+
+*   Ignoriert die`encodingType`
+
+*   Ignoriert die `targetWidth` und`targetHeight`
+
+*   `Camera.MediaType`wird nicht unterstützt.
+
+*   Ignoriert die `correctOrientation` Parameter.
+
+*   Ignoriert die `cameraDirection` Parameter.
+
+### iOS Macken
+
+*   Legen Sie `quality` unter 50 Speicherfehler auf einigen Geräten zu vermeiden.
+
+*   Bei der Verwendung `destinationType.FILE_URI` , Fotos werden im temporären Verzeichnis der Anwendung gespeichert. Den Inhalt des temporären Verzeichnis der Anwendung wird gelöscht, wenn die Anwendung beendet.
+
+### Tizen Macken
+
+*   nicht unterstützte Optionen
+
+*   gibt immer einen Datei-URI
+
+### Windows Phone 7 und 8 Eigenarten
+
+*   Ignoriert die `allowEdit` Parameter.
+
+*   Ignoriert die `correctOrientation` Parameter.
+
+*   Ignoriert die `cameraDirection` Parameter.
+
+*   Ignoriert die `saveToPhotoAlbum` Parameter. WICHTIG: Alle Aufnahmen die wp7/8 Cordova-Kamera-API werden immer in Kamerarolle des Telefons kopiert. Abhängig von den Einstellungen des Benutzers könnte dies auch bedeuten, dass das Bild in ihre OneDrive automatisch hochgeladen ist. Dies könnte möglicherweise bedeuten, dass das Bild für ein breiteres Publikum als Ihre Anwendung vorgesehen ist. Wenn diese einen Blocker für Ihre Anwendung, Sie müssen die CameraCaptureTask zu implementieren, wie im Msdn dokumentiert: <http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh394006.aspx> Sie können kommentieren oder Up-Abstimmung das Beiträge zu diesem Thema im [Bugtracker][3]
+
+*   Ignoriert die `mediaType` -Eigenschaft des `cameraOptions` wie das Windows Phone SDK keine Möglichkeit, Fotothek Videos wählen.
+
+ [3]: https://issues.apache.org/jira/browse/CB-2083
+
+## CameraError
+
+onError-Callback-Funktion, die eine Fehlermeldung bereitstellt.
+
+    function(message) {
+        // Show a helpful message
+    }
+    
+
+### Parameter
+
+*   **Meldung**: die Nachricht wird durch das Gerät systemeigenen Code bereitgestellt. *(String)*
+
+## cameraSuccess
+
+onSuccess Callback-Funktion, die die Bilddaten bereitstellt.
+
+    function(imageData) {
+        // Do something with the image
+    }
+    
+
+### Parameter
+
+*   **CMYK**: Base64-Codierung der Bilddaten, *oder* die Image-Datei-URI, je nach `cameraOptions` in Kraft. *(String)*
+
+### Beispiel
+
+    // Show image
+    //
+    function cameraCallback(imageData) {
+        var image = document.getElementById('myImage');
+        image.src = "data:image/jpeg;base64," + imageData;
+    }
+    
+
+## CameraPopoverHandle
+
+Ein Handle für das Dialogfeld "Popover" erstellt von `navigator.camera.getPicture`.
+
+### Methoden
+
+*   **SetPosition**: Legen Sie die Position der Popover.
+
+### Unterstützte Plattformen
+
+*   iOS
+
+### setPosition
+
+Legen Sie die Position von der Popover.
+
+**Parameter**:
+
+*   `cameraPopoverOptions`: die `CameraPopoverOptions` angeben, dass die neue Position
+
+### Beispiel
+
+     var cameraPopoverHandle = navigator.camera.getPicture(onSuccess, onFail,
+         { destinationType: Camera.DestinationType.FILE_URI,
+           sourceType: Camera.PictureSourceType.PHOTOLIBRARY,
+           popoverOptions: new CameraPopoverOptions(300, 300, 100, 100, Camera.PopoverArrowDirection.ARROW_ANY)
+         });
+    
+     // Reposition the popover if the orientation changes.
+     window.onorientationchange = function() {
+         var cameraPopoverOptions = new CameraPopoverOptions(0, 0, 100, 100, Camera.PopoverArrowDirection.ARROW_ANY);
+         cameraPopoverHandle.setPosition(cameraPopoverOptions);
+     }
+    
+
+## CameraPopoverOptions
+
+nur iOS-Parametern, die Anker-Element Lage und Pfeil Richtung der Popover angeben, bei der Auswahl von Bildern aus einem iPad Bibliothek oder Album.
+
+    { x : 0,
+      y :  32,
+      width : 320,
+      height : 480,
+      arrowDir : Camera.PopoverArrowDirection.ARROW_ANY
+    };
+    
+
+### CameraPopoverOptions
+
+*   **X**: x Pixelkoordinate des Bildschirmelement auf dem der Popover zu verankern. *(Anzahl)*
+
+*   **y**: y Pixelkoordinate des Bildschirmelement auf dem der Popover zu verankern. *(Anzahl)*
+
+*   **width**: Breite in Pixeln, das Bildschirmelement auf dem der Popover zu verankern. *(Anzahl)*
+
+*   **height**: Höhe in Pixeln, das Bildschirmelement auf dem der Popover zu verankern. *(Anzahl)*
+
+*   **arrowDir**: Richtung der Pfeil auf der Popover zeigen sollte. Im Sinne `Camera.PopoverArrowDirection` *(Anzahl)*
+    
+            Camera.PopoverArrowDirection = {
+                ARROW_UP : 1,        // matches iOS UIPopoverArrowDirection constants
+                ARROW_DOWN : 2,
+                ARROW_LEFT : 4,
+                ARROW_RIGHT : 8,
+                ARROW_ANY : 15
+            };
+        
+
+Beachten Sie, dass die Größe der Popover ändern kann, um die Richtung des Pfeils und Ausrichtung des Bildschirms anzupassen. Achten Sie darauf, um Orientierung zu berücksichtigen, wenn Sie den Anker-Element-Speicherort angeben.
+
+## navigator.camera.cleanup
+
+Entfernt Mittelstufe Fotos von der Kamera aus der vorübergehenden Verwahrung genommen.
+
+    navigator.camera.cleanup( cameraSuccess, cameraError );
+    
+
+### Beschreibung
+
+Fortgeschrittene Image-Dateien, die in vorübergehender Verwahrung gehalten werden, nach dem Aufruf von `camera.getPicture` entfernt. Gilt nur wenn der Wert von `Camera.sourceType` gleich `Camera.PictureSourceType.CAMERA` und `Camera.destinationType` gleich `Camera.DestinationType.FILE_URI`.
+
+### Unterstützte Plattformen
+
+*   iOS
+
+### Beispiel
+
+    navigator.camera.cleanup(onSuccess, onFail);
+    
+    function onSuccess() {
+        console.log("Camera cleanup success.")
+    }
+    
+    function onFail(message) {
+        alert('Failed because: ' + message);
+    }

+ 411 - 0
miaomiao/plugins/cordova-plugin-camera/doc/es/README.md

xqd
@@ -0,0 +1,411 @@
+<!---
+# license: Licensed to the Apache Software Foundation (ASF) under one
+#         or more contributor license agreements.  See the NOTICE file
+#         distributed with this work for additional information
+#         regarding copyright ownership.  The ASF licenses this file
+#         to you under the Apache License, Version 2.0 (the
+#         "License"); you may not use this file except in compliance
+#         with the License.  You may obtain a copy of the License at
+#
+#           http://www.apache.org/licenses/LICENSE-2.0
+#
+#         Unless required by applicable law or agreed to in writing,
+#         software distributed under the License is distributed on an
+#         "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#         KIND, either express or implied.  See the License for the
+#         specific language governing permissions and limitations
+#         under the License.
+-->
+
+# cordova-plugin-camera
+
+[![Build Status](https://travis-ci.org/apache/cordova-plugin-camera.svg)](https://travis-ci.org/apache/cordova-plugin-camera)
+
+Este plugin define un global `navigator.camera` objeto que proporciona una API para tomar fotografías y por elegir imágenes de biblioteca de imágenes del sistema.
+
+Aunque el objeto está unido al ámbito global `navigator` , no estará disponible hasta después de la `deviceready` evento.
+
+    document.addEventListener ("deviceready", onDeviceReady, false);
+    function onDeviceReady() {console.log(navigator.camera)};
+    
+
+## Instalación
+
+    cordova plugin add cordova-plugin-camera
+    
+
+## API
+
+  * Cámara 
+      * navigator.camera.getPicture(success, fail, options)
+      * CameraOptions
+      * CameraPopoverHandle
+      * CameraPopoverOptions
+      * Navigator.Camera.Cleanup
+
+## navigator.camera.getPicture
+
+Toma una foto con la cámara, o recupera una foto de Galería de imágenes del dispositivo. La imagen se pasa a la devolución de llamada de éxito como un codificado en base64 `String` , o como el URI para el archivo de imagen. El método se devuelve un `CameraPopoverHandle` objeto que puede utilizarse para volver a colocar el popover de selección de archivo.
+
+    navigator.camera.getPicture(cameraSuccess, cameraError, cameraOptions);
+    
+
+#### Descripción
+
+El `camera.getPicture` función abre la aplicación de cámara predeterminada del dispositivo que permite a los usuarios ajustar imágenes. Este comportamiento se produce de forma predeterminada, cuando `Camera.sourceType` es igual a `Camera.PictureSourceType.CAMERA` . Una vez que el usuario ajusta la foto, una aplicación de cámara se cierra y se restablecerá la aplicación.
+
+Si `Camera.sourceType` es `Camera.PictureSourceType.PHOTOLIBRARY` o `Camera.PictureSourceType.SAVEDPHOTOALBUM` , entonces una muestra de diálogo que permite a los usuarios seleccionar una imagen existente. El `camera.getPicture` función devuelve un `CameraPopoverHandle` objeto, que puede utilizarse para volver a colocar el diálogo de selección de imagen, por ejemplo, cuando cambia la orientación del dispositivo.
+
+El valor devuelto es enviado a la `cameraSuccess` función de callback, en uno de los formatos siguientes, dependiendo del objeto `cameraOptions` :
+
+  * Una `String` que contiene la imagen codificada en base64.
+
+  * Una `String` que representa la ubicación del archivo de imagen en almacenamiento local (por defecto).
+
+Puedes hacer lo que quieras con la imagen codificada o URI, por ejemplo:
+
+  * Representar la imagen en una etiqueta de `<img>`, como en el ejemplo siguiente
+
+  * Guardar los datos localmente (`LocalStorage`, [Lawnchair](http://brianleroux.github.com/lawnchair/), etc.)
+
+  * Enviar los datos a un servidor remoto
+
+**Nota**: resolución de la foto en los nuevos dispositivos es bastante bueno. Fotos seleccionadas de la Galería del dispositivo no son degradadas a una calidad más baja, incluso si un `quality` se especifica el parámetro. Para evitar problemas con la memoria común, establezca `Camera.destinationType` a `FILE_URI` en lugar de`DATA_URL`.
+
+#### Plataformas soportadas
+
+![](doc/img/android-success.png) ![](doc/img/blackberry-success.png) ![](doc/img/browser-success.png) ![](doc/img/firefox-success.png) ![](doc/img/fireos-success.png) ![](doc/img/ios-success.png) ![](doc/img/windows-success.png) ![](doc/img/wp8-success.png) ![](doc/img/ubuntu-success.png)
+
+#### Ejemplo
+
+Tomar una foto y recuperarlo como una imagen codificada en base64:
+
+    navigator.camera.getPicture(onSuccess, onFail, { quality: 50,
+        destinationType: Camera.DestinationType.DATA_URL
+    });
+    
+    function onSuccess(imageData) {
+        var image = document.getElementById('myImage');
+        image.src = "data:image/jpeg;base64," + imageData;
+    }
+    
+    function onFail(message) {
+        alert('Failed because: ' + message);
+    }
+    
+
+Tomar una foto y recuperar la ubicación del archivo de la imagen:
+
+    navigator.camera.getPicture(onSuccess, onFail, { quality: 50,
+        destinationType: Camera.DestinationType.FILE_URI });
+    
+    function onSuccess(imageURI) {
+        var image = document.getElementById('myImage');
+        image.src = imageURI;
+    }
+    
+    function onFail(message) {
+        alert('Failed because: ' + message);
+    }
+    
+
+#### Preferencias (iOS)
+
+  * **CameraUsesGeolocation** (booleano, el valor predeterminado de false). Para la captura de imágenes JPEG, establecido en true para obtener datos de geolocalización en la cabecera EXIF. Esto activará la solicitud de permisos de geolocalización si establecido en true.
+    
+        <preference name="CameraUsesGeolocation" value="false" />
+        
+
+#### Amazon fuego OS rarezas
+
+Amazon fuego OS utiliza los intentos para poner en marcha la actividad de la cámara del dispositivo para capturar imágenes y en teléfonos con poca memoria, puede matar la actividad Cordova. En este escenario, la imagen no aparezca cuando se restaura la actividad cordova.
+
+#### Rarezas Android
+
+Android utiliza los intentos para iniciar la actividad de la cámara del dispositivo para capturar imágenes, y en los teléfonos con poca memoria, puede matar la actividad Cordova. En este escenario, la imagen no aparezca cuando se restaura la actividad Cordova.
+
+#### Navegador rarezas
+
+Sólo puede devolver fotos como imagen codificada en base64.
+
+#### Firefox OS rarezas
+
+Cámara plugin actualmente se implementa mediante [Actividades Web](https://hacks.mozilla.org/2013/01/introducing-web-activities/).
+
+#### iOS rarezas
+
+Incluyendo un JavaScript `alert()` en cualquiera de la devolución de llamada funciones pueden causar problemas. Envuelva la alerta dentro de un `setTimeout()` para permitir que el selector de imagen iOS o popover cerrar completamente antes de la alerta se muestra:
+
+    setTimeout(function() {
+        // do your thing here!
+    }, 0);
+    
+
+#### Windows Phone 7 rarezas
+
+Invocando la aplicación de cámara nativa mientras el dispositivo está conectado vía Zune no funciona y desencadena un callback de error.
+
+#### Rarezas Tizen
+
+Tizen sólo es compatible con un `destinationType` de `Camera.DestinationType.FILE_URI` y un `sourceType` de`Camera.PictureSourceType.PHOTOLIBRARY`.
+
+## CameraOptions
+
+Parámetros opcionales para personalizar la configuración de la cámara.
+
+    {calidad: destinationType 75,: Camera.DestinationType.DATA_URL, sourceType: Camera.PictureSourceType.CAMERA, allowEdit: true, encodingType: Camera.EncodingType.JPEG, targetWidth: 100, targetHeight: 100, popoverOptions: CameraPopoverOptions, saveToPhotoAlbum: falsa};
+    
+
+  * **calidad**: calidad de la imagen guardada, expresada en un rango de 0-100, donde 100 es típicamente resolución sin pérdida de compresión del archivo. El valor predeterminado es 50. *(Número)* (Tenga en cuenta que no está disponible información sobre resolución de la cámara).
+
+  * **destinationType**: elegir el formato del valor devuelto. El valor predeterminado es FILE_URI. Definido en `navigator.camera.DestinationType` *(número)*
+    
+        Camera.DestinationType = {
+            DATA_URL : 0,      // Return image as base64-encoded string
+            FILE_URI : 1,      // Return image file URI
+            NATIVE_URI : 2     // Return image native URI (e.g., assets-library:// on iOS or content:// on Android)
+        };
+        
+
+  * **sourceType**: establecer el origen de la imagen. El valor predeterminado es cámara. Definido en `navigator.camera.PictureSourceType` *(número)*
+    
+        Camera.PictureSourceType = {
+            PHOTOLIBRARY : 0,
+            CAMERA : 1,
+            SAVEDPHOTOALBUM : 2
+        };
+        
+
+  * **allowEdit**: permite edición sencilla de imagen antes de la selección. *(Booleano)*
+
+  * **encodingType**: elegir la codificación del archivo de imagen devuelta. Por defecto es JPEG. Definido en `navigator.camera.EncodingType` *(número)*
+    
+        Camera.EncodingType = {
+            JPEG : 0,               // Return JPEG encoded image
+            PNG : 1                 // Return PNG encoded image
+        };
+        
+
+  * **targetWidth**: ancho en píxeles a escala de la imagen. Debe usarse con **targetHeight**. Proporción se mantiene constante. *(Número)*
+
+  * **targetHeight**: altura en píxeles a escala de la imagen. Debe usarse con **targetWidth**. Proporción se mantiene constante. *(Número)*
+
+  * **mediaType**: definir el tipo de medios para seleccionar. Sólo funciona cuando `PictureSourceType` es `PHOTOLIBRARY` o `SAVEDPHOTOALBUM` . Definido en `nagivator.camera.MediaType` *(número)*
+    
+        Camera.MediaType = {
+            PICTURE: 0,    // allow selection of still pictures only. DE FORMA PREDETERMINADA. Will return format specified via DestinationType
+            VIDEO: 1,      // allow selection of video only, WILL ALWAYS RETURN FILE_URI
+            ALLMEDIA : 2   // allow selection from all media types
+        };
+        
+
+  * **correctOrientation**: rotar la imagen para corregir la orientación del dispositivo durante la captura. *(Booleano)*
+
+  * **saveToPhotoAlbum**: guardar la imagen en el álbum de fotos en el dispositivo después de su captura. *(Booleano)*
+
+  * **popoverOptions**: opciones sólo iOS que especifican popover ubicación en iPad. Definido en`CameraPopoverOptions`.
+
+  * **cameraDirection**: elegir la cámara para usar (o parte posterior-frontal). El valor predeterminado es atrás. Definido en `navigator.camera.Direction` *(número)*
+    
+        Camera.Direction = {
+            BACK : 0,      // Use the back-facing camera
+            FRONT : 1      // Use the front-facing camera
+        };
+        
+
+#### Amazon fuego OS rarezas
+
+  * Cualquier valor de `cameraDirection` da como resultado una foto orientada hacia atrás.
+
+  * Ignora el `allowEdit` parámetro.
+
+  * `Camera.PictureSourceType.PHOTOLIBRARY` y `Camera.PictureSourceType.SAVEDPHOTOALBUM` Mostrar el mismo álbum de fotos.
+
+#### Rarezas Android
+
+  * Cualquier valor de `cameraDirection` da como resultado una foto orientada hacia atrás.
+
+  * Android también utiliza la actividad de cultivo de allowEdit, aunque cultivo debe trabajar y realmente pasar la imagen recortada a Córdoba, el único que funciona constantemente es el integrado con la aplicación de Google Plus fotos. Otros cultivos pueden no funcionar.
+
+  * `Camera.PictureSourceType.PHOTOLIBRARY` y `Camera.PictureSourceType.SAVEDPHOTOALBUM` Mostrar el mismo álbum de fotos.
+
+#### BlackBerry 10 rarezas
+
+  * Ignora el `quality` parámetro.
+
+  * Ignora el `allowEdit` parámetro.
+
+  * `Camera.MediaType`No se admite.
+
+  * Ignora el `correctOrientation` parámetro.
+
+  * Ignora el `cameraDirection` parámetro.
+
+#### Firefox OS rarezas
+
+  * Ignora el `quality` parámetro.
+
+  * `Camera.DestinationType`se ignora y es igual a `1` (URI del archivo de imagen)
+
+  * Ignora el `allowEdit` parámetro.
+
+  * Ignora el `PictureSourceType` parámetro (el usuario lo elige en una ventana de diálogo)
+
+  * Ignora el`encodingType`
+
+  * Ignora el `targetWidth` y`targetHeight`
+
+  * `Camera.MediaType`No se admite.
+
+  * Ignora el `correctOrientation` parámetro.
+
+  * Ignora el `cameraDirection` parámetro.
+
+#### iOS rarezas
+
+  * Establecer `quality` por debajo de 50 para evitar errores de memoria en algunos dispositivos.
+
+  * Cuando se utiliza `destinationType.FILE_URI` , fotos se guardan en el directorio temporal de la aplicación. El contenido del directorio temporal de la aplicación se eliminará cuando finalice la aplicación.
+
+#### Rarezas Tizen
+
+  * opciones no compatibles
+
+  * siempre devuelve un identificador URI de archivo
+
+#### Windows Phone 7 y 8 rarezas
+
+  * Ignora el `allowEdit` parámetro.
+
+  * Ignora el `correctOrientation` parámetro.
+
+  * Ignora el `cameraDirection` parámetro.
+
+  * Ignora el `saveToPhotoAlbum` parámetro. IMPORTANTE: Todas las imágenes tomadas con la cámara wp7/8 cordova API siempre se copian en rollo de cámara del teléfono. Dependiendo de la configuración del usuario, esto podría significar también que la imagen es auto-subido a su OneDrive. Esto potencialmente podría significar que la imagen está disponible a una audiencia más amplia que su aplicación previsto. Si un bloqueador para su aplicación, usted necesitará aplicar el CameraCaptureTask como se documenta en msdn: <http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh394006.aspx> también puede comentar o votar hasta el tema relacionado en el [issue tracker de](https://issues.apache.org/jira/browse/CB-2083)
+
+  * Ignora el `mediaType` propiedad de `cameraOptions` como el SDK de Windows Phone no proporciona una manera para elegir vídeos fototeca.
+
+## CameraError
+
+onError función callback que proporciona un mensaje de error.
+
+    function(message) {
+        // Show a helpful message
+    }
+    
+
+#### Descripción
+
+  * **mensaje**: el mensaje es proporcionado por código nativo del dispositivo. *(String)*
+
+## cameraSuccess
+
+onSuccess función callback que proporciona los datos de imagen.
+
+    function(imageData) {
+        // Do something with the image
+    }
+    
+
+#### Descripción
+
+  * **imageData**: codificación en Base64 de los datos de imagen, *o* el archivo de imagen URI, dependiendo de `cameraOptions` en vigor. *(String)*
+
+#### Ejemplo
+
+    // Show image
+    //
+    function cameraCallback(imageData) {
+        var image = document.getElementById('myImage');
+        image.src = "data:image/jpeg;base64," + imageData;
+    }
+    
+
+## CameraPopoverHandle
+
+Un identificador para el cuadro de diálogo popover creado por`navigator.camera.getPicture`.
+
+#### Descripción
+
+  * **setPosition**: Set the position of the popover. Takes the `CameraPopoverOptions` that specify the new position.
+
+#### Plataformas soportadas
+
+![](doc/img/android-fail.png) ![](doc/img/blackberry-fail.png) ![](doc/img/browser-fail.png) ![](doc/img/firefox-fail.png) ![](doc/img/fireos-fail.png) ![](doc/img/ios-success.png) ![](doc/img/windows-fail.png) ![](doc/img/wp8-fail.png) ![](doc/img/ubuntu-fail.png)
+
+#### Ejemplo
+
+     var cameraPopoverHandle = navigator.camera.getPicture(onSuccess, onFail,
+         { destinationType: Camera.DestinationType.FILE_URI,
+           sourceType: Camera.PictureSourceType.PHOTOLIBRARY,
+           popoverOptions: new CameraPopoverOptions(300, 300, 100, 100, Camera.PopoverArrowDirection.ARROW_ANY)
+         });
+    
+     // Reposition the popover if the orientation changes.
+     window.onorientationchange = function() {
+         var cameraPopoverOptions = new CameraPopoverOptions(0, 0, 100, 100, Camera.PopoverArrowDirection.ARROW_ANY);
+         cameraPopoverHandle.setPosition(cameraPopoverOptions);
+     }
+    
+
+## CameraPopoverOptions
+
+Sólo iOS parámetros que especifican la dirección ancla elemento ubicación y la flecha de la popover al seleccionar imágenes de biblioteca o álbum de un iPad.
+
+    { x : 0,
+      y :  32,
+      width : 320,
+      height : 480,
+      arrowDir : Camera.PopoverArrowDirection.ARROW_ANY
+    };
+    
+
+#### Descripción
+
+  * **x**: coordenadas de píxeles del elemento de la pantalla en la que anclar el popover x. *(Número)*
+
+  * **y**: coordenada píxeles del elemento de la pantalla en la que anclar el popover. *(Número)*
+
+  * **anchura**: anchura, en píxeles, del elemento sobre el que anclar el popover pantalla. *(Número)*
+
+  * **altura**: alto, en píxeles, del elemento sobre el que anclar el popover pantalla. *(Número)*
+
+  * **arrowDir**: dirección de la flecha en el popover debe apuntar. Definido en `Camera.PopoverArrowDirection` *(número)*
+    
+            Camera.PopoverArrowDirection = {
+                ARROW_UP : 1,        // matches iOS UIPopoverArrowDirection constants
+                ARROW_DOWN : 2,
+                ARROW_LEFT : 4,
+                ARROW_RIGHT : 8,
+                ARROW_ANY : 15
+            };
+        
+
+Tenga en cuenta que puede cambiar el tamaño de la popover para ajustar la dirección de la flecha y orientación de la pantalla. Asegúrese de que para tener en cuenta los cambios de orientación cuando se especifica la ubicación del elemento de anclaje.
+
+## Navigator.Camera.Cleanup
+
+Elimina intermedio fotos tomadas por la cámara de almacenamiento temporal.
+
+    Navigator.Camera.cleanup (cameraSuccess, cameraError);
+    
+
+#### Descripción
+
+Elimina intermedio archivos de imagen que se mantienen en depósito temporal después de llamar `camera.getPicture` . Se aplica sólo cuando el valor de `Camera.sourceType` es igual a `Camera.PictureSourceType.CAMERA` y el `Camera.destinationType` es igual a`Camera.DestinationType.FILE_URI`.
+
+#### Plataformas soportadas
+
+![](doc/img/android-fail.png) ![](doc/img/blackberry-fail.png) ![](doc/img/browser-fail.png) ![](doc/img/firefox-fail.png) ![](doc/img/fireos-fail.png) ![](doc/img/ios-success.png) ![](doc/img/windows-fail.png) ![](doc/img/wp8-fail.png) ![](doc/img/ubuntu-fail.png)
+
+#### Ejemplo
+
+    navigator.camera.cleanup(onSuccess, onFail);
+    
+    function onSuccess() {
+        console.log("Camera cleanup success.")
+    }
+    
+    function onFail(message) {
+        alert('Failed because: ' + message);
+    }

+ 391 - 0
miaomiao/plugins/cordova-plugin-camera/doc/es/index.md

xqd
@@ -0,0 +1,391 @@
+<!---
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+-->
+
+# cordova-plugin-camera
+
+Este plugin define un global `navigator.camera` objeto que proporciona una API para tomar fotografías y por elegir imágenes de biblioteca de imágenes del sistema.
+
+Aunque el objeto está unido al ámbito global `navigator` , no estará disponible hasta después de la `deviceready` evento.
+
+    document.addEventListener ("deviceready", onDeviceReady, false);
+    function onDeviceReady() {console.log(navigator.camera)};
+    
+
+## Instalación
+
+    Cordova plugin agregar cordova-plugin-camera
+    
+
+## navigator.camera.getPicture
+
+Toma una foto con la cámara, o recupera una foto de Galería de imágenes del dispositivo. La imagen se pasa a la devolución de llamada de éxito como un codificado en base64 `String` , o como el URI para el archivo de imagen. El método se devuelve un `CameraPopoverHandle` objeto que puede utilizarse para volver a colocar el popover de selección de archivo.
+
+    navigator.camera.getPicture (cameraSuccess, cameraError, cameraOptions);
+    
+
+### Descripción
+
+El `camera.getPicture` función abre la aplicación de cámara predeterminada del dispositivo que permite a los usuarios ajustar imágenes. Este comportamiento se produce de forma predeterminada, cuando `Camera.sourceType` es igual a `Camera.PictureSourceType.CAMERA` . Una vez que el usuario ajusta la foto, una aplicación de cámara se cierra y se restablecerá la aplicación.
+
+Si `Camera.sourceType` es `Camera.PictureSourceType.PHOTOLIBRARY` o `Camera.PictureSourceType.SAVEDPHOTOALBUM` , entonces una muestra de diálogo que permite a los usuarios seleccionar una imagen existente. El `camera.getPicture` función devuelve un `CameraPopoverHandle` objeto, que puede utilizarse para volver a colocar el diálogo de selección de imagen, por ejemplo, cuando cambia la orientación del dispositivo.
+
+El valor devuelto es enviado a la `cameraSuccess` función de callback, en uno de los formatos siguientes, dependiendo del objeto `cameraOptions` :
+
+*   Una `String` que contiene la imagen codificada en base64.
+
+*   Una `String` que representa la ubicación del archivo de imagen en almacenamiento local (por defecto).
+
+Puedes hacer lo que quieras con la imagen codificada o URI, por ejemplo:
+
+*   Representar la imagen en una etiqueta de `<img>`, como en el ejemplo siguiente
+
+*   Guardar los datos localmente (`LocalStorage`, [Lawnchair][1], etc.)
+
+*   Enviar los datos a un servidor remoto
+
+ [1]: http://brianleroux.github.com/lawnchair/
+
+**Nota**: resolución de la foto en los nuevos dispositivos es bastante bueno. Fotos seleccionadas de la Galería del dispositivo no son degradadas a una calidad más baja, incluso si un `quality` se especifica el parámetro. Para evitar problemas con la memoria común, establezca `Camera.destinationType` a `FILE_URI` en lugar de`DATA_URL`.
+
+### Plataformas soportadas
+
+*   Amazon fire OS
+*   Android
+*   BlackBerry 10
+*   Explorador
+*   Firefox OS
+*   iOS
+*   Tizen
+*   Windows Phone 7 y 8
+*   Windows 8
+
+### Preferencias (iOS)
+
+*   **CameraUsesGeolocation** (booleano, el valor predeterminado de false). Para la captura de imágenes JPEG, establecido en true para obtener datos de geolocalización en la cabecera EXIF. Esto activará la solicitud de permisos de geolocalización si establecido en true.
+    
+        <preference name="CameraUsesGeolocation" value="false" />
+        
+
+### Amazon fuego OS rarezas
+
+Amazon fuego OS utiliza los intentos para poner en marcha la actividad de la cámara del dispositivo para capturar imágenes y en teléfonos con poca memoria, puede matar la actividad Cordova. En este escenario, la imagen no aparezca cuando se restaura la actividad cordova.
+
+### Rarezas Android
+
+Android utiliza los intentos para iniciar la actividad de la cámara del dispositivo para capturar imágenes, y en los teléfonos con poca memoria, puede matar la actividad Cordova. En este escenario, la imagen no aparezca cuando se restaura la actividad Cordova.
+
+### Navegador rarezas
+
+Sólo puede devolver fotos como imagen codificada en base64.
+
+### Firefox OS rarezas
+
+Cámara plugin actualmente se implementa mediante [Actividades Web][2].
+
+ [2]: https://hacks.mozilla.org/2013/01/introducing-web-activities/
+
+### iOS rarezas
+
+Incluyendo un JavaScript `alert()` en cualquiera de la devolución de llamada funciones pueden causar problemas. Envuelva la alerta dentro de un `setTimeout()` para permitir que el selector de imagen iOS o popover cerrar completamente antes de la alerta se muestra:
+
+    setTimeout(function() {/ / Haz lo tuyo aquí!}, 0);
+    
+
+### Windows Phone 7 rarezas
+
+Invocando la aplicación de cámara nativa mientras el dispositivo está conectado vía Zune no funciona y desencadena un callback de error.
+
+### Rarezas Tizen
+
+Tizen sólo es compatible con un `destinationType` de `Camera.DestinationType.FILE_URI` y un `sourceType` de`Camera.PictureSourceType.PHOTOLIBRARY`.
+
+### Ejemplo
+
+Tomar una foto y recuperarlo como una imagen codificada en base64:
+
+    navigator.camera.getPicture (onSuccess, onFail, { quality: 50,
+        destinationType: Camera.DestinationType.DATA_URL
+    });
+    
+    function onSuccess(imageData) {var imagen = document.getElementById('myImage');
+        Image.src = "datos: image / jpeg; base64," + imageData;}
+    
+    function onFail(message) {alert (' falló porque: ' + mensaje);}
+    
+
+Tomar una foto y recuperar la ubicación del archivo de la imagen:
+
+    navigator.camera.getPicture (onSuccess, onFail, { quality: 50,
+        destinationType: Camera.DestinationType.FILE_URI });
+    
+    function onSuccess(imageURI) {var imagen = document.getElementById('myImage');
+        Image.src = imageURI;
+    } function onFail(message) {alert (' falló porque: ' + mensaje);}
+    
+
+## CameraOptions
+
+Parámetros opcionales para personalizar la configuración de la cámara.
+
+    {calidad: destinationType 75,: Camera.DestinationType.DATA_URL, sourceType: Camera.PictureSourceType.CAMERA, allowEdit: true, encodingType: Camera.EncodingType.JPEG, targetWidth: 100, targetHeight: 100, popoverOptions: CameraPopoverOptions, saveToPhotoAlbum: falsa};
+    
+
+### Opciones
+
+*   **calidad**: calidad de la imagen guardada, expresada en un rango de 0-100, donde 100 es típicamente resolución sin pérdida de compresión del archivo. El valor predeterminado es 50. *(Número)* (Tenga en cuenta que no está disponible información sobre resolución de la cámara).
+
+*   **destinationType**: elegir el formato del valor devuelto. El valor predeterminado es FILE_URI. Definido en `navigator.camera.DestinationType` *(número)*
+    
+        Camera.DestinationType = {
+            DATA_URL : 0,      // Return image as base64-encoded string
+            FILE_URI : 1,      // Return image file URI
+            NATIVE_URI : 2     // Return image native URI (e.g., assets-library:// on iOS or content:// on Android)
+        };
+        
+
+*   **sourceType**: establecer el origen de la imagen. El valor predeterminado es cámara. Definido en `navigator.camera.PictureSourceType` *(número)*
+    
+        Camera.PictureSourceType = {
+            PHOTOLIBRARY : 0,
+            CAMERA : 1,
+            SAVEDPHOTOALBUM : 2
+        };
+        
+
+*   **allowEdit**: permite edición sencilla de imagen antes de la selección. *(Booleano)*
+
+*   **encodingType**: elegir la codificación del archivo de imagen devuelta. Por defecto es JPEG. Definido en `navigator.camera.EncodingType` *(número)*
+    
+        Camera.EncodingType = {
+            JPEG : 0,               // Return JPEG encoded image
+            PNG : 1                 // Return PNG encoded image
+        };
+        
+
+*   **targetWidth**: ancho en píxeles a escala de la imagen. Debe usarse con **targetHeight**. Proporción se mantiene constante. *(Número)*
+
+*   **targetHeight**: altura en píxeles a escala de la imagen. Debe usarse con **targetWidth**. Proporción se mantiene constante. *(Número)*
+
+*   **mediaType**: definir el tipo de medios para seleccionar. Sólo funciona cuando `PictureSourceType` es `PHOTOLIBRARY` o `SAVEDPHOTOALBUM` . Definido en `nagivator.camera.MediaType` *(número)*
+    
+        Camera.MediaType = {
+            PICTURE: 0,    // allow selection of still pictures only. DE FORMA PREDETERMINADA. Will return format specified via DestinationType
+            VIDEO: 1,      // allow selection of video only, WILL ALWAYS RETURN FILE_URI
+            ALLMEDIA : 2   // allow selection from all media types
+        };
+        
+
+*   **correctOrientation**: rotar la imagen para corregir la orientación del dispositivo durante la captura. *(Booleano)*
+
+*   **saveToPhotoAlbum**: guardar la imagen en el álbum de fotos en el dispositivo después de su captura. *(Booleano)*
+
+*   **popoverOptions**: opciones sólo iOS que especifican popover ubicación en iPad. Definido en`CameraPopoverOptions`.
+
+*   **cameraDirection**: elegir la cámara para usar (o parte posterior-frontal). El valor predeterminado es atrás. Definido en `navigator.camera.Direction` *(número)*
+    
+        Camera.Direction = {
+            BACK : 0,      // Use the back-facing camera
+            FRONT : 1      // Use the front-facing camera
+        };
+        
+
+### Amazon fuego OS rarezas
+
+*   Cualquier valor de `cameraDirection` da como resultado una foto orientada hacia atrás.
+
+*   Ignora el `allowEdit` parámetro.
+
+*   `Camera.PictureSourceType.PHOTOLIBRARY` y `Camera.PictureSourceType.SAVEDPHOTOALBUM` Mostrar el mismo álbum de fotos.
+
+### Rarezas Android
+
+*   Cualquier valor de `cameraDirection` da como resultado una foto orientada hacia atrás.
+
+*   Ignora el `allowEdit` parámetro.
+
+*   `Camera.PictureSourceType.PHOTOLIBRARY` y `Camera.PictureSourceType.SAVEDPHOTOALBUM` Mostrar el mismo álbum de fotos.
+
+### BlackBerry 10 rarezas
+
+*   Ignora el `quality` parámetro.
+
+*   Ignora el `allowEdit` parámetro.
+
+*   `Camera.MediaType`No se admite.
+
+*   Ignora el `correctOrientation` parámetro.
+
+*   Ignora el `cameraDirection` parámetro.
+
+### Firefox OS rarezas
+
+*   Ignora el `quality` parámetro.
+
+*   `Camera.DestinationType`se ignora y es igual a `1` (URI del archivo de imagen)
+
+*   Ignora el `allowEdit` parámetro.
+
+*   Ignora el `PictureSourceType` parámetro (el usuario lo elige en una ventana de diálogo)
+
+*   Ignora el`encodingType`
+
+*   Ignora el `targetWidth` y`targetHeight`
+
+*   `Camera.MediaType`No se admite.
+
+*   Ignora el `correctOrientation` parámetro.
+
+*   Ignora el `cameraDirection` parámetro.
+
+### iOS rarezas
+
+*   Establecer `quality` por debajo de 50 para evitar errores de memoria en algunos dispositivos.
+
+*   Cuando se utiliza `destinationType.FILE_URI` , fotos se guardan en el directorio temporal de la aplicación. El contenido del directorio temporal de la aplicación se eliminará cuando finalice la aplicación.
+
+### Rarezas Tizen
+
+*   opciones no compatibles
+
+*   siempre devuelve un identificador URI de archivo
+
+### Windows Phone 7 y 8 rarezas
+
+*   Ignora el `allowEdit` parámetro.
+
+*   Ignora el `correctOrientation` parámetro.
+
+*   Ignora el `cameraDirection` parámetro.
+
+*   Ignora el `saveToPhotoAlbum` parámetro. IMPORTANTE: Todas las imágenes tomadas con la cámara wp7/8 cordova API siempre se copian en rollo de cámara del teléfono. Dependiendo de la configuración del usuario, esto podría significar también que la imagen es auto-subido a su OneDrive. Esto potencialmente podría significar que la imagen está disponible a una audiencia más amplia que su aplicación previsto. Si un bloqueador para su aplicación, usted necesitará aplicar el CameraCaptureTask como se documenta en msdn: <http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh394006.aspx> también puede comentar o votar hasta el tema relacionado en el [issue tracker de][3]
+
+*   Ignora el `mediaType` propiedad de `cameraOptions` como el SDK de Windows Phone no proporciona una manera para elegir vídeos fototeca.
+
+ [3]: https://issues.apache.org/jira/browse/CB-2083
+
+## CameraError
+
+onError función callback que proporciona un mensaje de error.
+
+    function(Message) {/ / Mostrar un mensaje útil}
+    
+
+### Parámetros
+
+*   **mensaje**: el mensaje es proporcionado por código nativo del dispositivo. *(String)*
+
+## cameraSuccess
+
+onSuccess función callback que proporciona los datos de imagen.
+
+    function(ImageData) {/ / hacer algo con la imagen}
+    
+
+### Parámetros
+
+*   **imageData**: codificación en Base64 de los datos de imagen, *o* el archivo de imagen URI, dependiendo de `cameraOptions` en vigor. *(String)*
+
+### Ejemplo
+
+    Mostrar imagen / / function cameraCallback(imageData) {var imagen = document.getElementById('myImage');
+        Image.src = "datos: image / jpeg; base64," + imageData;}
+    
+
+## CameraPopoverHandle
+
+Un identificador para el cuadro de diálogo popover creado por`navigator.camera.getPicture`.
+
+### Métodos
+
+*   **setPosition**: establecer la posición de la popover.
+
+### Plataformas soportadas
+
+*   iOS
+
+### setPosition
+
+Establecer la posición de la popover.
+
+**Parámetros**:
+
+*   `cameraPopoverOptions`: el `CameraPopoverOptions` que especifican la nueva posición
+
+### Ejemplo
+
+     var cameraPopoverHandle = navigator.camera.getPicture (onSuccess, onFail, {destinationType: Camera.DestinationType.FILE_URI, sourceType: Camera.PictureSourceType.PHOTOLIBRARY, popoverOptions: CameraPopoverOptions nuevo (300, 300, 100, 100, Camera.PopoverArrowDirection.ARROW_ANY)});
+    
+     Vuelva a colocar el popover si cambia la orientación.
+     Window.onorientationchange = function() {var cameraPopoverOptions = new CameraPopoverOptions (0, 0, 100, 100, Camera.PopoverArrowDirection.ARROW_ANY);
+         cameraPopoverHandle.setPosition(cameraPopoverOptions);
+     }
+    
+
+## CameraPopoverOptions
+
+Sólo iOS parámetros que especifican la dirección ancla elemento ubicación y la flecha de la popover al seleccionar imágenes de biblioteca o álbum de un iPad.
+
+    {x: 0, y: 32, ancho: 320, altura: 480, arrowDir: Camera.PopoverArrowDirection.ARROW_ANY};
+    
+
+### CameraPopoverOptions
+
+*   **x**: coordenadas de píxeles del elemento de la pantalla en la que anclar el popover x. *(Número)*
+
+*   **y**: coordenada píxeles del elemento de la pantalla en la que anclar el popover. *(Número)*
+
+*   **anchura**: anchura, en píxeles, del elemento sobre el que anclar el popover pantalla. *(Número)*
+
+*   **altura**: alto, en píxeles, del elemento sobre el que anclar el popover pantalla. *(Número)*
+
+*   **arrowDir**: dirección de la flecha en el popover debe apuntar. Definido en `Camera.PopoverArrowDirection` *(número)*
+    
+            Camera.PopoverArrowDirection = {
+                ARROW_UP : 1,        // matches iOS UIPopoverArrowDirection constants
+                ARROW_DOWN : 2,
+                ARROW_LEFT : 4,
+                ARROW_RIGHT : 8,
+                ARROW_ANY : 15
+            };
+        
+
+Tenga en cuenta que puede cambiar el tamaño de la popover para ajustar la dirección de la flecha y orientación de la pantalla. Asegúrese de que para tener en cuenta los cambios de orientación cuando se especifica la ubicación del elemento de anclaje.
+
+## Navigator.Camera.Cleanup
+
+Elimina intermedio fotos tomadas por la cámara de almacenamiento temporal.
+
+    Navigator.Camera.cleanup (cameraSuccess, cameraError);
+    
+
+### Descripción
+
+Elimina intermedio archivos de imagen que se mantienen en depósito temporal después de llamar `camera.getPicture` . Se aplica sólo cuando el valor de `Camera.sourceType` es igual a `Camera.PictureSourceType.CAMERA` y el `Camera.destinationType` es igual a`Camera.DestinationType.FILE_URI`.
+
+### Plataformas soportadas
+
+*   iOS
+
+### Ejemplo
+
+    Navigator.Camera.cleanup (onSuccess, onFail);
+    
+    function onSuccess() {console.log ("cámara limpieza éxito.")}
+    
+    function onFail(message) {alert (' falló porque: ' + mensaje);}

+ 378 - 0
miaomiao/plugins/cordova-plugin-camera/doc/fr/README.md

xqd
@@ -0,0 +1,378 @@
+<!---
+# license: Licensed to the Apache Software Foundation (ASF) under one
+#         or more contributor license agreements.  See the NOTICE file
+#         distributed with this work for additional information
+#         regarding copyright ownership.  The ASF licenses this file
+#         to you under the Apache License, Version 2.0 (the
+#         "License"); you may not use this file except in compliance
+#         with the License.  You may obtain a copy of the License at
+#
+#           http://www.apache.org/licenses/LICENSE-2.0
+#
+#         Unless required by applicable law or agreed to in writing,
+#         software distributed under the License is distributed on an
+#         "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#         KIND, either express or implied.  See the License for the
+#         specific language governing permissions and limitations
+#         under the License.
+-->
+
+# cordova-plugin-camera
+
+[![Build Status](https://travis-ci.org/apache/cordova-plugin-camera.svg)](https://travis-ci.org/apache/cordova-plugin-camera)
+
+Ce plugin définit un global `navigator.camera` objet qui fournit une API pour la prise de photos et de choisir des images de la bibliothèque d'images du système.
+
+Bien que l'objet est attaché à la portée globale `navigator` , il n'est pas disponible jusqu'après la `deviceready` événement.
+
+    document.addEventListener (« deviceready », onDeviceReady, false) ;
+    function onDeviceReady() {console.log(navigator.camera);}
+    
+
+## Installation
+
+    cordova plugin add cordova-plugin-camera
+    
+
+## API
+
+  * Appareil photo 
+      * navigator.camera.getPicture(success, fail, options)
+      * CameraOptions
+      * CameraPopoverHandle
+      * CameraPopoverOptions
+      * Navigator.Camera.Cleanup
+
+## navigator.camera.getPicture
+
+Prend une photo à l'aide de la caméra, ou récupère une photo de la Galerie d'images de l'appareil. L'image est passé au rappel succès comme un codage base64 `String` , ou comme l'URI du fichier de l'image. La méthode elle-même retourne un `CameraPopoverHandle` objet qui permet de repositionner le kangourou de sélection de fichier.
+
+    navigator.camera.getPicture(cameraSuccess, cameraError, cameraOptions);
+    
+
+#### Description
+
+Le `camera.getPicture` fonction ouvre l'application de caméra par défaut de l'appareil qui permet aux utilisateurs de prendre des photos. Ce comportement se produit par défaut, lorsque `Camera.sourceType` est égal à `Camera.PictureSourceType.CAMERA` . Une fois que l'utilisateur s'enclenche la photo, l'application appareil photo se ferme et l'application est restaurée.
+
+Si `Camera.sourceType` est `Camera.PictureSourceType.PHOTOLIBRARY` ou `Camera.PictureSourceType.SAVEDPHOTOALBUM` , puis un dialogue affiche qui permet aux utilisateurs de sélectionner une image existante. Le `camera.getPicture` retourne un `CameraPopoverHandle` objet, ce qui permet de repositionner le dialogue de sélection d'image, par exemple, lorsque l'orientation de l'appareil change.
+
+La valeur de retour est envoyée à la `cameraSuccess` la fonction de rappel, dans l'un des formats suivants, selon les `cameraOptions` :
+
+  * A `String` contenant l'image photo codée en base64.
+
+  * A `String` qui représente l'emplacement du fichier image sur le stockage local (par défaut).
+
+Vous pouvez faire ce que vous voulez avec l'image codée ou URI, par exemple :
+
+  * Afficher l'image dans un `<img>` tag, comme dans l'exemple ci-dessous
+
+  * Enregistrer les données localement ( `LocalStorage` , [poids](http://brianleroux.github.com/lawnchair/), etc..)
+
+  * Publier les données sur un serveur distant
+
+**NOTE**: la résolution de Photo sur les nouveaux appareils est assez bonne. Photos sélectionnées de la Galerie de l'appareil ne sont pas réduites à une baisse de la qualité, même si un `quality` paramètre est spécifié. Pour éviter les problèmes de mémoire commun, définissez `Camera.destinationType` à `FILE_URI` au lieu de`DATA_URL`.
+
+#### Plates-formes supportées
+
+![](doc/img/android-success.png) ![](doc/img/blackberry-success.png) ![](doc/img/browser-success.png) ![](doc/img/firefox-success.png) ![](doc/img/fireos-success.png) ![](doc/img/ios-success.png) ![](doc/img/windows-success.png) ![](doc/img/wp8-success.png) ![](doc/img/ubuntu-success.png)
+
+#### Exemple
+
+Prendre une photo, puis extrayez-la comme une image codée en base64 :
+
+    navigator.camera.getPicture (onSuccess, onFail, { quality: 50,
+        destinationType: Camera.DestinationType.DATA_URL
+    }) ;
+    
+    function onSuccess(imageData) {var image = document.getElementById('myImage') ;
+        image.src = "données : image / jpeg ; base64," + imageData;}
+    
+    function onFail(message) {alert (' a échoué car: "+ message);}
+    
+
+Prendre une photo et récupérer l'emplacement du fichier de l'image :
+
+    navigator.camera.getPicture (onSuccess, onFail, { quality: 50,
+        destinationType: Camera.DestinationType.FILE_URI }) ;
+    
+    function onSuccess(imageURI) {var image = document.getElementById('myImage') ;
+        image.SRC = imageURI ;
+    } function onFail(message) {alert (' a échoué car: "+ message);}
+    
+
+#### Préférences (iOS)
+
+  * **CameraUsesGeolocation** (boolean, par défaut, false). Pour capturer des images JPEG, true pour obtenir des données de géolocalisation dans l'en-tête EXIF. Cela va déclencher une demande d'autorisations de géolocalisation si défini à true.
+    
+        <preference name="CameraUsesGeolocation" value="false" />
+        
+
+#### Amazon Fire OS Quirks
+
+Amazon Fire OS utilise des intentions pour lancer l'activité de l'appareil photo sur l'appareil pour capturer des images et sur les téléphones avec peu de mémoire, l'activité de Cordova peut être tuée. Dans ce scénario, l'image peut ne pas apparaître lorsque l'activité de cordova est restaurée.
+
+#### Quirks Android
+
+Android utilise des intentions pour lancer l'activité de l'appareil photo sur l'appareil pour capturer des images et sur les téléphones avec peu de mémoire, l'activité de Cordova peut être tuée. Dans ce scénario, l'image peut ne pas apparaître lorsque l'activité de Cordova est restaurée.
+
+#### Bizarreries navigateur
+
+Peut retourner uniquement les photos comme image codée en base64.
+
+#### Firefox OS Quirks
+
+Appareil photo plugin est actuellement mis en œuvre à l'aide [d'Activités sur le Web](https://hacks.mozilla.org/2013/01/introducing-web-activities/).
+
+#### Notes au sujet d'iOS
+
+Y compris un JavaScript `alert()` dans les deux le rappel fonctions peuvent causer des problèmes. Envelopper l'alerte dans un `setTimeout()` pour permettre le sélecteur d'image iOS ou kangourou pour fermer entièrement avant que l'alerte s'affiche :
+
+    setTimeout(function() {/ / faire votre truc ici!}, 0) ;
+    
+
+#### Windows Phone 7 Quirks
+
+Invoquant l'application native caméra alors que l'appareil est connecté via Zune ne fonctionne pas et déclenche un rappel de l'erreur.
+
+#### Bizarreries de paciarelli
+
+Paciarelli prend uniquement en charge un `destinationType` de `Camera.DestinationType.FILE_URI` et un `sourceType` de`Camera.PictureSourceType.PHOTOLIBRARY`.
+
+## CameraOptions
+
+Paramètres optionnels pour personnaliser les réglages de l'appareil.
+
+    {qualité : destinationType 75,: Camera.DestinationType.DATA_URL, TypeSource : Camera.PictureSourceType.CAMERA, allowEdit : encodingType vrai,: Camera.EncodingType.JPEG, targetWidth : 100, targetHeight : 100, popoverOptions : CameraPopoverOptions, saveToPhotoAlbum : false} ;
+    
+
+  * **qualité**: qualité de l'image enregistrée, exprimée en une gamme de 0 à 100, 100 étant généralement pleine résolution sans perte de compression de fichiers. La valeur par défaut est 50. *(Nombre)* (Notez que les informations sur la résolution de la caméra sont indisponibles).
+
+  * **destinationType**: choisissez le format de la valeur de retour. La valeur par défaut est FILE_URI. Définies dans `navigator.camera.DestinationType` *(nombre)*
+    
+        Camera.DestinationType = {
+            DATA_URL : 0,      // Return image as base64-encoded string
+            FILE_URI : 1,      // Return image file URI
+            NATIVE_URI : 2     // Return image native URI (e.g., assets-library:// on iOS or content:// on Android)
+        };
+        
+
+  * **sourceType**: définissez la source de l'image. La valeur par défaut est la caméra. Définies dans `navigator.camera.PictureSourceType` *(nombre)*
+    
+        Camera.PictureSourceType = {
+            PHOTOLIBRARY : 0,
+            CAMERA : 1,
+            SAVEDPHOTOALBUM : 2
+        };
+        
+
+  * **allowEdit**: permettre un montage simple d'image avant la sélection. *(Booléen)*
+
+  * **encodingType**: choisir le fichier image retournée de codage. Valeur par défaut est JPEG. Définies dans `navigator.camera.EncodingType` *(nombre)*
+    
+        Camera.EncodingType = {
+            JPEG : 0,               // Return JPEG encoded image
+            PNG : 1                 // Return PNG encoded image
+        };
+        
+
+  * **targetWidth**: largeur en pixels de l'image de l'échelle. Doit être utilisé avec **targetHeight**. Aspect ratio reste constant. *(Nombre)*
+
+  * **targetHeight**: hauteur en pixels de l'image de l'échelle. Doit être utilisé avec **targetWidth**. Aspect ratio reste constant. *(Nombre)*
+
+  * **mediaType**: définir le type de média pour choisir de. Ne fonctionne que quand `PictureSourceType` est `PHOTOLIBRARY` ou `SAVEDPHOTOALBUM` . Définies dans `nagivator.camera.MediaType` *(nombre)*
+    
+        Camera.MediaType = {
+            PICTURE: 0,    // allow selection of still pictures only. PAR DÉFAUT. Will return format specified via DestinationType
+            VIDEO: 1,      // allow selection of video only, WILL ALWAYS RETURN FILE_URI
+            ALLMEDIA : 2   // allow selection from all media types
+        };
+        
+
+  * **correctOrientation**: faire pivoter l'image afin de corriger l'orientation de l'appareil lors de la capture. *(Booléen)*
+
+  * **saveToPhotoAlbum**: enregistrer l'image sur l'album photo sur l'appareil après la capture. *(Booléen)*
+
+  * **popoverOptions**: iOS uniquement des options qui spécifient l'emplacement de kangourou dans iPad. Défini dans`CameraPopoverOptions`.
+
+  * **cameraDirection**: choisissez la caméra à utiliser (ou dos-face). La valeur par défaut est de retour. Définies dans `navigator.camera.Direction` *(nombre)*
+    
+        Camera.Direction = {
+            BACK : 0,      // Use the back-facing camera
+            FRONT : 1      // Use the front-facing camera
+        };
+        
+
+#### Amazon Fire OS Quirks
+
+  * Tout `cameraDirection` résultats dans le back-face photo de valeur.
+
+  * Ignore la `allowEdit` paramètre.
+
+  * `Camera.PictureSourceType.PHOTOLIBRARY`et `Camera.PictureSourceType.SAVEDPHOTOALBUM` les deux affichent le même album photo.
+
+#### Quirks Android
+
+  * Tout `cameraDirection` résultats dans le back-face photo de valeur.
+
+  * Android utilise également l'activité de récolte pour allowEdit, même si la récolte doit travailler et transmet en réalité l'image recadrée à Cordoue, le seul que les œuvres sont toujours celui livré avec l'application Google Plus Photos. Autres cultures peuvent ne pas fonctionner.
+
+  * `Camera.PictureSourceType.PHOTOLIBRARY`et `Camera.PictureSourceType.SAVEDPHOTOALBUM` les deux affichent le même album photo.
+
+#### BlackBerry 10 Quirks
+
+  * Ignore la `quality` paramètre.
+
+  * Ignore la `allowEdit` paramètre.
+
+  * `Camera.MediaType`n'est pas pris en charge.
+
+  * Ignore la `correctOrientation` paramètre.
+
+  * Ignore la `cameraDirection` paramètre.
+
+#### Firefox OS Quirks
+
+  * Ignore la `quality` paramètre.
+
+  * `Camera.DestinationType`est ignorée et est égal à `1` (URI du fichier image)
+
+  * Ignore la `allowEdit` paramètre.
+
+  * Ignore la `PictureSourceType` paramètre (utilisateur il choisit dans une fenêtre de dialogue)
+
+  * Ignore le`encodingType`
+
+  * Ignore la `targetWidth` et`targetHeight`
+
+  * `Camera.MediaType`n'est pas pris en charge.
+
+  * Ignore la `correctOrientation` paramètre.
+
+  * Ignore la `cameraDirection` paramètre.
+
+#### Notes au sujet d'iOS
+
+  * La valeur `quality` inférieur à 50 pour éviter les erreurs de mémoire sur certains appareils.
+
+  * Lorsque vous utilisez `destinationType.FILE_URI` , les photos sont sauvegardées dans le répertoire temporaire de l'application. Le contenu du répertoire temporaire de l'application est supprimé lorsque l'application se termine.
+
+#### Bizarreries de paciarelli
+
+  * options non prises en charge
+
+  * retourne toujours un URI de fichier
+
+#### Notes au sujet de Windows Phone 7 et 8
+
+  * Ignore la `allowEdit` paramètre.
+
+  * Ignore la `correctOrientation` paramètre.
+
+  * Ignore la `cameraDirection` paramètre.
+
+  * Ignore la `saveToPhotoAlbum` paramètre. IMPORTANT : Toutes les images prises avec la caméra de cordova wp7/8 API sont toujours copiés au rôle d'appareil photo du téléphone. Selon les paramètres de l'utilisateur, cela pourrait également signifier que l'image est auto-téléchargées à leur OneDrive. Potentiellement, cela pourrait signifier que l'image est disponible à un public plus large que votre application destinée. Si ce un bloqueur pour votre application, vous devrez implémenter le CameraCaptureTask tel que documenté sur msdn : <http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh394006.aspx> vous pouvez aussi commenter ou haut-vote la question connexe dans le [gestionnaire d'incidents](https://issues.apache.org/jira/browse/CB-2083)
+
+  * Ignore la `mediaType` propriété de `cameraOptions` comme le kit de développement Windows Phone ne fournit pas un moyen de choisir les vidéos de PHOTOLIBRARY.
+
+## CameraError
+
+fonction de rappel onError qui fournit un message d'erreur.
+
+    function(message) {/ / afficher un message utile}
+    
+
+#### Description
+
+  * **message**: le message est fourni par du code natif de l'appareil. *(String)*
+
+## cameraSuccess
+
+fonction de rappel onSuccess qui fournit les données d'image.
+
+    function(ImageData) {/ / faire quelque chose avec l'image}
+    
+
+#### Description
+
+  * **imageData**: codage Base64 de l'image, *ou* le fichier image URI, selon `cameraOptions` en vigueur. *(String)*
+
+#### Exemple
+
+    Afficher image / / function cameraCallback(imageData) {var image = document.getElementById('myImage') ;
+        image.src = "données : image / jpeg ; base64," + imageData;}
+    
+
+## CameraPopoverHandle
+
+Un handle vers la boîte de dialogue de kangourou créé par`navigator.camera.getPicture`.
+
+#### Description
+
+  * **setPosition**: Set the position of the popover. Takes the `CameraPopoverOptions` that specify the new position.
+
+#### Plates-formes supportées
+
+![](doc/img/android-fail.png) ![](doc/img/blackberry-fail.png) ![](doc/img/browser-fail.png) ![](doc/img/firefox-fail.png) ![](doc/img/fireos-fail.png) ![](doc/img/ios-success.png) ![](doc/img/windows-fail.png) ![](doc/img/wp8-fail.png) ![](doc/img/ubuntu-fail.png)
+
+#### Exemple
+
+     var cameraPopoverHandle = navigator.camera.getPicture (onSuccess, onFail, {destinationType : Camera.DestinationType.FILE_URI, TypeSource : Camera.PictureSourceType.PHOTOLIBRARY, popoverOptions : nouvelle CameraPopoverOptions (300, 300, 100, 100, Camera.PopoverArrowDirection.ARROW_ANY)}) ;
+    
+     Repositionner le kangourou si l'orientation change.
+     Window.onorientationchange = function() {var cameraPopoverOptions = new CameraPopoverOptions (0, 0, 100, 100, Camera.PopoverArrowDirection.ARROW_ANY) ;
+         cameraPopoverHandle.setPosition(cameraPopoverOptions) ;
+     }
+    
+
+## CameraPopoverOptions
+
+iOS uniquement les paramètres qui spécifient la direction ancre élément emplacement et de la flèche de la kangourou lors de la sélection des images de la bibliothèque de l'iPad ou l'album.
+
+    {x: 0, y: 32, largeur : 320, hauteur : 480, arrowDir : Camera.PopoverArrowDirection.ARROW_ANY} ;
+    
+
+#### Description
+
+  * **x**: coordonnée de pixel de l'élément de l'écran sur lequel ancrer le kangourou x. *(Nombre)*
+
+  * **y**: coordonnée de y pixels de l'élément de l'écran sur lequel ancrer le kangourou. *(Nombre)*
+
+  * **largeur**: largeur, en pixels, de l'élément de l'écran sur lequel ancrer le kangourou. *(Nombre)*
+
+  * **hauteur**: hauteur, en pixels, de l'élément de l'écran sur lequel ancrer le kangourou. *(Nombre)*
+
+  * **arrowDir**: Direction de la flèche sur le kangourou doit pointer. Définies dans `Camera.PopoverArrowDirection` *(nombre)*
+    
+            Camera.PopoverArrowDirection = {
+                ARROW_UP : 1,        // matches iOS UIPopoverArrowDirection constants
+                ARROW_DOWN : 2,
+                ARROW_LEFT : 4,
+                ARROW_RIGHT : 8,
+                ARROW_ANY : 15
+            };
+        
+
+Notez que la taille de la kangourou peut changer pour s'adapter à la direction de la flèche et l'orientation de l'écran. Assurez-vous que tenir compte des changements d'orientation lors de la spécification de l'emplacement d'élément d'ancrage.
+
+## Navigator.Camera.Cleanup
+
+Supprime les intermédiaires photos prises par la caméra de stockage temporaire.
+
+    Navigator.Camera.Cleanup (cameraSuccess, cameraError) ;
+    
+
+#### Description
+
+Supprime les intermédiaires les fichiers image qui sont gardées en dépôt temporaire après avoir appelé `camera.getPicture` . S'applique uniquement lorsque la valeur de `Camera.sourceType` est égale à `Camera.PictureSourceType.CAMERA` et le `Camera.destinationType` est égal à`Camera.DestinationType.FILE_URI`.
+
+#### Plates-formes supportées
+
+![](doc/img/android-fail.png) ![](doc/img/blackberry-fail.png) ![](doc/img/browser-fail.png) ![](doc/img/firefox-fail.png) ![](doc/img/fireos-fail.png) ![](doc/img/ios-success.png) ![](doc/img/windows-fail.png) ![](doc/img/wp8-fail.png) ![](doc/img/ubuntu-fail.png)
+
+#### Exemple
+
+    Navigator.Camera.Cleanup (onSuccess, onFail) ;
+    
+    fonction onSuccess() {console.log ("succès de caméra nettoyage.")}
+    
+    function onFail(message) {alert (' a échoué car: "+ message);}

+ 391 - 0
miaomiao/plugins/cordova-plugin-camera/doc/fr/index.md

xqd
@@ -0,0 +1,391 @@
+<!---
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+-->
+
+# cordova-plugin-camera
+
+Ce plugin définit un global `navigator.camera` objet qui fournit une API pour la prise de photos et de choisir des images de la bibliothèque d'images du système.
+
+Bien que l'objet est attaché à la portée globale `navigator` , il n'est pas disponible jusqu'après la `deviceready` événement.
+
+    document.addEventListener (« deviceready », onDeviceReady, false) ;
+    function onDeviceReady() {console.log(navigator.camera);}
+    
+
+## Installation
+
+    Cordova plugin ajouter cordova-plugin-camera
+    
+
+## navigator.camera.getPicture
+
+Prend une photo à l'aide de la caméra, ou récupère une photo de la Galerie d'images de l'appareil. L'image est passé au rappel succès comme un codage base64 `String` , ou comme l'URI du fichier de l'image. La méthode elle-même retourne un `CameraPopoverHandle` objet qui permet de repositionner le kangourou de sélection de fichier.
+
+    navigator.camera.getPicture (cameraSuccess, cameraError, cameraOptions) ;
+    
+
+### Description
+
+Le `camera.getPicture` fonction ouvre l'application de caméra par défaut de l'appareil qui permet aux utilisateurs de prendre des photos. Ce comportement se produit par défaut, lorsque `Camera.sourceType` est égal à `Camera.PictureSourceType.CAMERA` . Une fois que l'utilisateur s'enclenche la photo, l'application appareil photo se ferme et l'application est restaurée.
+
+Si `Camera.sourceType` est `Camera.PictureSourceType.PHOTOLIBRARY` ou `Camera.PictureSourceType.SAVEDPHOTOALBUM` , puis un dialogue affiche qui permet aux utilisateurs de sélectionner une image existante. Le `camera.getPicture` retourne un `CameraPopoverHandle` objet, ce qui permet de repositionner le dialogue de sélection d'image, par exemple, lorsque l'orientation de l'appareil change.
+
+La valeur de retour est envoyée à la `cameraSuccess` la fonction de rappel, dans l'un des formats suivants, selon les `cameraOptions` :
+
+*   A `String` contenant l'image photo codée en base64.
+
+*   A `String` qui représente l'emplacement du fichier image sur le stockage local (par défaut).
+
+Vous pouvez faire ce que vous voulez avec l'image codée ou URI, par exemple :
+
+*   Afficher l'image dans un `<img>` tag, comme dans l'exemple ci-dessous
+
+*   Enregistrer les données localement ( `LocalStorage` , [poids][1], etc..)
+
+*   Publier les données sur un serveur distant
+
+ [1]: http://brianleroux.github.com/lawnchair/
+
+**NOTE**: la résolution de Photo sur les nouveaux appareils est assez bonne. Photos sélectionnées de la Galerie de l'appareil ne sont pas réduites à une baisse de la qualité, même si un `quality` paramètre est spécifié. Pour éviter les problèmes de mémoire commun, définissez `Camera.destinationType` à `FILE_URI` au lieu de`DATA_URL`.
+
+### Plates-formes prises en charge
+
+*   Amazon Fire OS
+*   Android
+*   BlackBerry 10
+*   Navigateur
+*   Firefox OS
+*   iOS
+*   Paciarelli
+*   Windows Phone 7 et 8
+*   Windows 8
+
+### Préférences (iOS)
+
+*   **CameraUsesGeolocation** (boolean, par défaut, false). Pour capturer des images JPEG, true pour obtenir des données de géolocalisation dans l'en-tête EXIF. Cela va déclencher une demande d'autorisations de géolocalisation si défini à true.
+    
+        <preference name="CameraUsesGeolocation" value="false" />
+        
+
+### Amazon Fire OS Quirks
+
+Amazon Fire OS utilise des intentions pour lancer l'activité de l'appareil photo sur l'appareil pour capturer des images et sur les téléphones avec peu de mémoire, l'activité de Cordova peut être tuée. Dans ce scénario, l'image peut ne pas apparaître lorsque l'activité de cordova est restaurée.
+
+### Quirks Android
+
+Android utilise des intentions pour lancer l'activité de l'appareil photo sur l'appareil pour capturer des images et sur les téléphones avec peu de mémoire, l'activité de Cordova peut être tuée. Dans ce scénario, l'image peut ne pas apparaître lorsque l'activité de Cordova est restaurée.
+
+### Bizarreries navigateur
+
+Peut retourner uniquement les photos comme image codée en base64.
+
+### Firefox OS Quirks
+
+Appareil photo plugin est actuellement mis en œuvre à l'aide [d'Activités sur le Web][2].
+
+ [2]: https://hacks.mozilla.org/2013/01/introducing-web-activities/
+
+### iOS Quirks
+
+Y compris un JavaScript `alert()` dans les deux le rappel fonctions peuvent causer des problèmes. Envelopper l'alerte dans un `setTimeout()` pour permettre le sélecteur d'image iOS ou kangourou pour fermer entièrement avant que l'alerte s'affiche :
+
+    setTimeout(function() {/ / faire votre truc ici!}, 0) ;
+    
+
+### Windows Phone 7 Quirks
+
+Invoquant l'application native caméra alors que l'appareil est connecté via Zune ne fonctionne pas et déclenche un rappel de l'erreur.
+
+### Bizarreries de paciarelli
+
+Paciarelli prend uniquement en charge un `destinationType` de `Camera.DestinationType.FILE_URI` et un `sourceType` de`Camera.PictureSourceType.PHOTOLIBRARY`.
+
+### Exemple
+
+Prendre une photo, puis extrayez-la comme une image codée en base64 :
+
+    navigator.camera.getPicture (onSuccess, onFail, { quality: 50,
+        destinationType: Camera.DestinationType.DATA_URL
+    }) ;
+    
+    function onSuccess(imageData) {var image = document.getElementById('myImage') ;
+        image.src = "données : image / jpeg ; base64," + imageData;}
+    
+    function onFail(message) {alert (' a échoué car: "+ message);}
+    
+
+Prendre une photo et récupérer l'emplacement du fichier de l'image :
+
+    navigator.camera.getPicture (onSuccess, onFail, { quality: 50,
+        destinationType: Camera.DestinationType.FILE_URI }) ;
+    
+    function onSuccess(imageURI) {var image = document.getElementById('myImage') ;
+        image.SRC = imageURI ;
+    } function onFail(message) {alert (' a échoué car: "+ message);}
+    
+
+## CameraOptions
+
+Paramètres optionnels pour personnaliser les réglages de l'appareil.
+
+    {qualité : destinationType 75,: Camera.DestinationType.DATA_URL, TypeSource : Camera.PictureSourceType.CAMERA, allowEdit : encodingType vrai,: Camera.EncodingType.JPEG, targetWidth : 100, targetHeight : 100, popoverOptions : CameraPopoverOptions, saveToPhotoAlbum : false} ;
+    
+
+### Options
+
+*   **qualité**: qualité de l'image enregistrée, exprimée en une gamme de 0 à 100, 100 étant généralement pleine résolution sans perte de compression de fichiers. La valeur par défaut est 50. *(Nombre)* (Notez que les informations sur la résolution de la caméra sont indisponibles).
+
+*   **destinationType**: choisissez le format de la valeur de retour. La valeur par défaut est FILE_URI. Définies dans `navigator.camera.DestinationType` *(nombre)*
+    
+        Camera.DestinationType = {
+            DATA_URL : 0,      // Return image as base64-encoded string
+            FILE_URI : 1,      // Return image file URI
+            NATIVE_URI : 2     // Return image native URI (e.g., assets-library:// on iOS or content:// on Android)
+        };
+        
+
+*   **sourceType**: définissez la source de l'image. La valeur par défaut est la caméra. Définies dans `navigator.camera.PictureSourceType` *(nombre)*
+    
+        Camera.PictureSourceType = {
+            PHOTOLIBRARY : 0,
+            CAMERA : 1,
+            SAVEDPHOTOALBUM : 2
+        };
+        
+
+*   **allowEdit**: permettre un montage simple d'image avant la sélection. *(Booléen)*
+
+*   **encodingType**: choisir le fichier image retournée de codage. Valeur par défaut est JPEG. Définies dans `navigator.camera.EncodingType` *(nombre)*
+    
+        Camera.EncodingType = {
+            JPEG : 0,               // Return JPEG encoded image
+            PNG : 1                 // Return PNG encoded image
+        };
+        
+
+*   **targetWidth**: largeur en pixels de l'image de l'échelle. Doit être utilisé avec **targetHeight**. Aspect ratio reste constant. *(Nombre)*
+
+*   **targetHeight**: hauteur en pixels de l'image de l'échelle. Doit être utilisé avec **targetWidth**. Aspect ratio reste constant. *(Nombre)*
+
+*   **mediaType**: définir le type de média pour choisir de. Ne fonctionne que quand `PictureSourceType` est `PHOTOLIBRARY` ou `SAVEDPHOTOALBUM` . Définies dans `nagivator.camera.MediaType` *(nombre)*
+    
+        Camera.MediaType = {
+            PICTURE: 0,    // allow selection of still pictures only. PAR DÉFAUT. Will return format specified via DestinationType
+            VIDEO: 1,      // allow selection of video only, WILL ALWAYS RETURN FILE_URI
+            ALLMEDIA : 2   // allow selection from all media types
+        };
+        
+
+*   **correctOrientation**: faire pivoter l'image afin de corriger l'orientation de l'appareil lors de la capture. *(Booléen)*
+
+*   **saveToPhotoAlbum**: enregistrer l'image sur l'album photo sur l'appareil après la capture. *(Booléen)*
+
+*   **popoverOptions**: iOS uniquement des options qui spécifient l'emplacement de kangourou dans iPad. Défini dans`CameraPopoverOptions`.
+
+*   **cameraDirection**: choisissez la caméra à utiliser (ou dos-face). La valeur par défaut est de retour. Définies dans `navigator.camera.Direction` *(nombre)*
+    
+        Camera.Direction = {
+            BACK : 0,      // Use the back-facing camera
+            FRONT : 1      // Use the front-facing camera
+        };
+        
+
+### Amazon Fire OS Quirks
+
+*   Tout `cameraDirection` résultats dans le back-face photo de valeur.
+
+*   Ignore la `allowEdit` paramètre.
+
+*   `Camera.PictureSourceType.PHOTOLIBRARY`et `Camera.PictureSourceType.SAVEDPHOTOALBUM` les deux affichent le même album photo.
+
+### Quirks Android
+
+*   Tout `cameraDirection` résultats dans le back-face photo de valeur.
+
+*   Ignore la `allowEdit` paramètre.
+
+*   `Camera.PictureSourceType.PHOTOLIBRARY`et `Camera.PictureSourceType.SAVEDPHOTOALBUM` les deux affichent le même album photo.
+
+### BlackBerry 10 Quirks
+
+*   Ignore la `quality` paramètre.
+
+*   Ignore la `allowEdit` paramètre.
+
+*   `Camera.MediaType`n'est pas pris en charge.
+
+*   Ignore la `correctOrientation` paramètre.
+
+*   Ignore la `cameraDirection` paramètre.
+
+### Firefox OS Quirks
+
+*   Ignore la `quality` paramètre.
+
+*   `Camera.DestinationType`est ignorée et est égal à `1` (URI du fichier image)
+
+*   Ignore la `allowEdit` paramètre.
+
+*   Ignore la `PictureSourceType` paramètre (utilisateur il choisit dans une fenêtre de dialogue)
+
+*   Ignore le`encodingType`
+
+*   Ignore la `targetWidth` et`targetHeight`
+
+*   `Camera.MediaType`n'est pas pris en charge.
+
+*   Ignore la `correctOrientation` paramètre.
+
+*   Ignore la `cameraDirection` paramètre.
+
+### iOS Quirks
+
+*   La valeur `quality` inférieur à 50 pour éviter les erreurs de mémoire sur certains appareils.
+
+*   Lorsque vous utilisez `destinationType.FILE_URI` , les photos sont sauvegardées dans le répertoire temporaire de l'application. Le contenu du répertoire temporaire de l'application est supprimé lorsque l'application se termine.
+
+### Bizarreries de paciarelli
+
+*   options non prises en charge
+
+*   retourne toujours un URI de fichier
+
+### Windows Phone 7 et 8 Quirks
+
+*   Ignore la `allowEdit` paramètre.
+
+*   Ignore la `correctOrientation` paramètre.
+
+*   Ignore la `cameraDirection` paramètre.
+
+*   Ignore la `saveToPhotoAlbum` paramètre. IMPORTANT : Toutes les images prises avec la caméra de cordova wp7/8 API sont toujours copiés au rôle d'appareil photo du téléphone. Selon les paramètres de l'utilisateur, cela pourrait également signifier que l'image est auto-téléchargées à leur OneDrive. Potentiellement, cela pourrait signifier que l'image est disponible à un public plus large que votre application destinée. Si ce un bloqueur pour votre application, vous devrez implémenter le CameraCaptureTask tel que documenté sur msdn : <http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh394006.aspx> vous pouvez aussi commenter ou haut-vote la question connexe dans le [gestionnaire d'incidents][3]
+
+*   Ignore la `mediaType` propriété de `cameraOptions` comme le kit de développement Windows Phone ne fournit pas un moyen de choisir les vidéos de PHOTOLIBRARY.
+
+ [3]: https://issues.apache.org/jira/browse/CB-2083
+
+## CameraError
+
+fonction de rappel onError qui fournit un message d'erreur.
+
+    function(message) {/ / afficher un message utile}
+    
+
+### Paramètres
+
+*   **message**: le message est fourni par du code natif de l'appareil. *(String)*
+
+## cameraSuccess
+
+fonction de rappel onSuccess qui fournit les données d'image.
+
+    function(ImageData) {/ / faire quelque chose avec l'image}
+    
+
+### Paramètres
+
+*   **imageData**: codage Base64 de l'image, *ou* le fichier image URI, selon `cameraOptions` en vigueur. *(String)*
+
+### Exemple
+
+    Afficher image / / function cameraCallback(imageData) {var image = document.getElementById('myImage') ;
+        image.src = "données : image / jpeg ; base64," + imageData;}
+    
+
+## CameraPopoverHandle
+
+Un handle vers la boîte de dialogue de kangourou créé par`navigator.camera.getPicture`.
+
+### Méthodes
+
+*   **setPosition**: définir la position de la kangourou.
+
+### Plates-formes prises en charge
+
+*   iOS
+
+### setPosition
+
+Définir la position de la kangourou.
+
+**Paramètres**:
+
+*   `cameraPopoverOptions`: la `CameraPopoverOptions` qui spécifie la nouvelle position
+
+### Exemple
+
+     var cameraPopoverHandle = navigator.camera.getPicture (onSuccess, onFail, {destinationType : Camera.DestinationType.FILE_URI, TypeSource : Camera.PictureSourceType.PHOTOLIBRARY, popoverOptions : nouvelle CameraPopoverOptions (300, 300, 100, 100, Camera.PopoverArrowDirection.ARROW_ANY)}) ;
+    
+     Repositionner le kangourou si l'orientation change.
+     Window.onorientationchange = function() {var cameraPopoverOptions = new CameraPopoverOptions (0, 0, 100, 100, Camera.PopoverArrowDirection.ARROW_ANY) ;
+         cameraPopoverHandle.setPosition(cameraPopoverOptions) ;
+     }
+    
+
+## CameraPopoverOptions
+
+iOS uniquement les paramètres qui spécifient la direction ancre élément emplacement et de la flèche de la kangourou lors de la sélection des images de la bibliothèque de l'iPad ou l'album.
+
+    {x: 0, y: 32, largeur : 320, hauteur : 480, arrowDir : Camera.PopoverArrowDirection.ARROW_ANY} ;
+    
+
+### CameraPopoverOptions
+
+*   **x**: coordonnée de pixel de l'élément de l'écran sur lequel ancrer le kangourou x. *(Nombre)*
+
+*   **y**: coordonnée de y pixels de l'élément de l'écran sur lequel ancrer le kangourou. *(Nombre)*
+
+*   **largeur**: largeur, en pixels, de l'élément de l'écran sur lequel ancrer le kangourou. *(Nombre)*
+
+*   **hauteur**: hauteur, en pixels, de l'élément de l'écran sur lequel ancrer le kangourou. *(Nombre)*
+
+*   **arrowDir**: Direction de la flèche sur le kangourou doit pointer. Définies dans `Camera.PopoverArrowDirection` *(nombre)*
+    
+            Camera.PopoverArrowDirection = {
+                ARROW_UP : 1,        // matches iOS UIPopoverArrowDirection constants
+                ARROW_DOWN : 2,
+                ARROW_LEFT : 4,
+                ARROW_RIGHT : 8,
+                ARROW_ANY : 15
+            };
+        
+
+Notez que la taille de la kangourou peut changer pour s'adapter à la direction de la flèche et l'orientation de l'écran. Assurez-vous que tenir compte des changements d'orientation lors de la spécification de l'emplacement d'élément d'ancrage.
+
+## Navigator.Camera.Cleanup
+
+Supprime les intermédiaires photos prises par la caméra de stockage temporaire.
+
+    Navigator.Camera.Cleanup (cameraSuccess, cameraError) ;
+    
+
+### Description
+
+Supprime les intermédiaires les fichiers image qui sont gardées en dépôt temporaire après avoir appelé `camera.getPicture` . S'applique uniquement lorsque la valeur de `Camera.sourceType` est égale à `Camera.PictureSourceType.CAMERA` et le `Camera.destinationType` est égal à`Camera.DestinationType.FILE_URI`.
+
+### Plates-formes prises en charge
+
+*   iOS
+
+### Exemple
+
+    Navigator.Camera.Cleanup (onSuccess, onFail) ;
+    
+    fonction onSuccess() {console.log ("succès de caméra nettoyage.")}
+    
+    function onFail(message) {alert (' a échoué car: "+ message);}

BIN
miaomiao/plugins/cordova-plugin-camera/doc/img/android-fail.png


BIN
miaomiao/plugins/cordova-plugin-camera/doc/img/android-success.png


BIN
miaomiao/plugins/cordova-plugin-camera/doc/img/blackberry-fail.png


BIN
miaomiao/plugins/cordova-plugin-camera/doc/img/blackberry-success.png


BIN
miaomiao/plugins/cordova-plugin-camera/doc/img/browser-fail.png


BIN
miaomiao/plugins/cordova-plugin-camera/doc/img/browser-success.png


BIN
miaomiao/plugins/cordova-plugin-camera/doc/img/firefox-fail.png


BIN
miaomiao/plugins/cordova-plugin-camera/doc/img/firefox-success.png


BIN
miaomiao/plugins/cordova-plugin-camera/doc/img/fireos-fail.png


BIN
miaomiao/plugins/cordova-plugin-camera/doc/img/fireos-success.png


Some files were not shown because too many files changed in this diff