標籤:windows phone 8.1 fileopenpicker onactivated事件 continuefileopenpick picksinglefileandcon
鑒於之前我有一篇部落格講訪問手機SD卡中的檔案的,那個是原Crowdsourced Security Testing道了檔案的路徑或者說知道了檔案放在那裡,所以
通過代碼直接擷取,當然是行得通的。但是很多情況下我們不知道我們要的檔案在SD卡的哪裡,我們要慢慢逐層查
找,然後選中後才行。這時就需要FileOpenPicker了。
訪問手機SD卡檔案的部落格地址: Windows Phone8.1中SD卡檔案的讀取寫入方法匯總
打個比方,一張自拍照,大部分女生呢要用美圖秀秀啊等美圖軟體修的美美的才能上傳到各個社交網站上去。當我們
要完成這個需求,我們的步驟是什麼呢?
第一種呢,當然可以直接開啟相簿,找到自拍照,選擇編輯方式,連結到美圖秀秀軟體開啟即可(這種連結應用的方
式也很常用,有必要掌握,這篇部落格不做介紹)
第二種呢,性子急的是直接開啟美圖秀秀,然後美圖裡有個按鈕讓你選擇你手機相簿中的具體那張圖片,這時跳出來
的讓你再手機中逐層尋找圖片,最終選擇到自拍照的過程就是FileOpenPicker來實現的。
微軟官方連結:FileOpenPicker
好了,知道了為什麼需要這個東西,那麼該瞭解下FilePicker的一些常見的屬性:
(很多屬性按字面意思來思考即可,並不是很難理解。其實看微軟官方連結更好更詳細,很有協助)
1.ViewMode(PickerViewMode類型) ------ 呈現項目的視圖模式 List/Thumbnail 項的列表/縮圖像集
2.SuggestedStartLocation(PickerLoactionId類型) --------- 呈現給我們的檔案的起始位置 documents/videos
/pictures/musicLibary downloads desktop homeGroup
3.CommitButtonText ------ 選擇檔案後我們要按的確認按鈕上面的文字
4.SettingIdentifier ------- 用到多個FileOpenPicker時給單個FileOpenPicker作的標識以示區分
注意:以上屬性在Windows Phone 8.1中無效
5.FileTypeFilter ------ 文件類型集合,其實就可以看作是檔案格式的過濾器,只篩選我們想要看的格式的檔案
搞定了屬性,有了一個大概的瞭解,就可以動手了
對於Windows 8及8.1的平台,兩者可能有一些小不同,但是基本都是一致的,版本的升級沒有改動多少。
直接上虛擬碼:
FileOpenPicker picker = new FileOpenPicker();//設定開啟的顯示模式picker.ViewMode = PickerViewMode.List;//起始開啟文檔顯示的視窗,這邊選擇的是案頭picker.SuggestedStartLocation = PickerLocationId.Desktop;//其實就是過濾的作用,規定你要開啟的是.txt檔案picker.FileTypeFilter.Add(".txt");// PickMultipleFilesAsync是選取多個檔案,// PickSingleFileAsync選取單個檔案StorageFile file = await picker.PickSingleFileAsync();if (file != null){//返回的是檔案名稱txtTitle.Text = file.Name;//返回的是檔案路徑//txtTitle.Text = file.Path;var stream = await file.OpenStreamForReadAsync();StreamReader sr = new StreamReader(stream);//這個是在你的.txt文本是以ANSI(國標)編碼的時候要規定encoding//StreamReader sr = new StreamReader(stream,Encoding.GetEncoding("GB2312"));string txt = await sr.ReadToEndAsync();txtContent.Text = txt;}
而Windows Phone平台的就不一樣了,遠比Windows來的麻煩些,WP8與WP8.1間的版本迭代也是有一些不同的
那麼Windows Phone麻煩在哪裡呢。
其一是手機存在著當FileOpenPicker起作用的時候,應用被掛起了,當FileOpenPicker選擇完成後,應用又要恢複過
來的情況,所以這個時候重寫OnActivated事件和ContinueFileOpenPicker函數就顯得關鍵和必要了
其二是Windows平台中的FileOpenPicker的選取單個或者多個檔案的屬性對應著PickerSingleFileAsync()和
PickMultipleFilesAsync(),雖說是非同步,就一個async和一個await就搞定了。而Windows Phone平台就只能
PickSingleFileAndContinue()和PickMultipleFilesAndContinue(),這個就是配合第一點的,處理起來麻煩。
總之一點,麻煩就麻煩在如何在調用檔案選擇器後繼續運行 Windows Phone 應用。下面給出微軟的解釋和解決方
案,大家看一下基本上就明白了,如果還是覺得太淩亂了,我的也可以將就看看了。
官方的解釋和解決方案:如何在調用檔案選擇器後繼續運行 Windows Phone 應用 (XAML)
麻煩歸麻煩,問題終究要解決的。而解決此問題分三大步,至於每一步的原因上面都做瞭解答。
首先要在App.xaml.cs中重寫OnActivated()事件
protected override void OnActivated(IActivatedEventArgs args){ if(args is FileOpenPickerContinuationEventArgs) { Frame rootFrame = Window.Current.Content as Frame; if(!rootFrame.Navigate(typeof(RepresentBook))) { throw new Exception("Failed to create target page"); } var page = rootFrame.Content as RepresentBook; page.FileOpenPickerEvent = (FileOpenPickerContinuationEventArgs)args; } Window.Current.Activate();}
其次在對應的頁面的.cs中執行個體化FileOpenPicker對象,把該有的屬性都設定好
private void findBtn_Click(object sender, RoutedEventArgs e){ //清空錯誤資訊 txtTip.Text = ""; //執行個體化FileOpenPicker對象-檔案選擇器 FileOpenPicker picker = new FileOpenPicker(); //設定開啟的顯示模式,這個在WP8.1上不起作用,而在Win8.1上還是有用的 //picker.ViewMode = PickerViewMode.Thumbnail; //其實開啟文檔顯示的視窗,這個在WP8.1上不起作用,而在Win8.1上還是有用的 //picker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary; //規定開啟的檔案格式 picker.FileTypeFilter.Add(".txt"); //利用ContinuationData 來記錄一些資訊,以保證應用恢複時能擷取應用掛起的資訊 picker.ContinuationData["Operation"] = "Text"; //提交按鈕上顯示的文本,在WP8.1上不起作用,在Win8.1上還是有用的 //picker.CommitButtonText = "找書"; //設定可選取單個檔案還是多個檔案 picker.PickSingleFileAndContinue();}
最後利用FileOpenPicker的頁面處理函數ContinueFileOpenPicker處理返回的資料
這個首先要給頁面這個類定義一個屬性,就是get,set嘛
private FileOpenPickerContinuationEventArgs _fileOpenPickerEventArgs = null;public FileOpenPickerContinuationEventArgs FileOpenPickerEvent{ get { return _fileOpenPickerEventArgs; } set { _fileOpenPickerEventArgs = value; ContinueFileOpenPicker(_fileOpenPickerEventArgs); }}
然後利用ContinueFileOpenPicker函數處理返回資料
public void ContinueFileOpenPicker(FileOpenPickerContinuationEventArgs args){ if ((args.ContinuationData["Operation"] as string) == "Text" && args.Files != null && args.Files.Count > 0) { StorageFile file = args.Files[0]; List<BookInfo> bookinfo = new List<BookInfo>(); Random random = new Random(); int ran = random.Next(1, 6); string imguri = "Assets/Images/" + ran + ".jpg"; int length = localSettings.Values.Count+1; string key = "booklist" + length.ToString(); if (!localSettings.Containers.ContainsKey(key)) { ApplicationDataCompositeValue composite = new ApplicationDataCompositeValue(); composite["bookimg"] = imguri; composite["bookname"] = file.Name; composite["bookpath"] = file.Path; if(localSettings.Values.Count==0) { localSettings.Values[key] = composite; } else { for (int i = 1; i < localSettings.Values.Count + 1; i++) { ApplicationDataCompositeValue composite2 = new ApplicationDataCompositeValue(); composite2 = (ApplicationDataCompositeValue)localSettings.Values["booklist" + i.ToString()]; if (composite2["bookname"].ToString()==file.Name) { txtTip.Text = "列表中已存在此書籍!"; } } if(txtTip.Text=="") { localSettings.Values[key] = composite; } } } if(localSettings.Values.Count!=0) { for (int i = 1; i < localSettings.Values.Count+1;i++ ) { ApplicationDataCompositeValue composite = new ApplicationDataCompositeValue(); composite = (ApplicationDataCompositeValue)localSettings.Values["booklist" + i.ToString()]; bookinfo.Add(new BookInfo { bookImg = composite["bookimg"].ToString(), bookName = composite["bookname"].ToString(), bookPath = composite["bookpath"].ToString() }); } listbox.ItemsSource = bookinfo; } }}
以上都是虛擬碼,大家弄清楚思想即可。
推薦連結:
編程小夢:windows phone 8.1開發:檔案選取器FileOpenPicker
Win8和Windows Phone 8.1資源橋樑:FileOpenPicker