搜尋此網誌

2010年5月29日 星期六

Android開發-droiddraw

前陣子開發iphone 這次跳到android來開發 最不習慣的就是 android怎麼 沒有一個可以直接拖拉介面的東西 用的很不習慣 這次來介紹一個其他人所開發的程式 可以讓你直接藉由拖拉的方式 產生xml

首先先下載 http://code.google.com/p/droiddraw/下載之後解壓縮 執行exe檔
以下是執行畫面 你可以從右手邊 拖拉元件 到左邊 呈現在手機上的畫面

拖拉完畢之後 按下方Generate 將產生的xml 複製到 你的專案下的res->layout->main.xml下 就可以完成了 雖然很方便
不過還是建議 入門時 還是先學會用手輸入的方式 順便學習一下xml 這樣觀念比較清楚

Android開發-環境建置

作業系統:win7 x32

首先先下載
1.JDK
2.Eclipse (我是下載 Eclipse IDE for Java Developer)
接著將Eclipse解縮到C槽 (看你的喜好)
3.android sdk (android 2.2)
同樣的解壓縮到C槽(看你的喜好)

.設定環境變數
開啟控制台->系統->左邊進階系統設定->進階->環境變數
找到path變數 按編輯 打入以下C:\Program Files\Java\jre6\bin;C:\android_sdk\tools;
不過目前似乎可以不需要設定以上環境變數 如果有問題 再自行設定看看

.安裝 ADT 擴充套件

打開Eclipse 點上方help->install new software
按add 在Location這個地方 輸入以下網址:
http://dl-ssl.google.com/android/eclipse/site.xml
Name的欄位 我是填寫android
接著會花一些時間 找尋適合的版本
等下方出現Developer Tools 就全選 按next 最後安裝完成之後 按finish
安裝完成之後 他會要你重新啟動Eclipse

.設定Android SDK
打開Eclipse 選上方window->preference->左邊Android
接著在SDK Loaction的地方 選擇你剛剛解壓縮android sdk的路徑 因為我解壓縮到C曹 因此我設定成C:\android_sdk 選好之後 你會發現下方怎麼都沒東西!?正常來說應該會有東西 沒關係別擔心 接著進行以下步驟

.更新package
打開Eclipse 選上方window->Android SDK and AVD manager ->左手邊Installed Packages->update all->接著會列出很多需要安裝的package->選Accept all->按install
這邊的安裝會花一段時間 我的網路是偽光纖 都需要下載大約半小時以上 所以就耐心等待他安裝完成吧

.設定 Android 虛擬機器
打開Eclipse->選上方windows->Android SDK and AVD manager->左手邊virtual device->點右方new
接著會跳出一個選單 需要填入一些模擬器的資訊

name填入android(這邊看你的喜好)
Target 這邊我選android 2.2 (android模擬器相當強大 可以模擬很多硬體 像是要寫google map的相關應用 這邊要選Google APIS)
SD Card
Size 的地方 我填入1024
Skin的地方 我選built-in
Hardware的地方 就讓他保持原預設值

接著按Creat AVD

接著恭喜你 以上步驟 就可以將環境設定好了 可以開始開發android程式了 第一次跑模擬器的時候 需要花一些時間 當然cpu不能太爛 不然真的會花很多時間 筆者電腦
AMD AM2 4800+ 也跑了大概5分鐘左右(印象中)

以下提供一開始入門學習android的網站
1.深入淺出 Android -- Google 手持設備應用程式設計入門
2.Android 官方教學

2010年5月18日 星期二

iphone開發-UIImageView

在iPhone程式中,每個程式裡面會有唯一一個UIWindow這個View,剩下的所有的View都會包含在UIWindow中,因此每個View會產生階層的形式,一層蓋著一層

此次的程式可以學到:
1.如何用寫code的方式 將圖片用全螢幕的形式呈現在view上
2.如何將小圖片加入目前的view上
3.如何清除上一個View

test14ViewController.h


#import <UIKit/UIKit.h>

@interface test14ViewController : UIViewController {
UIImageView *myImage;
}
//讓myImage 可以使用dot syntax
@property(nonatomic,retain)UIImageView *myImage;
-(IBAction)addimage:(id)sender;
-(IBAction)reset:(id)sender;
-(void)image;

@end

test14ViewController.m

#import "test14ViewController.h"

@implementation test14ViewController

@synthesize myImage;


- (void)viewDidLoad {

[super viewDidLoad];
//讓圖片可以全螢幕
UIImageView *myView=[[UIImageView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
//指定圖片檔名
[myView setImage:[UIImage imageNamed:@"jokeman1.png"]];
//設定圖片的透明度 值為0.0~1.0(圖片隱藏~完全不隱藏)
[myView setAlpha:0.2];
//將myView加入到目前的view 蓋上去
[self.view addSubview:myView];

}
-(IBAction)addimage:(id)sender
{
[self image];
}

-(IBAction)reset:(id)sender
{
//[myImage setHidden:YES];(將myImage隱藏)
//將myImage移除
[myImage removeFromSuperview];


}

-(void)image
{
//前兩個座標指定圖片的顯示區域 後兩個設定圖片長寬
CGRect myImageRect = CGRectMake(130.0f, 150.0f, 64.0f, 71.0f);
myImage = [[UIImageView alloc] initWithFrame:myImageRect];
[myImage setImage:[UIImage imageNamed:@"butterfly.png"]];
//加入到目前的view
[self.view addSubview:myImage];
[myImage release];
}


- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];

// Release any cached data, images, etc that aren't in use.
}


- (void)dealloc {
[super dealloc];
}

@end

2010年5月16日 星期日

iphone開發-Peer-to-Peer Connectivity used by Bluetooth

最近寫過wifi 也有看到怎麼用藍芽來建立雙方連線 順便記錄一下

GamekitTestViewController.h

#import <UIKit/UIKit.h>
#import <GameKit/GameKit.h>

@interface GameKitTestViewController :
//用GKPeerPickerControllerDelegate 協定
UIViewController <GKPeerPickerControllerDelegate,GKSessionDelegate>
{
GKPeerPickerController *mPicker;
GKSession *mSession;
IBOutlet UITextField *mTextField;
IBOutlet UITextView *mTextView;
NSMutableArray *mPeers;
}
-(IBAction) connectClicked:(id)sender;
-(IBAction) sendData:(id)sender;
@property (retain) GKSession *mSession;

@end

GameKitTestViewController.m

#import " GameKitTestViewController.h "

@implementation GameKitTestViewController

@synthesize mSession;

- (void)viewDidLoad {
[super viewDidLoad];

mPicker=[[GKPeerPickerController alloc] init];
mPicker.delegate=self;
//使用iphone內建介面 讓user選擇要wifi or bluetooh
//但這邊須注意一點是 iphone 藍芽的部分 會自動幫你建立雙方的連線 但是透過
wifi的話 就要自己寫 可以參考我前幾篇
mPicker.connectionTypesMask = GKPeerPickerConnectionTypeNearby | GKPeerPickerConnectionTypeOnline;
mPeers=[[NSMutableArray alloc] init];
//顯示週遭有哪些peer
[mPicker show];
}

//當user選擇哪種連線時 就會呼叫下列method
- (void)peerPickerController:(GKPeerPickerController *)picker didSelectConnectionType:(GKPeerPickerConnectionType)type{
if (type == GKPeerPickerConnectionTypeOnline) {
picker.delegate = nil;
[picker dismiss];
[picker autorelease];
}
}
//當peer picker 需要session 就會呼叫此method 也就是準備session讓其他peer可以連進來
- (GKSession *)peerPickerController:(GKPeerPickerController *)picker sessionForConnectionType:(GKPeerPickerConnectionType)type{

NSString *txt=mTextField.text;
GKSession* session = [[GKSession alloc] initWithSessionID:@"test" displayName:txt sessionMode:GKSessionModePeer];
[session autorelease];
return session;
}

//當連線建立完成時 會呼叫此method
- (void)peerPickerController:(GKPeerPickerController *)picker didConnectPeer:(NSString *)peerID toSession:(GKSession *)session{

NSLog(@"Connected from %@",peerID);

self.mSession = session;
session.delegate = self;
[session setDataReceiveHandler: self withContext:nil];
picker.delegate = nil;
[picker dismiss];
[picker autorelease];
}

//這邊如同wifi 就不再敘述了
- (void)session:(GKSession *)session peer:(NSString *)peerID didChangeState:(GKPeerConnectionState)state{

switch (state)
{
case GKPeerStateConnected:
{
NSString *str=[NSString stringWithFormat:@"%@\n%@%@",mTextView.text,@"Connected from pier ",peerID];
mTextView.text= str;
NSLog(str);
[mPeers addObject:peerID];
break;
}
case GKPeerStateDisconnected:
{
[mPeers removeObject:peerID];

NSString *str=[NSString stringWithFormat:@"%@\n%@%@",mTextView.text,@"DisConnected from pier ",peerID];
mTextView.text= str;
NSLog(str);
break;
}
}
}

2010年5月15日 星期六

iphone開發-從一個class呼叫另一個class的method

假設有ClassA ClassB 我要在ClassB中 呼叫ClassA的method
可以用以下程式的寫法

ClassA.h

@interface ClassA:UIViewController{

}
-(int)calculate;

ClassA.m

@implementation ClassA

-(int)calculate
{
int x=5;
return x;
}

ClassB.h

@interface ClassB:UIViewController{

}
-(IBAction)test:(id)sender;

ClassB.m
//要import ClassA.h
#import " ClassA.h "
#import " ClassB.h "

@implementation ClassB
-(IBAction)test:(id)sender
{
int y;
//先alloc 再init 相當於Java中的new
//產生ClassA 的instance
ClassA *integer=[[ClassA alloc]init];
//這樣y值就會得到5
y=[integer calculate];
[integer release];

}

iphone開發-透過按鈕切換view

這次我將程式分開成兩個class來寫 順便練習怎麼各自呼叫對方的method 另外我這次設計了兩個xib 當一開始classA的xib載入後 我按下按鈕之後 程式能切換到class B的xib

test12ViewController.h

// forward declaration
@class Testcontroller;

@interface test12ViewController : UIViewController {

//另外一個class
Testcontroller *testcontroller;

}
//以下這樣寫 就可以使用dot syntax
@property(nonatomic,retain)Testcontroller *testcontroller;
//用來切換不同的view
-(IBAction)change:(id)sender;
-(int)display;


@end

test12ViewController.m

#import " test12ViewController.h "
//用Testcontroller產生一個instance object
#import " Testcontroller.h "

@implementation test12ViewController
@synthesize testcontroller;

-(IBAction)change:(id)sender
{
if (self.testcontroller==nil) {
//載入Testcontroller的xib
Testcontroller *testcontrollertemp=[[Testcontroller alloc]initWithNibName:@"Testcontroller" bundle:nil];
self.testcontroller=testcontrollertemp;

[testcontrollertemp release];
//加到原本的view上面
[self.view addSubview:testcontroller.view];

}
}
-(int)display
{
int x=5;
return x;
}

- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];

// Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}


- (void)dealloc {
[testcontroller release];
[super dealloc];
}

@end

testcontroller.m

#import " Testcontroller.h "
//必須記得import以下 因為要產生test12ViewController的instance
//若沒有加入這段 會出現 "XXX may not respond to class"
#import " test12ViewController.h "


@implementation Testcontroller
@synthesize display;






- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];

// Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}

-(IBAction)test:(id)sender
{
int y;
//產生test12ViewController的instance
test12ViewController *integer=[[test12ViewController alloc]init];
//透過這個instance 去呼叫test12ViewController的method
y=[integer display];
//將int轉換成字串
NSString *dispalytext=[[NSString alloc]initWithFormat:@"%d",y];
display.text=dispalytext;
[integer release];
[dispalytext release];

}
- (void)dealloc {
[super dealloc];
}


@end

2010年5月6日 星期四

iphone開發-Peer-to-Peer Connectivity used by Wifi

今天幫Lab的同學寫了一個程式 透過wifi 讓兩台iphone連線 然後讓其中一台播放音樂時 另外一台也能自動放出音樂
而這次程式主要是用到Gamekit API 還有Avaudioplayer

" test10ViewController.h"
//用Gamekit api前 要先import以下這行
#import <GameKit/GameKit.h>
#import <UIKit/UIKit.h>

//用GKSessionDelegate協定
@interface test10ViewController : UIViewController <GKSessionDelegate>
{
UILabel *display;
NSString *sessionID;
//產生GKsession 物件
GKSession *myGKSession;
NSString *peerList;
AVAudioPlayer *audioPlayer;
//存放物件的陣列
NSMutableArray *mPeers;

}
@property(nonatomic,retain)IBOutlet UILabel *display;


-(IBAction)play:(id)sender;
-(IBAction)stop:(id)sender;
-(void) setupSession;
- (void) destroySession;
-(void) disconnectCurrentCall;
-(void) sendData;

@end

" test10ViewController.m"

//在這邊先定義sessionID 兩台手機靠這個來辨識對方 所以雙方都要一樣
有點像在Java寫的UUID

#define sessionID @"connecttest"

- (void)viewDidLoad {
[super viewDidLoad];
//呼叫setupSession method
[self setupSession];
//指定音樂檔案的路徑
NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/audio.mp3", [[NSBundle mainBundle] resourcePath]]];
NSError *error;
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
//初始化陣列
mPeers=[[NSMutableArray alloc] init];
}
-(void)setupSession
{
//GKSessionModerPeer 表示此程式可當Server or Client 詳細的說明 請看Library
//初始化Session
myGKSession = [[GKSession alloc] initWithSessionID:sessionID displayName:nil sessionMode:GKSessionModePeer];

myGKSession.delegate = self;

[myGKSession setDataReceiveHandler:self withContext:nil];
//設定為YES 將服務發佈出去
myGKSession.available = YES;

}
-(IBAction)play:(id)sender
{
audioPlayer.currentTime = 0;
[audioPlayer play];
//按下播放按鈕之後 將字串傳出去
[self sendData];
}
-(IBAction)stop:(id)sender
{
[audioPlayer stop];
}
//此處可將字串傳送給對方 我這邊是用來讓另外一台手機判斷 何時放音樂之用
-(void) sendData
{
NSString *str=@"test";
[myGKSession sendData:[str dataUsingEncoding: NSASCIIStringEncoding] toPeers:mPeers withDataMode:GKSendDataReliable error:nil];

}
//當收到data時 呼叫此method
-(void) receiveData:(NSData *)data fromPeer:(NSString *)peer inSession: (GKSession *)session context:(void *)context
{
NSString *str4 = @"test";
NSString* aStr;
aStr = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
//判斷字串是否相同
if([str4 isEqualToString:aStr])
{
//相同就放音樂
[audioPlayer play];

}


}

- (void)session:(GKSession *)session peer:(NSString *)peerID didChangeState:(GKPeerConnectionState)state
{
switch (state) {
//發現服務時 會跳到此case
case GKPeerStateAvailable:
peerList=peerID;
display.text=[myGKSession displayNameForPeer:peerID];
//將peerID加到陣列中 用來傳送資料 要傳給哪個peer的紀錄之用
[mPeers addObject:peerID];
//連線到提供服務的peer
[myGKSession connectToPeer:peerID withTimeout:10.0];
break;

case GKPeerStateUnavailable:
peerList=nil;
display.text=@"No Service";
break;
case GKPeerStateDisconnected:


peerList=nil;

break;

case GKPeerStateConnecting:



break;
//連線之後 就會跳到此case
case GKPeerStateConnected:
display.text=@"Connect Sucessfully";
//切換到view2
[[NSBundle mainBundle]loadNibNamed:@"view2" owner:self options:NULL];
break;
default:

break;
}
//當有client請求連線 就會呼叫此method
- (void)session:(GKSession *)session didReceiveConnectionRequestFromPeer:(NSString *)peerID
{
//接受此client的連線要求
[myGKSession acceptConnectionFromPeer:peerID error:nil];
}

PS:另外要記得加入Gamekit framework
程式以上就大致完成了

Game Kit programming Guide