上次提到Cordova如何自己建立自己的Plugin,而這次怎來簡單的介紹一下如何在Android和IOS中取得圖片和影片吧!所以這次來簡單實作如何透過Native的圖片和照片API取得結果,並透過Plugin回傳在Cordova上使用囉!
首先一樣建立一個範例的plugin。
$ plugman create –name FetchDevice –plugin_id cordova-plugin-fetch-device-test –plugin_version 0.0.1 –path FetchDeviceTest
接著定義好介面的呼叫名稱如下方所示。
Var exec = require(“cordova/exec”);
Exports.fetchFile = function(params , success , error){
exec(success, error, ‘FetchFile’ , ‘fetchFile’ . [params])
}
接著先來講解一下Android的部分(java),Android可以透過Mediastore的API來取得,而其中分為Images、Video、Files三種,分別是取得圖檔和影片以及檔案,而我們這邊就直接透過Mediastoew.Files來實作取得圖片和影片吧!
先在JAVA加入一個function並使他對應到上方的fetchFile,再來就是要如何使用這個API呢?就要透過Cursor來實現了。
Cursor cursor = this.cordova.getActivity().getApplicationContext().getContentResolver().query(fileURI.projection,my_selection,selection_args,null)
第一個fileURI我設定是在External的路徑下,接著projection則是簡單地拿取Mediastore.Files.FIleColumns.DATA和_ID取得檔案路徑與ID,selection則是簡單設定條件為Mediastore.Files.FIleColumns.MEDIA_TYPE等於影片和圖片,接來透過cursor裡面的結果就會包含手機裡面的圖檔案影片檔的資訊拉。
if(cursor != null && getCount()> 0 ){
if(cursor.moveToFirst()){
String path = cursor.getString(cursor.getColumnIndex(Mediastore.Files.FIleColumns.DATA))
String id = cursor.getString(cursor.getColumnIndex(Mediastore.Files.FIleColumns._ID))
}
}
最後就是透過Callbacl.success()把匯集好的資料回傳出去囉,事不是很間單呢!這邊簡單提醒一下在做Android Native的收尋時,會導致UI介面的lock住,也因此可以透過下面的方法來避免發生這樣的問題,既可以呼叫原生執行,而介面也能繼續呈現的動畫或文字效果。
cordova.getThreadPool().excute(new Runnable(){
Public void run(){
fetchFile(args,callbackContext);
}
})
而既然圖片都取得了而且連ID剛才也一並獲得,那麼便可以透過這個ID再去取得對應的縮圖,Mediastore.Images.thumbnails來找到對應得圖片縮圖
,如此一來便可以自己做一個簡單的選擇圖片的Gallery的相關功能。
String select = Mediastore.Images.Thumbnails.IMAGE_ID + “=” + id
Cursor cursor(Mediastore.Images.Thumbnails.EXTERNAL_CONTENT_URI, projection,select,null,null)
接下來則是對於IOS(swift)的部分,也是一樣建立一個對應到上面fetchFile的function,接下來則是要用到PhotoKit中PHAsset.fetchAssets的方式來取得圖片和影片,而ios比較不樣的地方需要先在PHFetchOptions()中的predicate
先設定好要取得的是圖片或影片。
let options = PHFetchOptions()
option.predicate = NSPredicate(format:”modificationDate>= %@ AND
modificationDate <=%@ AND mediaType = %d”, stardate,endDate,PHAssetMediaType.viewo.rawValue)
而這邊modification則是自己在做時間的區間來取得範圍內的影片,而TYPE的部分就設為影片格式,接下來就是透過取得影片中包含的資訊,像是location、modificationDate、creationDate等等,而在取得影片的路徑部分,我們可以藉由下面的方式來取得所想要的路徑啦!
PHImageManager.default().requestAVAsset(for:myasset, ……){ (asset,audi,info) in
let videoPath = asset as !AVURLAsset
let path = videoPath.url.path
}
而要注意的是IOS在影片的部分可以透過上述方法來播放影片,但要拿來取得影片上傳則是要另外使用requestExportSession的方式,先做export到你的APP路徑下然後才能上傳唷!
既然android都提到縮圖那IOS也稍微講一下,在縮圖的部分也能透過Identifier來拿取對應的縮圖,而在影片的部份能使提供的方法取的指定時間的縮圖。
PHimageManager,default().requestAVAsset(forVideo: asset,……){
(avasset,…..) in
let generate = AVAssetImageGenerator(asset: asset)
generate.maximunSize = CGSize(width:360 , height:360)
generate.appliesPreferredTrackTransform = true
let time = CMTimeMakeWithSecond(1.0 , 60)
Do{
let img = try generate.copyCGImage(at:time,actualTime:nil)
} catch{
//error
}
}
結語:
這次提到很多原生的部分,其實在跨平台的應用都是需要仰賴原生Android or iOS來支援,也因此在網路雖然已經存在許多的套件,但到了專案需要很多更延伸的功能時,勢必要自己來撰寫原生得部分來讓自己的APP做出所想要的效果與功能,而在我們的PowerCloud中在做備份還原時,便使用到上述相關的功能,希望有興趣的人也可以來互相討論,除了擁有跨平台的JavaScript能力也順便一起精進原生的語言能力!