ラベル 日本語 の投稿を表示しています。 すべての投稿を表示
ラベル 日本語 の投稿を表示しています。 すべての投稿を表示

2011年11月18日金曜日

iOS5で「gloss effect」を無効にする方法

iOS5になってアイコンの「gloss effect」が消せなくなったなっと思ったら、
他のアプリのアイコンは光沢が入ってない。

調べてみたら、iOS5からオプションが増えたらしい。


これで「gloss effect」が消える。


2011年11月14日月曜日

【お前の体重を見ろ!】バージョン2のアイコン

久しぶりのブログだな。
今日は【お前の体重を見ろ!】をバージョンアップしようと思ってアイコンを作ってみた。
今回はiPhoneとAndroid両方対応するつもりで、
アンドロイドっぽくないアイコンを考えて、俺が唯一に作れるクマを選んでデブにしてみた。
バージョン1とキャラクターが違うけど、まぁ。。いい。

これが頑張って作った太ったクマ!
俺ちょっとデザインのうでが上がったんじゃない?
ちなみに2年前の俺はこんなデザインをしていた。
おお!発展してる。

2011年2月27日日曜日

Mac OS X + Android + OpenCV2.2

参照:Android - OpenCV Wiki
Ubuntu 10.10 + Android + OpenCVの環境をセットアップ(hironemu's blog)

この前「hironemu」さんのブログを参照して自分の環境でAndroid+OpenCV2.2をセットアップしてみて簡単なエッジ効果を試してみたのを今日まとめてみた。

1. 事前に確認するUtility

「swig」、「swig-java」、「apache-ant」、「cmake」
自分の環境で入ってなかったらインストールしておく。
僕はMacPortsからインストールしました。
$ sudo port install swig
$ sudo port install swig-java
$ sudo port install cmake
「swig」と「swig-java」のactiveバージョンが合わないとエラーになるので、
activeバージョンを合わせ

2. NDK

http://developer.android.comで落とした「ndk r4」ではC++の問題で動かないらしい。
(r5はC++サポートしているのでいけるかなと思ったら、ビルド方法が面倒でやめた。)

「http://www.crystax.net/android/ndk-r4.php」サイトで
C++サポートするようにカスタマイズされた Android NDK r4 を落とす。

ndkが「$HOME/android-ndk-r4-crystax」じゃないとダメらしい。
気に入らないが $HOMEにリンクを作る。

3. OpenCV2.2

OpenCVソース取得。
参照サイトにはSVNから落とすように書いてあるが、ビルドで失敗する可能性があるので、
2.2の安定バージョンのソースを落とした。「http://sourceforge.net/projects/opencvlibrary/files/opencv-unix/2.2/」

落としたのを好きな場所に解凍してビルドする。

OpenCV Wikiのビルド手順
$ cd opencv/android
$ mkdir build
$ cd build
$ cmake ..
$ make

4. android-jni

Android NDKで使用する「android-opencv」を生成する。
$ cd opencv/android/android-jni
$ make
実行後、生成された「local.env.mk」ファイルの
「ANDROID_NDK_ROOT」項目を自分の環境に合わせて変更して、もう一回「make」(hironemu's blog参照)

「opencv/android/android-jni/libs」に
「armeabi/libandroid-opencv.so」、「armeabi-v7a/libandroid-opencv.so」ファイルができたら成功。



5. エッジ効果を試す。

エッジ効果をテストしたアプリのスクリーンショットはこちら。
元の画像
エッジ効果した画像
問題なく動くが、やはり実機でしか動かなかった。

OpenCVアプリを作るときは
OpenCV Wikiに書いてあるように「project_create.sh」を実行するか
自分で作るなら、NDKの設定で「Android.mk」にOpenCVのライブラリとヘッダのパスを追加する。
#Android.mk
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := OpenCVUtil
LOCAL_SRC_FILES := babukuma_opencv_util.c
LOCAL_LDLIBS    := -lm -llog

#define OPENCV_INCLUDES and OPENCV_LIBS
PATH_TO_OPENCV_ANDROID_BUILD := ~/dev/OpenCV-2.2.0/android/build
include $(PATH_TO_OPENCV_ANDROID_BUILD)/android-opencv.mk

LOCAL_LDLIBS += $(OPENCV_LIBS)
    
LOCAL_C_INCLUDES +=  $(OPENCV_INCLUDES) 

include $(BUILD_SHARED_LIBRARY)
これなら問題なく「ndk-build」でビルドされる。

以下は作ったソース。。
/**
 * OpenCVUtil.java
 */
package com.babukuma.android.demo.opencv.jni;

/**
 * @author babukuma
 * 
 */
public final class OpenCVUtil {
 static {
  System.loadLibrary("OpenCVUtil");
 }

 /**
  * エッジ効果。
  * 
  * @param picData
  *            RGBのピクセルデータ
  * @param width
  *            画像のWidth
  * @param height
  *            画像のHeight
  */
 public static native void edge(int[] picData, int width, int height);
}
/**
 * EdgeActivity.java
 */
package com.babukuma.android.demo.opencv.activity;

import static com.babukuma.android.demo.opencv.Main.LOG_TAG;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;

import com.babukuma.android.demo.opencv.R;
import com.babukuma.android.demo.opencv.jni.OpenCVUtil;

/**
 * エッジ効果テスト用Activity
 * 
 * @author babukuma
 */
public class EdgeActivity extends Activity {
 private ImageView picView;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  Log.d(LOG_TAG, "EdgeActivity#onCreate");

  setContentView(R.layout.edge);

  picView = (ImageView) findViewById(R.id.picView);
  picView.setOnClickListener(new OnClickListener() {

   public void onClick(View v) {
    Log.d(LOG_TAG, "picView#1onClick");
    BitmapDrawable db = (BitmapDrawable) picView.getDrawable();
    Bitmap bitmap = db.getBitmap();
    // Bitmap.Config.ARGB_8888
    Bitmap copyBitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
    int width = copyBitmap.getWidth();
    int height = copyBitmap.getHeight();
    int[] pixels = new int[width * height];
    copyBitmap.getPixels(pixels, 0, width, 0, 0, width, height);

    Log.d(LOG_TAG, "OpenCVUtil#edge");
    OpenCVUtil.edge(pixels, width, height);

    Log.d(LOG_TAG, "finish OpenCVUtil#edge");
    copyBitmap.setPixels(pixels, 0, width, 0, 0, width, height);

    picView.setImageBitmap(copyBitmap);
   }
  });
 }
}
/*
 * babukuma_opencv_util.h
 */
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_babukuma_android_demo_opencv_jni_OpenCVUtil */

#ifndef _Included_com_babukuma_android_demo_opencv_jni_OpenCVUtil
#define _Included_com_babukuma_android_demo_opencv_jni_OpenCVUtil
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_babukuma_android_demo_opencv_jni_OpenCVUtil
 * Method:    edge
 * Signature: ([III)V
 */
JNIEXPORT void JNICALL Java_com_babukuma_android_demo_opencv_jni_OpenCVUtil_edge
  (JNIEnv *, jclass, jintArray, jint, jint);

#ifdef __cplusplus
}
#endif
#endif
/*
 * babukuma_opencv_util.c
 */
#include <stdio.h>

// JNI
#include<jni.h>

// Android
#include <android/log.h>

// OpenCV
#include <opencv/cv.h>

#include "babukuma_opencv_util.h"

// Android LOG
#define  LOG_TAG    "OpenCVDemo"
#define  LOGD(...)  __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define  LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)

// 関数定義
IplImage* pixels2IplImage(int* pixels, int width, int height);
void iplImage2Pixcels(int *pixcels, IplImage *srcImage);


/*
 * エッジ効果。
 * 「picData」データは必ず「ARGB」
 *
 * Class:     com_babukuma_android_demo_opencv_jni_OpenCVUtil
 * Method:    edge
 * Signature: ([III)V
 */
JNIEXPORT void JNICALL Java_com_babukuma_android_demo_opencv_jni_OpenCVUtil_edge
  (JNIEnv *env, jclass class, jintArray picData, jint width, jint height)
{
 LOGD("call Java_com_babukuma_android_demo_opencv_jni_OpenCVUtil_edge");

 jboolean isCopy;

 //Colorの配列を取り出す(配列のポインタを取得)
 jint* picDataPtr = (*env)->GetIntArrayElements(env, picData, &isCopy);

 //Color(int) の配列から、IplImageを作る
 LOGD("call pixels2IplImage");
 IplImage *srcImage = pixels2IplImage(picDataPtr, width, height);

 //画像の作成完了。
 LOGD("CV_BGR2GRAY");
 IplImage *wordImage=cvCreateImage(cvGetSize(srcImage),IPL_DEPTH_8U,1);
 cvCvtColor(srcImage, wordImage, CV_BGR2GRAY);
 LOGD("cvReleaseImage srcImage");
 cvReleaseImage(&srcImage);
 srcImage = NULL;

 // Detect edge
 LOGD("Detect edge");
 IplImage *wordImage2 = cvCreateImage(cvGetSize(wordImage), IPL_DEPTH_8U, 1);
 cvCanny(wordImage, wordImage2, 64, 128, 3);
 cvReleaseImage(&wordImage);
 LOGD("cvReleaseImage wordImage");
 cvReleaseImage(&wordImage);
 wordImage = NULL;


 // Convert black and whilte to 24bit image then convert to UIImage to show
 IplImage *edgedImage = cvCreateImage(cvGetSize(wordImage2), IPL_DEPTH_8U, 3);
 int y, x;
 for(y=0; y<wordImage2->height; y++) {
  for(x=0; x<wordImage2->width; x++) {
   char *p = edgedImage->imageData + y * edgedImage->widthStep + x * 3;
   *p = *(p+1) = *(p+2) = wordImage2->imageData[y * wordImage2->widthStep + x];
  }
 }
 LOGD("cvReleaseImage wordImage2");
 cvReleaseImage(&wordImage2);
 wordImage2 = NULL;

 //IplImageの値を、int配列に戻す
 LOGD("call iplImage2Pixcels");
 iplImage2Pixcels(picDataPtr, edgedImage);

 LOGD("cvReleaseImage edgedImage");
 cvReleaseImage(&edgedImage);
 edgedImage = NULL;

 (*env)->ReleaseIntArrayElements(env, picData, picDataPtr, 0);
}

// jint配列からIplImageを作成
// alphaは捨てる。
IplImage* pixels2IplImage(int *pixels, int width, int height) {
 int x, y, index;

 IplImage *img = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 3);
 unsigned char* base = (unsigned char*) (img->imageData);
 unsigned char* ptr;

 for (y = 0; y < height; y++) {
  ptr = base + y * img->widthStep;
  for (x = 0; x < width; x++) {
   index = x + y * width;
   // B
   ptr[3 * x] = pixels[index] & 0xFF;
   // G
   ptr[3 * x + 1] = pixels[index] >> 8 & 0xFF;
   // R
   ptr[3 * x + 2] = pixels[index] >> 16 & 0xFF;
   // A
   // pixels[index] >> 24 & 0xFF;
  }
 }
 return img;
}

// IplImageからjint配列作成
void iplImage2Pixcels(int *pixcels, IplImage *srcImage)
{
    int x, y;
    int w,h;
    w=srcImage->width;
    h=srcImage->height;

    unsigned char* base = (unsigned char*) (srcImage->imageData);
    unsigned char* ptr;
    for (y = 0; y < h; y++)
    {
        ptr = base + y * srcImage->widthStep;
        for (x = 0; x < w; x++)
        {
            pixcels[x + y * w] =
              (0xFF000000) | // A
              (ptr[3 * x + 2] << 16) | // R
              (ptr[3 * x + 1] << 8) | // G
              (ptr[3 * x]); // B
        }
     }
}

彼女もエッジ効果させてみました。
怖い彼女になった。

2011年2月15日火曜日

OpenCV2.2をインストールした。

From Evernote:

OpenCV2.2をインストールした。

MacPortsからOpenCV2.2をインストール

MacPortsのport tree更新
$ sudo port selfupdate

OpenCVインストール
$ sudo port install opencv

OpenCVをPython2.6にバインディング(python使わないなら要らない)
$ sudo port -v install opencv +python26

インストール結果を確認すると
「/opt/local/bin」にユーティリティ
(opencv_createsamples,  opencv_haartraining, opencv_performance, opencv_traincascade)
「/opt/local/lib」にライブラリ
「/opt/local/include/opencv」にヘッダ
がインストールされている。


OpenCVの確認の為、あるサンプルをテストしてみる。
参照したサンプルは

この本のソースをOpenCV2.2用に修正したもの。


Command Line Tool プロジェクトを作成する。



有効なアーキテクチャを「i386」「x86_64」にする。



ヘッダ検索パスに「/opt/local/include」を追加

OpenCVグループを作って、「/opt/local/lib」のOpenCVライブラリを追加


「main.c」
#include <stdio.h>
#include <opencv/cv.h>
#include <opencv/highgui.h>

int main (intargcconstchar * argv[]) {
char* szWndName="カメラ映像";
CvCapture* capture;
IplImage* img;
capture = cvCaptureFromCAM(0); // カメラ映像取得
if (capture==NULL) {
fprintf(stderr, "カメラが見つかりません。\n");
return -1;
}
cvNamedWindow(szWndName, CV_WINDOW_AUTOSIZE);
while (1) {
img=cvQueryFrame(capture); // フレーム取得
cvShowImage(szWndName, img); // フレーム表示
if(cvWaitKey(1)>=0) { // 何かキーを押したら終了
break;
}
}
cvDestroyWindow(szWndName);
cvReleaseCapture(&capture);
    return0;
}


実行するとMacのカメラで自分の顔が映る。




2011年2月14日月曜日

Linuxにffmpegをインストール

From Evernote:

Linuxにffmpegをインストール

■ Linux(CentOS5.5)にffmpegをインストール。


LAME 3.98.4 http://lame.sourceforge.net/ MP3への変換ライブラリ
FAAC / FAAD2 1.28 / 2.7 http://www.audiocoding.com/ MPEG2-AAC, MPEG4-AAC 音声圧縮ライブラリ
opencore-amr 0.1.2 http://opencore-amr.sourceforge.net/ 3G携帯用音声コーデック
ffmpeg 0.6.1 http://www.ffmpeg.org/

ffmpeg 0.6.1
では「liba52」が要らなくなった。(バージョン0.5から無くなったらしい)
理由:native ac3 encoderを持ってるらしい。


1. LAMEインストール
# tar xzvf lame-3.98.4.tar.gz
# cd lame-3.98.4
# ./configure
# make
# make instll

2. FAACインストール
「configure」がない為、「bootstrap」で生成する。
# tar xzvf faac-1.28.tar.gz
# cd faac-1.28
# ./bootstrap
# ./configure
# make
# make instll

3. FAAD2インストール
# tar xzvf faad2-2.7.tar.gz
# cd faad2-2.7
# ./configure
# make
# make instll

4. opencore-amrインストール
# tar xzvf opencore-amr-0.1.2.tar.gz
# cd opencore-amr-0.1.2
# ./configure
# make
# make instll

5. ffmpegインストール
# cd ffmpeg-0.6.1
# ./configure --enable-libmp3lame --enable-libfaac --enable-libfaad --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-gpl --enable-nonfree --enable-version3
# make
# make install


FAACインストール時発生した問題
# ./bootstrap
./bootstrap: line 3: aclocal: command not found
./bootstrap: line 4: autoheader: command not found
./bootstrap: line 8: libtoolize: command not found
./bootstrap: line 10: automake: command not found
./bootstrap: line 11: autoconf: command not found

この問題は 「automake」、「libtool」がインストールされていない為発生する。
「automake」、「libtool」をインストールして解決
# yum install automake
# yum install libtool


opencore-amrインストール時発生した問題

configureでエラーが発生
configure: error: C++ compiler cannot create executables
C++コンパイラが入ってないらしい。
「gcc-c++」をインストールして解決
# yum install gcc-c++


ffmpeg実行時
「ffmpeg: error while loading shared libraries: libfaac.so.0: cannot open shared object file: No such file or directory」エラーが発生すると。
ライブラリを登録する。

# vi /etc/ld.so.conf
行末に「/usr/local/lib」を追加
# /sbin/ldconfig


Unknown encoder 'png'
エラーが発生する。

「libpng-dev」をインストールして解決
# yum install libpng-dev

ffmpegの再インストールが必要


2010年12月16日木曜日

[SVN] an unversioned directory of the same name already exists エラー

svnで
an unversioned directory of the same name already exists
エラーが発生して更新とコミットするたびに警告がでって面倒くさくなった。

それで、対象のディレクトリを消しって
$ svn update --force {rootディレクトリpath}
で強制更新したら直った。。

2010年12月9日木曜日

Android SDK2.3で「Multiple substitutions specified in non-positional」エラーが発生するようになった。

Android SDK2.3をインストルしたら
既存プロジェクト「strings.xml」で「Multiple substitutions specified in non-positional」エラーが発生するようになった。

を調べてみたら、
気になったのが「Formatting strings」の部分。。

僕が作った「strings.xml」の中で
「〜〜〜60~70%です。〜〜〜」という文言がある。

原因は「%」だった。
「%」はどう書けばいいのかな?
「%%」、「\%」はダメだった。。
わからん。。(´Д`;)

とりあえず、この「%」を全角「%」に書き換えたら直った。(^_^;)

2010年12月8日水曜日

Node ManagerでBAD_CERTIFICATEが発生する

サーバのホスト名を変更したらNode Managerで
「BEA-090482 BAD_CERTIFICATE」エラーが発生するようになった。

調べたなんとか対応はした。(根本的な解決ではないと思うけど)

WebLogin起動スクリプトに

-Dweblogic.security.SSL.ignoreHostnameVerification=true

を追加して無視するように対応

2010年11月28日日曜日

ギャラクシータブエミュレータをインストルしてみた。

ギャラクシータブエミュレータをインストルしてみた。

参照サイトは「http://innovator.samsungmobile.com/galaxyTab.do」

「Android SDK and AVD Manager」を開いて、


「Available Packages」タブに
「http://innovator.samsungmobile.com/android/repository/srepository.xml」サイトを追加。


追加後 「GALAXY Tab Addon」をインストル。




ギャラクシータブエミュレータを追加




実行してみると
僕のPCでもはエミュレータ画面が切れてしまいますね。
iPadエミュレータみたいに50%縮小して見れるならいいと思いますが。。

2010年9月3日金曜日

[Android] お前の体重を見ろ! v1.0

「お前の体重を見ろ!」の1.0バージョンをリリースした。
0.9バージョンはこちら

「お前の体重を見ろ!」は、体重管理アプリケーションです。毎日体重を記録してグラフに表示したり、BMI・BMR計算をすることができます。

Support languages
- English
- 日本語
- 한국어

v1.0
1. 共有機能追加
- メールやツイッタークライアントと連携
(勇気を持ってツイッターに公開可能!!)
2. CSVインポート機能追加
3. アイコン変更

次のバージョンでは要望もあったしロック機能を追加しようかと思ってる。






2010年9月1日水曜日

[Android] ログレベル設定方法

Androidでログのレベル設定方法

エミュレータと実機のログレベルがどうやらデフォルト「INFO」らしい。

確認してみると

Log.isLoggable(TAG, Log.VERBOSE) == false
Log.isLoggable(TAG, Log.DEBUG) == false
Log.isLoggable(TAG, Log.INFO) == true
Log.isLoggable(TAG, Log.WARN) == true
Log.isLoggable(TAG, Log.ERROR) == true

になる。

だから以下のコードは出力されるが、

Log.d(TAG, msg); // ログレベルとは関係なく出力はされる。



以下のコードだと出力されない。

if(Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, msg); // ログレベルが「DEBUG」以上の場合、出力はされる。
}


特定ログタグのログレベル設定方法は

$ ./adb shell setprop log.tag.<your_log_tag> <level>



例えば、TAGが「BABUKUMA」の場合は

$ ./adb shell stop
$ ./adb shell setprop log.tag.BABUKUMA DEBUG
$ ./adb shell start


確認してみると

Log.isLoggable(TAG, Log.VERBOSE) == false
Log.isLoggable(TAG, Log.DEBUG) == true
Log.isLoggable(TAG, Log.INFO) == true
Log.isLoggable(TAG, Log.WARN) == true
Log.isLoggable(TAG, Log.ERROR) == true

2010年8月30日月曜日

[iPhone] UIWebViewのリンクからSafariを開く方法

UIWebViewのリンクからSafariを開く方法

参照:

UIWebViewDelegateを利用する。

Interface BuilderでUIWebViewのdelegateを設定する。


以下のコードを追加
// リンクをクリック時、Safariを起動する為の処理
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if (navigationType == UIWebViewNavigationTypeLinkClicked) {
NSLog(@"URL = %@", [[request URL] absoluteString]);
[[UIApplication sharedApplication] openURL:[request URL]];
return NO;
}

return YES;
}


以下はソース全体
WebViewTestAppDelegate.h
//
// WebViewTestAppDelegate.h
// WebViewTest
//
// Created by BABUKUMA on 10/08/30.
// Copyright babukuma.com 2010. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface WebViewTestAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
IBOutlet UIWebView *webView;
}

@property (nonatomic, retain) IBOutlet UIWindow *window;

@end


WebViewTestAppDelegate.m
//
// WebViewTestAppDelegate.m
// WebViewTest
//
// Created by BABUKUMA on 10/08/30.
// Copyright babukuma.com 2010. All rights reserved.
//

#import "WebViewTestAppDelegate.h"

@implementation WebViewTestAppDelegate

@synthesize window;


#pragma mark -
#pragma mark Application lifecycle

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

// Override point for customization after application launch.

[window makeKeyAndVisible];

// WebViewの初期表示
NSLog(@"BABUKUMA : WebViewの初期表示");
NSURL *url = [NSURL URLWithString:@"http://babukuma.com"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[webView loadRequest: request];

return YES;
}

// リンクをクリック時、Safariを起動する為の処理
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if (navigationType == UIWebViewNavigationTypeLinkClicked) {
NSLog(@"URL = %@", [[request URL] absoluteString]);
[[UIApplication sharedApplication] openURL:[request URL]];
return NO;
}

return YES;
}


- (void)applicationWillResignActive:(UIApplication *)application {
}


- (void)applicationDidEnterBackground:(UIApplication *)application {
}


- (void)applicationWillEnterForeground:(UIApplication *)application {
}


- (void)applicationDidBecomeActive:(UIApplication *)application {
}


- (void)applicationWillTerminate:(UIApplication *)application {
}


#pragma mark -
#pragma mark Memory management

- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
}


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


@end

2010年8月12日木曜日

[Android] INSTALL_PARSE_FAILED_NO_CERTIFICATES

アンドロイドアプリで開発したアプリを端末にインストルするとき
INSTALL_PARSE_FAILED_NO_CERTIFICATES」エラーが出てインストルできなくなった。

開発モードアプリケーションへの署名問題らしいけど、
アンインストールして再インストールしても失敗して悩んだ。

原因まではまだわからないが、
パケージ名を変えたらインストルできるようになった。

原因はなんだろ。。。
開発途中で何回かアプリ名を変えたりパケージ名を変えたりしたのが原因かな?

2010年8月5日木曜日

[Android] お前の体重を見ろ! v0.9

今日「お前の体重を見ろ!」の0.9バージョンをアップした。
「お前の体重を見ろ!」は簡単に体重管理できるアンドロイド用の無料アプリだ。
無料だから気楽に使って欲しい!

今回のバージョンアップ内容は
v0.9
1. 体脂肪グラフ追加
2. BMIとBMRの説明追加
3. バグ対応
- 体重グラフで(kg)しか表示されないバグ









次はCSVインポート機能等を追加する予定。

2010年7月7日水曜日

Scala WebApplication + Mavenプロジェクト構成

Scala WebApplicationのMavenプロジェクト構成


1. Webアプリケーションプロジェクト作成

mvn archetype:create -DgroupId=com.babukuma -DartifactId=Scala.Web -DarchetypeArtifactId=maven-archetype-webapp


2. ディレクトリ構成
 - javaソース
   ・src/main/java
   ・src/test/java (テスト用)
 - scalaソース
   ・src/main/scala
   ・src/test/scala (テスト用)
 - resources
   ・src/main/resources
   ・src/test/resources (テスト用)
 - Webアプリケーションファイル
   ・src/main/webapp
   ・src/test/webapp (テスト用)


3. pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.babukuma</groupId>
<artifactId>Scala.Web</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>Scala.Web Maven Webapp</name>
<url>http://maven.apache.org</url>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<jdkVersion>1.6</jdkVersion>
<junitVersion>4.8.1</junitVersion>
<scalaVersion>2.8.0.RC7</scalaVersion>
<scalaPluginVersion>2.12</scalaPluginVersion>
</properties>

<repositories>
<repository>
<id>scala-tools.org</id>
<name>Scala-tools Maven2 Repository</name>
<url>http://scala-tools.org/repo-releases</url>
</repository>
</repositories>

<pluginRepositories>
<pluginRepository>
<id>scala-tools.org</id>
<name>Scala-tools Maven2 Repository</name>
<url>http://scala-tools.org/repo-releases</url>
</pluginRepository>
</pluginRepositories>

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junitVersion}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-servlet_2.5_spec</artifactId>
<version>1.1.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
<version>${scalaVersion}</version>
</dependency>
</dependencies>
<build>
<finalName>Scala.Web</finalName>

<!-- To define the plugin version in your parent POM -->
<pluginManagement>
<plugins>
<plugin>
<groupId>org.scala-tools</groupId>
<artifactId>maven-scala-plugin</artifactId>
<version>${scalaPluginVersion}</version>
</plugin>
</plugins>
</pluginManagement>

<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${jdkVersion}</source>
<target>${jdkVersion}</target>
</configuration>
</plugin>

<!-- To use the plugin goals in your POM or parent POM -->
<plugin>
<groupId>org.scala-tools</groupId>
<artifactId>maven-scala-plugin</artifactId>
<version>${scalaPluginVersion}</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
<configuration>
<jvmArgs>
<jvmArg>-Xms64m</jvmArg>
<jvmArg>-Xmx1024m</jvmArg>
</jvmArgs>
</configuration>
</plugin>
</plugins>
</build>

<!-- To use the report goals in your POM or parent POM -->
<reporting>
<plugins>
<plugin>
<groupId>org.scala-tools</groupId>
<artifactId>maven-scala-plugin</artifactId>
<version>${scalaPluginVersion}</version>
</plugin>
</plugins>
</reporting>
</project>



4. テスト用ソース(Servlet)
HelloScalaServlet.scala

package com.babukuma

import javax.servlet.http._

class HelloScalaServlet extends HttpServlet {
override def doGet(request : HttpServletRequest, response : HttpServletResponse) =
response.getWriter().print("Hello Scala")
}


5. web.xml

<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
<display-name>Scala Web Application</display-name>
<servlet>
<servlet-name>helloScala</servlet-name>
<servlet-class>com.babukuma.HelloScalaServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>helloScala</servlet-name>
<url-pattern>/helloScala</url-pattern>
</servlet-mapping>
</web-app>


6. 動作確認

2010年7月6日火曜日

Scala + Maven2 プロジェクト構成

参照URL
- http://scala-tools.org/mvnsites/maven-scala-plugin/
- http://www.scala-lang.org/node/345

pom.xml ファイル

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.babukuma</groupId>
<artifactId>scala.test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>scala.test</name>
<url>http://maven.apache.org</url>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<junitVersion>4.8.1</junitVersion>
<scalaVersion>2.8.0.RC7</scalaVersion>
<scalaPluginVersion>2.12</scalaPluginVersion>
</properties>

<repositories>
<repository>
<id>scala-tools.org</id>
<name>Scala-tools Maven2 Repository</name>
<url>http://scala-tools.org/repo-releases</url>
</repository>
</repositories>

<pluginRepositories>
<pluginRepository>
<id>scala-tools.org</id>
<name>Scala-tools Maven2 Repository</name>
<url>http://scala-tools.org/repo-releases</url>
</pluginRepository>
</pluginRepositories>

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junitVersion}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
<version>${scalaVersion}</version>
</dependency>
</dependencies>

<build>
<!--
<sourceDirectory>src/main/scala</sourceDirectory>
<testSourceDirectory>src/test/scala</testSourceDirectory>
-->
<!-- To define the plugin version in your parent POM -->
<pluginManagement>
<plugins>
<plugin>
<groupId>org.scala-tools</groupId>
<artifactId>maven-scala-plugin</artifactId>
<version>${scalaPluginVersion}</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<!-- To use the plugin goals in your POM or parent POM -->
<plugin>
<groupId>org.scala-tools</groupId>
<artifactId>maven-scala-plugin</artifactId>
<version>${scalaPluginVersion}</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
<configuration>
<jvmArgs>
<jvmArg>-Xms64m</jvmArg>
<jvmArg>-Xmx1024m</jvmArg>
</jvmArgs>
</configuration>
</plugin>
</plugins>
</build>

<!-- To use the report goals in your POM or parent POM -->
<reporting>
<plugins>
<plugin>
<groupId>org.scala-tools</groupId>
<artifactId>maven-scala-plugin</artifactId>
<version>${scalaPluginVersion}</version>
</plugin>
</plugins>
</reporting>
</project>


フォルダ構成
- javaソース
・src/main/java
・src/test/java (テスト用)
- scalaソース
・src/main/scala
・src/test/scala (テスト用)
- resources
・src/main/resources
・src/test/resources (テスト用)



テストソース
HelloScala.scala

package com.babukuma.scala

object HelloScala {

def main(args: Array[String]): Unit = {
println("Hello Scala!")

val helloJava = new HelloJava
helloJava.printHelloJava()
}
}


HelloJava.java

package com.babukuma.scala;

public class HelloJava {
public void printHelloJava() {
System.out.println("Hello Java!");
}
}


コンパイルとパッケージング

$ mvn compile
$ mvn package


実行



$ mvn scala:run -DmainClass=com.babukuma.scala.HelloScala
Hello Scala!
Hello Java!

2010年5月18日火曜日

[SQLite] not implemented by SQLite JDBC driver

SQLiteをJavaで使う時、
「REAL」タイプをjava側のBigDecimalにマッピングするのはできないらしい。

「not implemented by SQLite JDBC driver」というエラーが発生する。

調べてみると、ResultSetの「getBigDecimal()」と「getBLOB()」も使えないようだ。

2010年4月10日土曜日

SQLiteとH2の性能比較

H2とSQLite3の性能比較が知りたくて調べてみたが
古い記事しかなかったので簡単に性能比較してみた。

SQLiteバージョン : 3.6.23
H2バージョン : 1.2.132

テスト言語はJava(プロジェクトがJavaベースなので)
SQLiteのJDBCドライバは「SQLiteJDBC」を使用した。

SQLiteJDBC : http://www.zentus.com/sqlitejdbc/

テスト環境1


- CPU : 2.53 GHz Intel Core 2 Duo
- Memory : 4GB
- OS : Mac OS X 10.6.3
区分SQLiteH2 EmbeddedH2 In-memory
Insert (100万件)0.5 秒0.9 秒0.9 秒
Select (100万件)0.002 秒0.015 秒0.07 秒
File size2,048 bytes14,336 bytes-


テスト環境2


- CPU : 2.53 GHz Intel Core 2 Duo
- Memory : 4GB
- OS : Mac OS X 10.6.3
区分SQLiteH2 EmbeddedH2 In-memory
Insert (100万件)0.5 秒1.3 秒1.5 秒
Select (100万件)0.004 秒0.09 秒0.095 秒
File size2,048 bytes14,336 bytes-


簡単なテストだが全板的にSQLiteの勝ち。
特に瀬能が低いマシンではもっとH2よりパフォーマンスがいいらしい。
でもH2は今まで「In-memory」方式が「組込み」より早いと思ったのが大間違いだったのがショックだ。


下はテストで使用したソース

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;

public class SqlitePerformance {
private static final int ROW_COUNT = 1000000;
private static final int MAX = 100;

/**
* SQLite3 Embedded
*
* @author babukuma
* @since 2010/04/09
* @param args
*/
public static void main(String[] args) throws Exception {
System.out.println("SQLite TEST [" + ROW_COUNT + "件]");
Class.forName("org.sqlite.JDBC");
Connection conn = DriverManager
.getConnection("jdbc:sqlite:babukuma.sqllite.db");

Statement stat = conn.createStatement();
stat.executeUpdate("drop table if exists babukuma;");
stat
.executeUpdate("create table babukuma (id integer primary key, value integer);");

conn.setAutoCommit(false);
System.out.print("Insert Test : ");
long startTime = System.currentTimeMillis();

PreparedStatement prep = conn
.prepareStatement("insert into babukuma values (?, ?);");

for (int i = 0; i < ROW_COUNT; i++) {
prep.setInt(1, i);
prep.setInt(2, i);
prep.addBatch();

if (i > 0 && (i % MAX) == 0 && i == ROW_COUNT - 1) {
prep.executeBatch();
prep.clearBatch();
}
}

conn.commit();

long endTime = System.currentTimeMillis();
System.out.println(((endTime - startTime) / 1000.) + "秒");

System.out.print("Select Test : ");
startTime = System.currentTimeMillis();
ResultSet rs = stat.executeQuery("select * from babukuma;");
while (rs.next()) {
rs.getInt("id");
rs.getInt("value");
// System.out.println("id = " + rs.getInt("id"));
// System.out.println("value = " + rs.getString("value"));
}
rs.close();
endTime = System.currentTimeMillis();
System.out.println(((endTime - startTime) / 1000.) + "秒");

conn.close();
}
}


import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;

import org.h2.jdbcx.JdbcConnectionPool;

public class H2Performance {
private static final int ROW_COUNT = 1000000;
private static final int MAX = 100;

/**
* H2 Embedded
*
* @author babukuma
* @since 2010/04/09
* @param args
*/
public static void main(String[] args) throws Exception {
System.out.println("H2 TEST [" + ROW_COUNT + "件]");
JdbcConnectionPool cp = JdbcConnectionPool.create(
"jdbc:h2:babukuma.h2", "", "");
Connection conn = cp.getConnection();

Statement stat = conn.createStatement();
stat.executeUpdate("drop table if exists babukuma;");
stat
.executeUpdate("create table babukuma (id int primary key, value int);");

conn.setAutoCommit(false);
System.out.print("Insert Test : ");
long startTime = System.currentTimeMillis();

PreparedStatement prep = conn
.prepareStatement("insert into babukuma values (?, ?);");

for (int i = 0; i < ROW_COUNT; i++) {
prep.setInt(1, i);
prep.setInt(2, i);
prep.addBatch();

if (i > 0 && (i % MAX) == 0 && i == ROW_COUNT - 1) {
prep.executeBatch();
prep.clearBatch();
}
}

conn.commit();

long endTime = System.currentTimeMillis();
System.out.println(((endTime - startTime) / 1000.) + "秒");

System.out.print("Select Test : ");
startTime = System.currentTimeMillis();
ResultSet rs = stat.executeQuery("select * from babukuma;");
while (rs.next()) {
rs.getInt("id");
rs.getInt("value");
// System.out.println("id = " + rs.getInt("id"));
// System.out.println("value = " + rs.getString("value"));
}
rs.close();
endTime = System.currentTimeMillis();
System.out.println(((endTime - startTime) / 1000.) + "秒");

conn.close();
}
}


import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;

import org.h2.jdbcx.JdbcConnectionPool;

public class H2InMemoryPerformance {
private static final int ROW_COUNT = 1000000;
private static final int MAX = 100;

/**
* H2 In memory
*
* @author babukuma
* @since 2010/04/09
* @param args
*/
public static void main(String[] args) throws Exception {
System.out.println("H2 In Memory TEST [" + ROW_COUNT + "件]");
JdbcConnectionPool cp = JdbcConnectionPool
.create("jdbc:h2:mem:", "", "");
Connection conn = cp.getConnection();

Statement stat = conn.createStatement();
stat.executeUpdate("drop table if exists babukuma;");
stat
.executeUpdate("create table babukuma (id int primary key, value int);");

conn.setAutoCommit(false);
System.out.print("Insert Test : ");
long startTime = System.currentTimeMillis();

PreparedStatement prep = conn
.prepareStatement("insert into babukuma values (?, ?);");

for (int i = 0; i < ROW_COUNT; i++) {
prep.setInt(1, i);
prep.setInt(2, i);
prep.addBatch();

if (i > 0 && (i % MAX) == 0 && i == ROW_COUNT - 1) {
prep.executeBatch();
prep.clearBatch();
}
}

conn.commit();

long endTime = System.currentTimeMillis();
System.out.println(((endTime - startTime) / 1000.) + "秒");

System.out.print("Select Test : ");
startTime = System.currentTimeMillis();
ResultSet rs = stat.executeQuery("select * from babukuma;");
while (rs.next()) {
rs.getInt("id");
rs.getInt("value");
// System.out.println("id = " + rs.getInt("id"));
// System.out.println("value = " + rs.getString("value"));
}
rs.close();
endTime = System.currentTimeMillis();
System.out.println(((endTime - startTime) / 1000.) + "秒");

conn.close();
}
}

2010年3月15日月曜日

[SWT] SWT on 64bit Mac OS X

Mac OS X 10.6.2 Snow Leopardで
SWTアプリケーションがちゃんと動かない現象があって色々調べてみたら
どうやらオプションが必要のようだ。

「-d64」オプションと「-XstartOnFirstThread」オプション

「-d64」オプションは明確に64bit VMを指定するために使う。

「-XstartOnFirstThread」オプションはMacでSWTアプリケーションが正常に動けるため必要のようだ。SWTに限ったオプションではないらしい。

二つのオプションを付けると。。
java -d64 -XstartOnFirstThread -jar babukuma_swt_test.jar

実際テストしてみると問題なく動作した。

参照してサイト
http://www.eclipse.org/swt/macosx
http://www.eclipse.org/swt/faq.php

2010年3月11日木曜日

[Android] 「Android NDK r3」を使ってみた。

今回リリースされた「Android NDK r3」を使ってみた。

環境:Mac OS X 10.6.2

android-ndk-r3-darwin-x86.zipを「http://developer.android.com/」からダウンロードして適当に展開する。
おれは「/Users/babukuma/dev/android-ndk-r3」にした。(以下$NDK)

1. Androidプロジェクト生成
テスト用のプロジェクトを生成する。

生成するとこの構成になるはず。

「jni」フォルダ作成


2.「Application.mk」ファイル作成。
プロジェクトディレクトリ下に「Application.mk」ファイルを作成。

今回はモジュール名を「jnitest」にした。
書き方は「$NDK/docs/APPLICATION-MK.TXT」参照

# Application.mk
APP_PROJECT_PATH := $(call my-dir)
APP_MODULES := jnitest


3. Nativeメソッド作成。
「Main.java」ファイルに作成した。

package com.babukuma.android.test.jni;

import android.app.Activity;
import android.os.Bundle;

public class Main extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}

public native String helloJNI();

public native int add(int a, int b);
}


4. ヘッダファイル生成
プロジェクトディレクトリで「javah」コマンドでヘッダファイル「jni/jnitest.h」を生成。

生成された「jnitest.h」ファイル

/* DO NOT EDIT THIS FILE - it is machine generated */
#include<jni.h>
/* Header for class com_babukuma_android_test_jni_Main */

#ifndef _Included_com_babukuma_android_test_jni_Main
#define _Included_com_babukuma_android_test_jni_Main
#ifdef __cplusplus
extern"C" {
#endif
/*
* Class: com_babukuma_android_test_jni_Main
* Method: helloJNI
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_babukuma_android_test_jni_Main_helloJNI
(JNIEnv *, jobject);

/*
* Class: com_babukuma_android_test_jni_Main
* Method: add
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_com_babukuma_android_test_jni_Main_add
(JNIEnv *, jobject, jint, jint);

#ifdef __cplusplus
}
#endif
#endif


5. Cソース作成。
「jni」ディレクトリで「jnitest.c」を作成する。

作った「jnitest.c」ファイル

#include<jni.h>
#include"jnitest.h"

JNIEXPORT jstring JNICALL Java_com_babukuma_android_test_jni_Main_helloJNI(
JNIEnv *env, jobject thisObj) {
jstring result = (*env)->NewStringUTF(env, "Hello JNI !");
return result;
}

JNIEXPORT jint JNICALL Java_com_babukuma_android_test_jni_Main_add(JNIEnv *env,
jobject thisObj, jint a, jint b) {
jint result = a + b;
return result;
}


6. 「Android.mk」ファイルを作成する。
jniディレクトリに「Android.mk」ファイルを作成する。
書き方は「$NDK/docs/ANDROID-MK.TXT」参照

作った「Android.mk」ファイル

# Android.mkLOCAL_PATH := $(call my-dir)

include$(CLEAR_VARS)

LOCAL_MODULE := jnitest
LOCAL_SRC_FILES := jnitest.c

include$(BUILD_SHARED_LIBRARY)


7. Cソースビルド
ビルドをするにはプロジェクトPATHが「$NDK/apps/<プロジェクト>」になる必要があるのでリンクを作った。

$NDKディレクトリで「make APP=jnitest」でビルド
ここで「jnitest」は「$NDK/apps/」下のプロジェクトフォルダ名になる。

Eclipseをリロードしてみると「libs/armeabi/libjnitest.so」ファイルが生成されたのがわかる。


8. Javaソースを修正して実行してみる。
修正後の「Main.java」ファイル

package com.babukuma.android.test.jni;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class Main extends Activity {
static {
System.loadLibrary("jnitest");
}

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

// call helloJNI()
TextView result1 = (TextView) findViewById(R.id.text_result_1);
result1.setText(helloJNI());

// call add(1, 2)
TextView result2 = (TextView) findViewById(R.id.text_result_2);
result2.setText("1 + 2 = " + add(1, 2));
}

public native String helloJNI();

public native int add(int a, int b);
}


修正後実行してみるとNativeメソッドが問題なく呼ばれた。