繁体   English   中英

从相机拍摄照片会在20%的时间内失败

[英]Taking a picture from the camera fails 20% of the time

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%的时间,“警报(”拍照成功“);” 没有被调用,而没有显示错误。 如果我取消拍摄照片,则会显示警告,并显示“尝试拍照时发生错误”消息,因此错误回调有效。

基本上没有任何反应。 我在CM9上的三星Galaxy S2和全新的HTC One X上进行了测试。

最近我回答了另一个关于同样问题的问题。 我们在我的公司碰到了这个并解决了它。 它与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。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM