2013年7月13日 星期六

Android save file to external storage

在External storage下開一個app專屬資料夾並且儲存檔案:

首先建立資料夾

final String writeDir= Environment.getExternalStorageDirectory()+ "/YourAppName/log/"; File dir = new File(writeDir); dir.mkdirs();
case1. 寫入文字檔案
mFileWriter = new FileWriter(writeDir+ "/logFile.txt", true); mFileWriter.write("yayahihihello"); mFileWriter.flush(); mFileWriter.close();

case2. 使用FileOutputStream儲存圖檔


//這個路徑可以被內建的gallery app 找到 final String writePath = Environment.getExternalStorageDirectory()+"/Pictures/YourAPPName"; Bitmap bitmap = (拿到你要存的bitmap); //將Bitmap轉成bytes才能儲存 ByteArrayOutputStream bytes = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bytes); //使用FileOutputStream儲存bytes FileOutputStream fo = new FileOutputStream(f); fo.write(bytes.toByteArray()); bytes.close(); fo.close();

接著最後儲存的檔案編號繼續下去


String fileName,fileNameBase = "CanvasNetPic" ; int counter =1; fileName = "CanvasNetPic0"; File f = new File(savePath+"/"+fileName+".jpg"); while(f.exists()) { fileName = fileNameBase + Integer.toString(counter); f = new File(savePath+"/"+fileName+".jpg"); counter++; }



通知Android media scanner file system被改變過, 這樣新儲存的檔案才會馬上被gallery或其他content reader讀到


sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"+ Environment.getExternalStorageDirectory())));

但這樣子media scanner會去重新掃描整個ExternalStroage, 或是檔案很多或是device比較慢的話要掃很久, 會導致打開gallery以後要放著一段時間新儲存的檔案才會出來

只掃描儲存檔案的資料夾可以大幅減掃掃描時間:

sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"+ "你的儲存路徑")));

2013年7月6日 星期六

Android http post (file) + responsed json handling

以下code包含:建立一個連線, post file or value, 處理回傳的json 首先是http request post的部分: //設定連線timeout HttpParams httpParameters = new BasicHttpParams(); int timeoutConnection = 5000; HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection); //設定等待socket回傳timeout int timeoutSocket = 8000; HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket); HttpClient httpclient = new DefaultHttpClient(httpParameters); httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1); //建立post request HttpPost httppost = new HttpPost("http://xxxxx.php"); //要傳送的檔案 File file = new File(filePath); //android post傳送檔案內建好像只提供自己建立http header然後再手動在content中包入檔案的方式,頗麻煩,這邊使用apache的library來加入檔案. MultipartEntity mpEntity = new MultipartEntity(); ContentBody cbFile = new FileBody(file); mpEntity.addPart("File", cbFile); httppost.setEntity(mpEntity); //執行 HttpResponse response = httpclient.execute(httppost); 如果沒有要傳送檔案的話可以這樣: List nameValuePairs = new ArrayList(2); nameValuePairs.add(new BasicNameValuePair("id", "12345")); nameValuePairs.add(new BasicNameValuePair("stringdata", "AndDev is Cool!")); httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs)); 接著拿到response以後做json處理. BasicResponseHandler handler = new BasicResponseHandler(); String responseString = handler.handleResponse(response); //將回應的string parse成json 物件 JSONObject json = new JSONObject(responseString); //取值範例 if(json.has("Status")) { String status = json.getString("Status"); }

2013年7月1日 星期一

Ios animation sample (CABasicAnimation)

To start animation:

ImageView wave1,wave2 //basic sample CABasicAnimation *wave1ScaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; wave1ScaleAnimation.toValue = [NSNumber numberWithFloat:1.5]; wave1ScaleAnimation.duration = 1; //infinity loop wave1ScaleAnimation.repeatCount = HUGE_VALF; //totally 2 second per cycle wave1ScaleAnimation.autoreverses = YES; wave1ScaleAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; [wave1.layer addAnimation:wave1ScaleAnimation forKey:@"RecordingAnimation"]; //group animation sample CABasicAnimation *wave2ScaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; wave2ScaleAnimation.toValue = [NSNumber numberWithFloat:2.1]; CABasicAnimation *alphaAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"]; alphaAnimation.toValue = [NSNumber numberWithFloat:0.0]; //begin time and duration relative to group alphaAnimation.beginTime = 0.5; alphaAnimation.duration =0.5; CAAnimationGroup *group = [CAAnimationGroup animation]; //use CACurrentMediaTime() to get absolute begin Time group.beginTime = CACurrentMediaTime()+ 1; group.duration = 1; group.repeatCount = HUGE_VALF; group.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; group.animations = [NSArray arrayWithObjects:wave2ScaleAnimation, alphaAnimation,nil]; [wave2.layer addAnimation:group forKey:@"groupAnimation"];

To stop animation:

[wave1.layer removeAllAnimations]; [wave2.layer removeAnimationForKey:@"groupAnimation"];

[CABasicAnimation animationWithKeyPath:@"transform.scale"]中的keyPath如下表:


另一種較舊的animation用法:

[UIView animateWithDuration:0.5 delay:1.0 options: UIViewAnimationCurveEaseOut animations:^{ self.basketTop.frame = basketTopFrame; self.basketBottom.frame = basketBottomFrame; } completion:^(BOOL finished){ NSLog(@"Done!"); }]; }

順便附上很方便的alpha transition animation:

[UIView transitionWithView:myImageView duration:0.25f options:UIViewAnimationOptionTransitionCrossDissolve animations:^{ [rotateView setImage:[UIImage imageNamed:@"record_rotate_red.png"]]; } completion:nil];