4
var camera = {
  settings : {
    quality : 50,
    targetWidth : 1024,
    targetHeight : 1024,
    correctOrientation : true
  }
};
var error = function(message) {
  alert("Error happened while trying to get a picture", message);
};
document.addEventListener("deviceready", function() {
  camera.toFile = function() {
    this.settings.destinationType = navigator.camera.DestinationType.FILE_URI;
    return this;
  },
  camera.toBase64 = function() {
    this.settings.destinationType = navigator.camera.DestinationType.DATA_URL;
    return this;
  },
  camera.fromCamera = function() {
    this.settings.sourceType = navigator.camera.PictureSourceType.CAMERA;
    return this;
  };
  camera.fromLibrary = function() {
    this.settings.sourceType = navigator.camera.PictureSourceType.PHOTOLIBRARY;
    return this;
  };
  camera.fromPhotoAlbum = function() {
    this.settings.sourceType = navigator.camera.PictureSourceType.SAVEDPHOTOALBUM;
    return this;
  }
  camera.get = function(callback) {
    navigator.camera.getPicture(function(data) {
      alert("taking a picture successful");
      callback(data);
    }, error, camera.settings);
  };
}, false);

这是我的相机小包装。我这样称呼它:

camera.fromPhotoAlbum().toBase64().get(function(base64){});

大约 20% 的时间,“alert(”拍照成功“);” 不调用,而没有显示错误。如果我取消拍照,则会显示一条带有“尝试拍照时发生错误”消息的警报,因此错误回调起作用。

基本上什么都不会发生。我已经在 CM9 上的三星 Galaxy S2 和全新的 HTC One X 上对其进行了测试。

4

1 回答 1

11

最近我回答了关于同样问题的另一个问题。我们在我的公司遇到了这个问题并解决了。它与Android系统的关系比Phonegap更多。

发生的事情是当您启动相机时,您的应用程序进入 onStop()。在那里,如果需要内存,Android 系统有权终止您的应用程序。碰巧的是,当相机拍照并将其转储到内存中时,内存通常会变低,因此当您的用户拍照时,您的应用程序很有可能会被杀死。

现在您的应用程序已经死了,当相机完成时,它会重新启动您的应用程序。这就是为什么它表现得如此奇怪。相机返回到您的应用程序,但与之前的实例不同,因此您的回调永远不会被调用,因为它不再存在。

您可以通过降低图片的质量并通过 URI 而不是数据将其传递给您的应用程序来降低发生这种情况的频率,但问题不会完全消失。

为了解决回调永远不会发生的问题,我们制作了一个 Java 回调来启动相机并在每次拍摄时将图片保存到相同的位置。然后,当应用程序从被杀状态重新启动时,它会在该位置查找图片。

对于一个愚蠢的问题,这是一个奇怪的解决方案,但是如果您的应用程序被杀死,那么相机回调就不会发生。如果您需要有关如何使 Java 回调来执行此操作的更多信息,请告诉我,我会将我们的代码放在这里。否则,请查看此 SO 答案以获取更多信息。

编辑:这是我们在主要 DroidGap 活动中使用的代码:

private static final String folderPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/appName";
private static final String filePath = "phonegapImage.jpg";

@Override
public void onCreate(Bundle savedState) {
    //...The rest of onCreate, this makes the Java available in JavaScript
    appView.addJavascriptInterface(this, "Camera");
}

public void takePhoto(final String callback) {
    Log.v("Camera Plugin", "Starting takePhoto callback");

    Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
    intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(folderPath, filePath)));
    startActivityForResult(intent, TAKE_PICTURE);
}

public String getPhotoUri() {
    return Uri.fromFile(new File(folderPath, filePath)).toString();
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    switch (requestCode) {
        case TAKE_PICTURE:
            if (resultCode == Activity.RESULT_OK) {
                //Do whatever you need to do when the camera returns
                //This is after the picture is already saved, we return to the page
            }
            break;
        default:
            Log.v("Camera", "Something strange happened...");
            break;
    }
}

然后,在您的 JavaScript 中,您可以使用以下命令调用相机:

Camera.takePhoto("onPhotoURISuccess");
//Then, to get the location of the photo after you take it and load the page again
var imgPath = Camera.getPhotoUri();

所以,就是这样。只需确保将所有路径/文件/页面/等名称更改为您要在应用程序中使用的名称。这将在每次拍摄照片时覆盖该图像,但如果您不希望这样做,您可能会想办法动态命名它们。您可以像使用 JavaScript 中的任何其他路径一样使用该 URI。

于 2012-07-18T16:41:06.063 回答