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 の Samsung Galaxy S2 と新しい HTC One X でテストしました。

4

1 に答える 1

11

私が答えたこの同じ問題について、最近別の質問がありました。私の会社でこれに遭遇し、解決しました。Phonegap よりも Android システムに関係があります。

カメラを起動すると、アプリは 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();

それで、それはそれについてです。すべてのパス/ファイル/ページ/etc の名前をアプリで使用する名前に変更してください。これにより、写真が撮影されるたびにその画像が上書きされますが、必要ない場合は、動的に名前を付ける方法を考え出すことができます。JavaScript の他のパスと同じように、その URI を使用できます。

于 2012-07-18T16:41:06.063 に答える