2013年5月27日 星期一

跳出UIPickerView來做選擇(有限資料)的做法



雖然覺得這樣的使用有點麻煩(太囉唆),但是還是記錄一下。



.h內的interface中加入UIPickerViewDelegate,UIActionSheetDelegate,UIPickerViewDataSource並且所使用的視圖元件要連接Outlets-Delegate要連接到File's Owners,否則無法抓到回傳的event。 
部分程式碼如下:

1.建立一個button並將Outlets-Delegate要連接到File's Owners
2.建立一個function內容如下,用button來觸發    
    //建立動作表
    UIActionSheet *SpeakSheet=[[UIActionSheet alloc]initWithTitle:@"\n\n\n\n\n\n\n\n\n\n\n\n\n" delegate:self cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:@"set Sepaker", nil];
    //顯示動作表
    [SpeakSheet showInView:self.view];
    
    //建立挑選器視圖
    UIPickerView *SpeakPickerView = [[UIPickerView alloc]init];
    SpeakPickerView.tag=101;
    SpeakPickerView.delegate=self;
    SpeakPickerView.dataSource=self;
    SpeakPickerView.showsSelectionIndicator=YES;
    [SpeakSheet addSubview:SpeakPickerView];
3.如果有連接到File's Owner's就會被觸發,就可以在接到資訊
#pragma mark -
#pragma mark - SpeakPickerView methods
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
    if (pickerView.tag==101){
        return 1;
    }
    return 1;//N個轉軸
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
    if (pickerView.tag==101){
        return SpeakName.count;
    }
    return 1;//每個轉軸N個選項
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
    NSLog(@"component:%i  row:%i",component,row);
    if (pickerView.tag==101){
        return [SpeakName objectAtIndex:row];
    }
    return @"error";
}
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
    NSLog(@"clickedButtonAtIndex %i",buttonIndex);//回傳資料的地方
    //這裡沒寫完,要判斷要切換到誰,不過不重要,因為要換方法,所以就不再寫
    
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
    //當選定的時候從這邊抓取值,當按下click之後即可,讀取最正確地值作處理
    NSLog(@"didSelectRow");
}

2013年5月12日 星期日

[Android]製作簡易的自動更新機制

在Android上要怎麼製作簡易的自動更新機制呢?
1.按下一個button,送出去檢查apk版本,並比對網路上的版本,如果一致(不更新),不一致(更新),大概就是這樣,清楚明瞭。

大概幾個重點:
1.取得APK的版本:
   getPackageManager().getPackageInfo(getPackageName(),0).versionName;
2.下載:
   downLoadFile()   //參考此function
3.intent安裝
  Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(path,fileName)),"application/vnd.android.package-archive");
startActivity(intent);

完整的code大致上如下所示:
//取得網站上的最新版本
    public void checkUpdateVersion() {
     try {
         //Log.e("tdy", "checkUpdate start");
            URL updateURL = new URL(Versionurl);              
            URLConnection conn = updateURL.openConnection();
            InputStream is = conn.getInputStream();
            BufferedInputStream bis = new BufferedInputStream(is);
            ByteArrayBuffer baf = new ByteArrayBuffer(50);
           
            int current = 0;
            while((current = bis.read()) != -1){
                 baf.append((byte)current);
            }

            /* Convert the Bytes read to a String. */
            final String s = new String(baf.toByteArray());        
           
            /* Get current Version Number */
            s_curVersion = getPackageManager().getPackageInfo(getPackageName(),0).versionName;
            s_newVersion = s;
            //Log.e("tdy",s_curVersion+" = "+s_newVersion);
            if (s_curVersion.equals(s_newVersion)){
             //Log.e("tdy","不需更新");  
             mHandler.post(showVersion);
            }else{
             //Log.e("tdy","需更新");
             mHandler.post(showUpdate);
            }
        } catch (Exception e) {
         //Log.e("tdy","網路發生錯誤");
         e.printStackTrace();         
        }
    }
    //更新資料
    private Runnable showUpdate = new Runnable(){
        public void run(){
         new AlertDialog.Builder(SpeakSettings.this)
         .setTitle("軟體更新")
         .setMessage("目前版本("+s_curVersion+")\n發現新版本("+s_newVersion+"),是否更新?")
         .setPositiveButton("更新", new DialogInterface.OnClickListener() {
                 public void onClick(DialogInterface dialog, int whichButton) {
                         /* User clicked OK so do some stuff */
                   pBar = new ProgressDialog(SpeakSettings.this);
      pBar.setTitle("正在下載");
      pBar.setMessage("請稍候...");
      pBar.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
      pBar.setIndeterminate(false);//設置進度條是否不明確
      pBar.setCancelable(true);
      pBar.setProgress(100);
      pBar.show();
      //開始下載
      Thread thread = new Thread(){
            public void run(){
              Message message = new Message();
         message.what = downLoadFile(fileurl, fileName, path);
         msghandler.sendMessage(message);
            }
      };
      thread.start();
      
                 }
         })
         .setNegativeButton("暫不更新", new DialogInterface.OnClickListener() {
                 public void onClick(DialogInterface dialog, int whichButton) {
                         /* User clicked Cancel */
                 }
         })
         .show();
        }
    };
    //show目前版本
    private Runnable showVersion = new Runnable(){
        public void run(){
         new AlertDialog.Builder(SpeakSettings.this)
         .setTitle("軟體更新")
         .setMessage("目前為最新版本("+s_curVersion+")")
         .setNegativeButton("好", new DialogInterface.OnClickListener() {
                 public void onClick(DialogInterface dialog, int whichButton) {
                         /* User clicked Cancel */
                 }
         })
         .show();
        }
    };
    //下載檔案
    public int downLoadFile(String httpUrl, String fileName, String path) {
     try {
      // 當存放文件的文件目錄不存在的時候創建該文件目錄
      File tmpFile = new File(path);
      if (!tmpFile.exists()) {
       tmpFile.mkdir();
      }
      //this is the file to be downloaded
   URL url = new URL(httpUrl);
   //create the new connection
   HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
   //set up some things on the connection
   urlConnection.setRequestMethod("GET");
   urlConnection.setDoOutput(true);
   //and connect!
   urlConnection.connect();

   File file = new File(path,fileName);
   //this will be used to write the downloaded data into the file we created
   FileOutputStream fileOutput = new FileOutputStream(file);
   //this will be used in reading the data from the internet
   InputStream inputStream = urlConnection.getInputStream();
   //this is the total size of the file
   int totalSize = urlConnection.getContentLength();
   //variable to store total downloaded bytes
   int downloadedSize = 0;
   //create a buffer...
   byte[] buffer = new byte[1024];
   int bufferLength = 0; //used to store a temporary size of the buffer
   //now, read through the input buffer and write the contents to the file
   while ( (bufferLength = inputStream.read(buffer)) > 0 ) {
    //add the data in the buffer to the file in the file output stream (the file on the sd card
    fileOutput.write(buffer, 0, bufferLength);
    //add up the size so we know how much is downloaded
    downloadedSize += bufferLength;
    //this is where you would do something to report the prgress, like this maybe
    //updateProgress(downloadedSize, totalSize);
    pBar.setProgress(downloadedSize*100/totalSize);    
   }
   //close the output stream when done
   fileOutput.close();
     }catch (Exception e) {
   // TODO: handle exception
      return 0;
  }
        return 1;
    }
    //顯示下載完畢或失敗的event
    public Handler msghandler = new Handler() {
  public void handleMessage(android.os.Message msg) {
   super.handleMessage(msg);
   if (msg.what == 1) {
    Toast.makeText(getApplicationContext(), "下載成功!!", Toast.LENGTH_LONG).show();
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setDataAndType(
      Uri.fromFile(new File(path,fileName)),
      "application/vnd.android.package-archive");
    startActivity(intent);
   } else {
    Toast.makeText(getApplicationContext(), "下載失敗!!", Toast.LENGTH_LONG).show();    
   }
   pBar.cancel();
  }
 };