こんな感じのようです。
- (void)method:(id)object
{
// objectがNSStringクラスかどうかを確認
if ([object isKindOfClass:[NSString class]]) {
// NSStringクラスの場合
...
}
- (void)method:(id)object
{
// objectがNSStringクラスかどうかを確認
if ([object isKindOfClass:[NSString class]]) {
// NSStringクラスの場合
...
}
- (void)viewDidLoad {
UITextField *textField = [[[UITextField alloc]
initWithFrame:CGRectMake(10, 10, 200, 31)]
autorelease];
textField.borderStyle = UITextBorderStyleRoundedRect;
[textField addTarget:self
action:@selector(editingDidEnd:)
forControlEvents:UIControlEventEditingDidEndOnExit];
[self.view addSubview:textField];
}
- (void)editingDidEnd:(id)sender {
UITextField *textField = (UITextField *)sender;
[textField resignFirstResponder];
}
package com.example.atwitter;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import twitter4j.Paging;
import twitter4j.ResponseList;
import twitter4j.Status;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
import twitter4j.User;
import twitter4j.conf.ConfigurationBuilder;
import twitter4j.http.AccessToken;
import twitter4j.http.RequestToken;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
// キー
private static String CONSUMERKEY ="XXXXXX";
private static String CONSUMERSECRET ="XXXXXX";
private static String ACCESSTOKEN ="XXXXXX";
private static String ACCESSSECRET ="XXXXXX";
// コールバックURL
private final String CALLBACK_URL="testapp://atwitter/";
private static String SNL = System.getProperty("line.separator");
private static String DNL = SNL + SNL;
// Twitter
private Twitter twitter;
private AccessToken accessToken;
// TextView
private TextView textView;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Twitterの初期化
initializeTwitter(null);
// TextViewを保持
textView = (TextView)findViewById(R.id.TextView01);
// ボタンにコールバックを登録
Button button = (Button)findViewById(R.id.Auth);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// twitterアクション実行
String result = doOAuth(twitter);
textView.setText(result);
}
});
button = (Button)findViewById(R.id.Button01);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// twitterアクション実行
String result = userTimeline(twitter);
textView.setText(result);
}
});
}
private void initializeTwitter(AccessToken accessToken) {
ConfigurationBuilder confBuilder = new ConfigurationBuilder();
confBuilder.setOAuthConsumerKey(CONSUMERKEY);
confBuilder.setOAuthConsumerSecret(CONSUMERSECRET);
TwitterFactory twitterFactory = new TwitterFactory(confBuilder.build());
twitter = twitterFactory.getOAuthAuthorizedInstance(accessToken);
}
public String userTimeline(Twitter twitter){
ResponseList statuses = null; //
String result = "print userTimeline:" + DNL;
int pageNumber =1;
int count = 20;
//Paging
Paging paging = new Paging(pageNumber, count);
try {
statuses = twitter.getUserTimeline(paging);
if (statuses != null) {
for (Status status :statuses) {
result += status.getUser().getScreenName() +":"
+ SNL + status.getText() + DNL;
}
}
} catch (Exception e) {
result += e.getMessage();
e.printStackTrace();
}
return result;
}
private String doOAuth(Twitter twitter_) {
String result = "doOAuth:" + DNL;
Twitter twitter = new TwitterFactory().getInstance();
twitter.setOAuthConsumer(CONSUMERKEY, CONSUMERSECRET);
// RequestTokenを取得
RequestToken requestToken = null;
try {
requestToken = twitter.getOAuthRequestToken(CALLBACK_URL);
}
catch (TwitterException e) {
result += e.getMessage() + DNL;
e.printStackTrace();
}
// RequestTokenを保存
ObjectOutputStream oos;
try {
OutputStream out = openFileOutput("RequestToken", MODE_PRIVATE);
oos = new ObjectOutputStream(out);
oos.writeObject(requestToken);
} catch (Exception e) {
result += e.getMessage() + DNL;
e.printStackTrace();
}
// 認証ページへ
String strUrl = requestToken.getAuthorizationURL();
Uri uri = Uri.parse(strUrl);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
result += strUrl;
return result;
}
// 起動時に呼ばれる(認証完了時も呼ばれる)
@Override
public void onResume() {
super.onResume();
String result = "";
// extract the OAUTH access token if it exists
Uri uri = this.getIntent().getData();
if (uri != null && uri.toString().startsWith(CALLBACK_URL)) {
RequestToken requestToken = null;
try {
InputStream in = openFileInput("RequestToken");
ObjectInputStream ois = new ObjectInputStream(in);
requestToken = (RequestToken)ois.readObject();
} catch (Exception e) {
result += e.getMessage() + DNL;
e.printStackTrace();
}
String access_token = uri.getQueryParameter("oauth_verifier");
try {
accessToken = twitter.getOAuthAccessToken(requestToken, access_token);
initializeTwitter(accessToken);
// ここでAccessTokenを保存しておけば次回から認証不要となる
textView.setText("認証完了");
} catch (TwitterException e) {
result += e.getMessage() + DNL;
e.printStackTrace();
}
}
}
}
ポイントは、<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.atwitter"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".MainActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="testapp" android:host="atwitter" android:path="/"/>
</intent-filter>
</activity>
</application>
<uses-sdk android:minSdkVersion="4" />
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
</manifest>
24行目でuses-permissionを使ってINTERNETを許可しています。あと、17行目でコールバックURLをフックしています。<?xml version="1.0" encoding="utf-8"?>
<FrameLayout android:id="@+id/FrameLayout01" android:layout_width="fill_parent" android:layout_height="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android">
<TextView android:id="@+id/TextView01" android:layout_height="fill_parent" android:layout_width="fill_parent" android:text="Hello, twitter!"></TextView>
<LinearLayout android:id="@+id/LinearLayout01" android:layout_height="wrap_content" android:layout_gravity="bottom" android:layout_width="wrap_content">
<Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="認証" android:id="@+id/Auth"></Button>
<Button android:id="@+id/Button01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="タイムラインとか"></Button>
</LinearLayout>
</FrameLayout>
特別なことは何も。UILabel *label = [[UILabel alloc] initWithFrame:frame]; label.userInteractionEnabled = YES;
- (void)switchToolbar {
// ツールバーの表示/非表示を切り替える
[UIView beginAnimations:nil context:nil];
{
// 時間を0.25とする
[UIView setAnimationDuration:0.25];
CGFloat toAlpha;
if (toolbar_.hidden) {
toolbar_.alpha = 0.0;
toolbar_.hidden = NO;
toAlpha = 1.0;
}
else {
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(animationDidStop)];
toAlpha = 0.0;
}
toolbar_.alpha = toAlpha;
}
[UIView commitAnimations];
}
- (void)animationDidStop {
toolbar_.hidden = YES;
}
typedef enum {
MyClassConstValue1,
MyClassConstValue2,
} MyClassConstValue;
@interface MyClass : NSObject {
}
@end
あ、値を持つ定数はどうするのかな。
// 日付のオフセットを生成 NSDateComponents *dateComp = [[NSDateComponents alloc] init]; // 1日後とする [dateComp setDay:1]; // 1日後のNSDateインスタンスを取得する NSDate *date = [[NSCalendar currentCalendar] dateByAddingComponents:dateComp toDate:[NSDate date] options:0]; [dateComp release];1日前の日付を取得する場合は[dateComp setDay:-1]で、1ヶ月後とかだとsetMonthを利用します。
- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
[super setEditing:editing animated:animated];
// テーブルの編集モードを変更
[myTableView setEditing:editing animated:animated];
}
private Bitmap yuv2monochrome(byte data[], int width, int height, int[] buffer) {
int y;
for (int i = 0; i < width * height; i++) {
y = data[i];
buffer[i] = 0xff000000 | y << 16 | y << 8 | y;
}
return Bitmap.createBitmap(buffer, width, height, Config.RGB_565);
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// タイトルバーを消す
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
// ステータスバーを消す
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
@interface MyViewController : UIViewController {
// 3桁NumberFormatter
NSNumberFormatter *formatter;
}
@property (nonatomic, assign) NSNumberFormatter *formatter;
- (NSNumberFormatter *)formatter {
if (formatter == nil) {
formatter = [[NSNumberFormatter alloc] init];
[formatter setPositiveFormat:@"#,##0"];
}
return formatter;
}
- (void)dealloc {
[formatter release];
[super dealloc];
}
str = [self.formatter stringFromNumber:[NSNumber numberWithInt:2010]];
NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"CoreDataTest.sqlite"]];
NSString *storePath = [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"CoreDataTest.sqlite"];
NSFileManager *fileManager = [NSFileManager defaultManager];
// データがなければデフォルトデータをコピーする
if (![fileManager fileExistsAtPath:storePath]) {
NSString *defaultStorePath = [[NSBundle mainBundle] pathForResource:@"CoreDataTest" ofType:@"sqlite"];
if (defaultStorePath) {
[fileManager copyItemAtPath:defaultStorePath toPath:storePath error:NULL];
}
}
NSURL *storeUrl = [NSURL fileURLWithPath:storePath];
<RelativeLayout
android:id="@+id/RelativeLayout01"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
>
<android.opengl.GLSurfaceView
android:id="@+id/GlView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:keepScreenOn="true">
</android.opengl.GLSurfaceView>
<com.example.CameraView
android:id="@+id/CameraPreview"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
</com.example.CameraView>
</RelativeLayout>
SurfaceViewを継承したCameraViewを追加しています。package com.example;
import android.app.Activity;
import android.graphics.PixelFormat;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
public class GLTestActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 画面を構築
setContentView(R.layout.main);
// GL
GLSurfaceView glSurfaceView = (GLSurfaceView)findViewById(R.id.GlView);
glSurfaceView.setEGLConfigChooser(8, 8, 8, 8, 16, 0);
glSurfaceView.setRenderer(new CubeRenderer(true));
glSurfaceView.getHolder().setFormat(PixelFormat.TRANSLUCENT);
}
}
ポイントはGLSerfaceView#setEGLConfigChooser()とSurfaceHolder#setFormat()です。package com.example;
import android.content.Context;
import android.hardware.Camera;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class CameraView extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder _holder;
private Camera _camera;
public CameraView(Context context) {
super(context);
// サーフェイスホルダーの生成
_holder = getHolder();
_holder.addCallback(this);
// プッシュバッッファの指定
_holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public CameraView(Context context, AttributeSet attrs) {
super(context, attrs);
// サーフェイスホルダーの生成
_holder = getHolder();
_holder.addCallback(this);
// プッシュバッッファの指定
_holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// カメラのプレビュー開始
Camera.Parameters parameters = _camera.getParameters();
parameters.setPreviewSize(width, height);
_camera.setParameters(parameters);
_camera.startPreview();
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
// カメラの初期化
try {
_camera = Camera.open();
_camera.setPreviewDisplay(holder);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// カメラのプレビュー停止
_camera.setPreviewCallback(null);
_camera.stopPreview();
_camera.release();
_camera = null;
}
}
private class PreviewDraw implements Runnable {
private byte[] _data;
@Override
public void run() {
bitmap = BitmapUtil.yuv2rgb(_data, _previewSize.width, _previewSize.height, _rgbBuffer);
// 描画
if (bitmap != null) {
Canvas canv = holder.lockCanvas();
if (canv != null) {
canv.drawBitmap(bitmap, 0, 0, null);
holder.unlockCanvasAndPost(canv);
}
}
}
public void setData(byte[] data) {
_data = data;
}
}
private final Camera.PreviewCallback previewCallback =
new Camera.PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera camera) {
_previewDraw = new PreviewDraw();
_previewDraw.setData(data);
Thread thread = new Thread(_previewDraw);
thread.start();
}
};
<pre name="code" class="c">
int main() {
printf("Hello, World!");
exit(0);
}
</pre>
int main() {
printf("Hello, World!");
exit(0);
}
<?xml version="1.0" encoding="utf-8"?>
<framelayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<com.example.CameraView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/SurfaceView01"
/>
</FrameLayout>
package com.example;
import android.app.Activity;
import android.os.Bundle;
import android.view.Window;
public class CameraTest extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
}
}
package com.example;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.hardware.Camera;
import android.view.SurfaceView;
import android.view.SurfaceHolder;
import android.util.AttributeSet;
public class CameraView extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder holder;
private Camera camera;
private Bitmap bitmap;
private int[] rgb;
private int width, height;
/**
* プレビューコールバック
* prepareSavePreviewImageコールバックで登録され、プレビュー画像を取得する
*/
private final Camera.PreviewCallback _previewCallback =
new Camera.PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera camera) {
decodeYUV420SP(rgb, data, width, height);
bitmap.setPixels(rgb, 0, width, 0, 0, width, height);
// 描画
Canvas canv = holder.lockCanvas();
canv.drawBitmap(bitmap, 0, 0, null);
holder.unlockCanvasAndPost(canv);
}
};
// コンストラクタ
public CameraView(Context context) {
super(context);
this.initialize();
}
// コンストラクタ
public CameraView(Context context, AttributeSet attrs) {
super(context, attrs);
this.initialize();
}
// 初期化処理
private void initialize() {
// サーフェイスホルダーの生成
holder=getHolder();
holder.addCallback(this);
// サーフェイスホルダーのタイプを設定
holder.setType(SurfaceHolder.SURFACE_TYPE_NORMAL);
// 画像を読み込んでおく
}
// サーフェイス生成イベントの処理
public void surfaceCreated(SurfaceHolder holder) {
// カメラの初期化
try {
camera=Camera.open();
camera.setPreviewCallback(_previewCallback);
} catch (Exception e) {
}
}
// サーフェイス変更イベントの処理
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// 描画データの準備
width = w;
height = h;
bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
rgb = new int[w * h];
// カメラのプレビュー開始
Camera.Parameters parameters = camera.getParameters();
parameters.setPreviewSize(w, h);
camera.setParameters(parameters);
camera.startPreview();
}
//サーフェイス解放イベントの処理
public void surfaceDestroyed(SurfaceHolder holder) {
// カメラのプレビュー停止
camera.stopPreview();
camera.setPreviewCallback(null);
camera.release();
camera = null;
}
// YUV420 to BMP
static public void decodeYUV420SP(int[] rgb, byte[] yuv420sp, int width, int height) {
final int frameSize = width * height;
for (int j = 0, yp = 0; j < height; j++) {
int uvp = frameSize + (j >> 1) * width, u = 0, v = 0;
for (int i = 0; i < width; i++, yp++) {
int y = (0xff & ((int) yuv420sp[yp])) - 16;
if (y < 0) y = 0;
if ((i & 1) == 0) {
v = (0xff & yuv420sp[uvp++]) - 128;
u = (0xff & yuv420sp[uvp++]) - 128;
}
int y1192 = 1192 * y;
int r = (y1192 + 1634 * v);
int g = (y1192 - 833 * v - 400 * u);
int b = (y1192 + 2066 * u);
if (r < 0) r = 0; else if (r > 262143) r = 262143;
if (g < 0) g = 0; else if (g > 262143) g = 262143;
if (b < 0) b = 0; else if (b > 262143) b = 262143;
rgb[yp] = 0xff000000 | ((r << 6) & 0xff0000) | ((g >> 2) & 0xff00) | ((b >> 10) & 0xff);
}
}
}
}
| 名前 | Android_1_6 |
| ターゲット | Google APIs - API Level 4 |
| SD Card | 32MiB |
| Skin | Default(HVGA) |
| ハードウェア | (変更なし) |