1. 程式人生 > >Phonegap jQueryMobile 線上應用拍照、相簿選擇上傳+預覽

Phonegap jQueryMobile 線上應用拍照、相簿選擇上傳+預覽

     拍照上傳以及從相簿中選擇圖片上傳是大多數手機應用的典型功能,這幾天在做一個移動端的專案,其中就用到該功能。      專案技術選擇的是Phonegap+jQueryMobile,因為jQuery自己比較熟悉,用jQueryMobile沒有什麼大的難點。      介面用jQueryMobile搭的很快,一開始打算用Phonegap將應用做為離線版本,但後來發現離線版本升級的話還是和普通的app一樣,都需要重新安裝,這就沒有了WebApp的優勢和亮點,故最終選擇了線上版本,即將專案作為一個web應用,用Tomcat釋出在伺服器上,Phonegap作為一個app外殼行使瀏覽器功能在其中請求伺服器上的頁面等資源。
     做該功能的時候,由於對於Phonegap接觸不久,花了我整整兩天的時間,這兩天沒有做其他的,一直在研究如何實現圖片預覽,網上、官網有很多成功的例子,但沒有一個在我這邊成功預覽的,幾乎看遍了網上所有的帖子,點壞了滑鼠!心情壞到了極點,因為本以為很簡單的東西,而後網上說的也都很簡單,很多帖子都是一樣的內容,但是我卻死活跑不通,崩潰!      到最後,才發現問題原來出在我的“線上”應用上,無語,其實做J2EE的我深知瀏覽器端是無許可權操作本地檔案的,但是由於對Phonegap的不瞭解,由於知道Phonegap可以直接操作本地資源,誤認為用了Phonegap就無敵了,你以為呢!於是我就把WebApp整成離線的試下嘍,果然,可以顯示了!
     但專案已經做到這個地步了,再把它重構成離線的?不可取。於是我就開始分析了。。。      Phonegap不是可以操作本地檔案嗎?html中的img標籤不能根據本地圖片路徑渲染圖片,但它可以不用檔案路徑啊!於是呵呵了。      最終解決方案是用Phonegap的FileReader來根據本地圖片路徑以base64的形式讀取其內容,base64是可以直接在img標籤上渲染的,所以問題就解決了。 下面擷取拍照上傳以及預覽的程式碼如下: 圖片處理程式碼:
var picUrl = "" ;
function capturePhotoUrl() {

     navigator.camera.getPicture(onCaptureSuccess, onUrlFail, {
           quality : 80,
//         allowEdit : true,//在Android中此配置忽略
           destinationType : Camera.DestinationType.FILE_URI,
           sourceType:Camera.PictureSourceType.CAMERA,
           targetWidth : 800, // 生成的圖片大小 單位畫素
           targetHeight : 640
     });

}
function onCaptureSuccess(imageURI) {
     picUrl = imageURI;
     //這是關鍵部分
     window.resolveLocalFileSystemURI(imageURI, function(fileEntry){
           fileEntry.file( function(file){
                 var reader = new FileReader();
                    reader.onloadend = function(evt) {
                     $( "#uploadImgDom").append("<img path='"+imageURI+"' class='uploadImg' src='"+evt.target.result+"' />");
                     $( "#report-page").trigger("create" );
                    };
                    reader.readAsDataURL(file);
           }, readFileFail);
     }, readFileFail);
//   $("#urlinfo").text("圖片的原始路徑" + imageURI);
}

function readFileFail(evt){
     navigator.notification.alert( "檔案讀取失敗,原因:" + evt.code, null, "警告" );
}

function onUrlFail(message) {
     navigator.notification.alert( "失敗,原因:" + message, null, "警告" );
}

function loadImageLocal() {
     navigator.camera.getPicture(onLoadSuccess, onUrlFail, {
           quality : 80,
           sourceType : Camera.PictureSourceType.PHOTOLIBRARY,
           destinationType : Camera.DestinationType.FILE_URI,
//         encodingType : Camera.EncodingType.JPEG,
//         mediaType : Camera.MediaType.PICTURE,
           targetWidth : 800, // 生成的圖片大小 單位畫素,選擇圖片的時候一定要制定這個值,否則
           targetHeight : 640
     });

}

function onLoadSuccess(imageURI) {
     imageURI = imageURI + ".jpg";
     picUrl = imageURI;
     window.resolveLocalFileSystemURI(imageURI, function(fileEntry){
           fileEntry.file( function(file){
                 var reader = new FileReader();
                    reader.onloadend = function(evt) {
                     $( "#uploadImgDom").append("<img path='"+imageURI+"' class='uploadImg' src='"+evt.target.result+"' />");
                     $( "#report-page").trigger("create" );
                    };
                    reader.readAsDataURL(file);
           }, readFileFail);
     }, readFileFail);
//   $("#urlinfo").text("圖片的原始路徑" + picUrl);
}

function uploadPhoto() {
     $("#report-btn").attr({ "disabled": "disabled"});
     var options = new FileUploadOptions();
     options.fileKey = "file";
     options.fileName = picUrl.substr(picUrl.lastIndexOf( '/') + 1);
     options.mimeType = "image/jpeg";
     
     var ft = new FileTransfer(); //檔案上傳類
    ft.onprogress = function (progressEvt) { //顯示上傳進度條
        if (progressEvt.lengthComputable) {
            navigator.notification.progressValue(Math.round(( progressEvt.loaded / progressEvt.total ) * 100));
        }
    }
    navigator.notification.progressStart( "提醒", "當前上傳進度" );
     
     var params = new Object();
     params.title = $( "#textinput-2").val();
     params.info = $( "#textarea-2").val();
     params.longitude = $( "#longitude").text();
     params.latitude = $( "#latitude").text();
     
     options.params = params;
     
     
     ft.upload(picUrl, basePath+ "/report", win,
                fail, options);
}

function win(r) {
     navigator.notification.progressStop(); //停止進度條
     
     $("#returnpic").attr( "src",
                basePath+ "/files/" + r.response);

//   $("#returninfo").html(
//              "上傳成功\n:反饋的資訊:r.responseCode:" + r.responseCode + "\nr.response:"
//                         + r.response + "\nr.bytesSent:" + r.bytesSent);
     $("#report-btn").removeAttr( "disabled");
     navigator.notification.alert( "上傳成功!" , function(){
           $( "#reportPageBackBtn").click();
     }, "提醒");
}

function fail(error) {

     /*
      * FileTransferError.FILE_NOT_FOUND_ERR:1 檔案未找到錯誤。
      * •FileTransferError.INVALID_URL_ERR:2 無效的URL錯誤。
      * •FileTransferError.CONNECTION_ERR:3 連線錯誤。 FileTransferError.ABORT_ERR =
      * 4; 程式異常
      */
     var errorcode = error.code;
     var errstr = "";
     switch (errorcode) {
     case 1: {
           errstr = "錯誤程式碼1:原始檔路徑異常,請重新選擇或者拍照上傳!" ;
            break;
     }
     case 2: {
           errstr = "錯誤程式碼2:目標地址無效,請重試!" ;
            break;
     }
     case 3: {
           errstr = "您手機或者後臺伺服器網路異常,請重新上傳!" ;
            break;
     }
     default: {
           errstr = "程式出錯";
            break;
     }

     }
     $("#returninfo").text(
                 "上傳失敗,錯誤程式碼:" + errstr + "上傳原始檔:" + error.source + "目標地址:"
                           + error.target + "請重新上傳!" );
    
     $("#report-btn").removeAttr( "disabled");
}
前臺顯示程式碼: