3

我已经几乎完成了使用 Appcelerator 开发 HTML5 应用程序,我还有一个功能要添加,该功能允许用户在通过应用程序向客户端发送消息时拍照。显示了一个包含消息表单的特定 div,我希望用户能够用他们的手机拍照,并将其自动附加到消息上,然后将其提交到我们的服务器。

然而,在四处寻找之后,我对如何让它工作感到困惑。虽然 API 显示了使相机工作的 Javascript,但我似乎无法访问它,而且我不知道 API 调用应该位于何处。它是放在 app.js 文件中,还是它自己的文件中,或者在哪里调用它并不重要?任何帮助/建议将不胜感激。

编辑
感谢 Dragon,我对我的代码进行了以下更改:

index.html

        <div class="col-square">
            <a href="#" onclick="Ti.App.fireEvent('app:fromWebView');"><i class="fa fa-camera fa-squareBlock"></i><br />Take Photo</a>
        </div>

<script type="text/javascript">
    Ti.App.addEventListener("app:fromTitanium", function(e) {
        alert(e.message);
    });
</script>

应用程序.js

Ti.App.addEventListener('app:fromWebView', function(e){

  Titanium.Media.showCamera({

    success:function(event)
    {       
        var image = event.media;
        var file = Titanium.Filesystem.getFile(Titanium.Filesystem.applicationDataDirectory,"userImg.jpg");
        file.write(image);
        var data = file.nativePath;

        Ti.App.fireEvent('app:fromTitanium', {message: "photo taken fine"});

    },
    cancel:function()
    {
    },
    error:function(error)
    {
      var a = Titanium.UI.createAlertDialog({title:'Camera'});
      if (error.code == Titanium.Media.NO_CAMERA)
      {
        a.setMessage('Please run this test on device');
      }
      else
      {
        a.setMessage('Unexpected error: ' + error.code);
      }
      a.show();
    },
    showControls:false, // don't show system controls
    mediaTypes:Ti.Media.MEDIA_TYPE_PHOTO,
    autohide:false  // tell the system not to auto-hide and we'll do it ourself
  });
});

但是,在这种情况下,按钮可以很好地打开相机。但是,当照片被拍摄并被选中时,它会返回到屏幕但没有任何反应。然后它在调试中给出这个错误 - “Ti 未定义”。然后当我定义 Ti 时,它将返回“App 未定义”。

这样做的特殊之处在于,如果我删除将处理从 app.js 发送到 webview 的数据的代码,它工作正常,即使从 webview 打开相机的代码足够接近相同的代码?

4

2 回答 2

3

这是你可以做的:

在您的 webview 调用和事件中,并在 webview 的父级中编写事件侦听器。像这样的东西会进入 webview:

<button onclick="Ti.App.fireEvent('app:fromWebView', { message: 'event fired from WebView, handled in Titanium' });">fromWebView</button>

接下来是webview 的父 js 中的类似内容:

Ti.App.addEventListener('app:fromWebView', function(e) {
    alert(e.message);
    //Here you can call the camera api.
})

要将图像发送到 webview,请遵循相反的过程。

不要忘记检查Docs

希望能帮助到你。

于 2014-09-30T09:58:58.463 回答
1

我总是避免在 Titanium 的“网络”世界中使用事件侦听器。当您从 webview 调用“fireEvent”时,您正在跨越从 webview 沙箱到原生世界的桥梁。这就是 Titanium 拍摄照片并将其保存到文件系统的地方。为了让 Titanium 告诉 webview 它完成了,我推荐使用 evalJS。可靠得多。

这是一个使用照片库而不是相机的示例。在模拟器中测试要容易得多。只需替换Titanium.Media.openPhotoGalleryTitanium.Media.showCamera即可使用相机。

应用程序.js

var win = Ti.UI.createWindow({
    background : 'white',
    title : 'camera test'
});

var webview = Ti.UI.createWebView({
    url : 'test.html'
});

win.add(webview);
win.open();

Ti.App.addEventListener('choosePicture', function(e) {

    var filename = e.filename;

    Titanium.Media.openPhotoGallery({

        success : function(event) {
            var image = event.media;
            var file = Titanium.Filesystem.getFile(Titanium.Filesystem.applicationDataDirectory, filename);
            file.write(image);
            var full_filename = file.nativePath;
            webview.evalJS('photoDone("' + full_filename + '");');

        },
        cancel : function() {
        },
        error : function(error) {
            var a = Titanium.UI.createAlertDialog({
                title : 'Camera'
            });
            if (error.code == Titanium.Media.NO_CAMERA) {
                a.setMessage('Please run this test on device');
            } else {
                a.setMessage('Unexpected error: ' + error.code);
            }
            a.show();
        },
        showControls : false, // don't show system controls
        mediaTypes : Ti.Media.MEDIA_TYPE_PHOTO,
        autohide : true
    });
});

测试.html

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
    <head>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>My HTML Page</title>
        <style>
            body {
                padding-top: 20px
            }
        </style>
        <script>
            var photoNumber = 0;
            function doShowCamera() {
                photoNumber++;
                Ti.App.fireEvent('choosePicture', {
                    filename : photoNumber + ".png"
                });
            }

            function photoDone(filename) {
                var img = document.getElementById('myPhoto');
                img.src = filename;
            }

        </script>
    </head>
    <body>
        <img id="myPhoto" width="300" height="400"/>
        <input type="button" value="Show Pictures" onclick="doShowCamera();" />
    </body>
</html>

Ti.App.addEventListener调用可以在您的 Titanium 代码中的任何位置(而不是在您的 web 视图中),只要它只运行一次即可。app.js 是运行它的好地方。

于 2014-10-05T02:32:33.433 回答