2012年5月27日日曜日

Xcode3でMac OS X Lionにnode.jsをインストールすると失敗する

OS: Lion 10.7.4
Xcode: 3 -> 4

purpose: Install node.js using ports

App StoreからXcodeをインストールすると/Applicationsフォルダにインストールされる。
その前にまずXcode3をアンインストールする必要がある。
以下のサイトが参考になる。

Xcode4に更新してからでnode.jsをport経由でインストールしたくてもエラーする

警告の内容の一部
----------------------
Warning: xcodebuild exists but failed to execute
Warning: Xcode does not appear to be installed; most ports will likely fail to build.
Warning: The Command Line Tools for Xcode don't appear to be installed; most ports will likely fail to build.
Warning: See http://guide.macports.org/chunked/installing.xcode.html for more information.

----------------------

以下のサイトを参考にツールをインストールすれば無事にnode.jsをインストールできる。


$sudo port install nodejs
$node -v
v0.6.18

安定版がインストールされました。
エンジョイ!

2012年4月16日月曜日

AndroidでiPhone風のスイッチを作る

普通のAndroidのToggleButtonを使ってもつまらないですね!

デザインならiPhoneが今のところ一番だと考えます。

なるべく近づけてみましょう。

論より証拠ということで以下のコードを参考にしてみてください。
←普通のToggleButton

←これがカスタマイズした後のToggleButton

手順は以下の通りです。
1、以下のコードをres/drawable/customtoggle.xmlとでもして保存して下さい。
2、backgroundプロパティに指定して下さい。
3、on textとoff textにそれぞれ半角スペースを指定して下さい。


<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:state_checked="false">
        <layer-list>
            <item>
                <shape>
                    <size android:height="27dp" android:width="60dp" />

                    <gradient android:angle="270" android:centerColor="#c0c0c0" android:centerX="0.5" android:centerY="0.5" android:endColor="#c0c0c0" android:gradientRadius="10" android:startColor="#c0c0c0" android:type="linear" />

                    <corners android:radius="8dp" />

                    <solid android:color="#c0c0c0" />

                    <stroke android:width="1dip" android:color="#808080" />
                </shape>
            </item>
            <item android:left="30dp">
                <shape>
                    <size android:height="27dp" android:width="30dp" />
                    <corners android:radius="8dp" />
<gradient android:angle="270" android:centerColor="#B0C4DE" android:centerX="0.5" android:centerY="0.5" android:endColor="#778899" android:gradientRadius="10" android:startColor="#ADD8E6" android:type="linear" />


                    <stroke android:width="1dip" android:color="#808080" />
                </shape>
            </item>
            <item android:left="-30dp">
                <bitmap android:src="@drawable/off" android:gravity="center" />
            </item>
        </layer-list>
    </item>
    <item android:state_checked="true">
        <layer-list>
            <item>
                <shape>
                    <size android:height="27dp" android:width="60dp" />

                    <corners android:radius="8dp" />

                    <solid android:color="#ffffff" />

                    <stroke android:width="1dip" android:color="#808080" />
                </shape>
            </item>
            <item android:right="30dp">
                <shape>
                    <size android:height="27dp" android:width="30dp" />
<gradient android:angle="270" android:centerColor="#B0C4DE" android:centerX="0.5" android:centerY="0.5" android:endColor="#778899" android:gradientRadius="10" android:startColor="#ADD8E6" android:type="linear" />
                    <corners android:radius="8dp" />

                    <stroke android:width="1dip" android:color="#808080" />
                </shape>
            </item>
            <item android:right="-29dp">
                <bitmap android:src="@drawable/on" android:gravity="center" />
            </item>
        </layer-list>
    </item>

</selector>

2012年4月14日土曜日

Androidでアラームを作るための手順の例

ネットで「Android アラーム 開発」などとググるといろんな方が記事を書いています。

しかし、断片的なイメージが強かったのでまとめてみたいと思います。

■今回作成するアプリの概要
AlarmManagerを用いて、指定した時間後にアラーム通知画面が表示され、アラーム音を鳴らす

■手順
SampleActivity(アラーム設定画面とします)

(任意)MyAlarmManager(設定されたアラームを管理する独自クラス)

MyAlarmService(サービスを起動してブロードキャストメッセージを送ります)

MyAlarmNotificationReceiver(メッセージを受信して通知画面を起動します)

AlarmNotificationActivity(通知画面です)

■条件
1、スリープ画面であってもアラーム画面を表示する

■実装
まず、マニフェストファイルで設定しないといけない項目があります。
以下のXMLをAndroidManifest.xmlのapplicationタグ内の適切なところに配置します。
intent-filterで独自のメッセージ「"MyAlarmAction"」を受信するようにしてます。
------------------------------------------------------------------------------------------------
 <receiver android:name="MyAlarmNotificationReceiver">
            <intent-filter>
                <action android:name="MyAlarmAction"/>
            </intent-filter>
</receiver>
<service android:name="MyAlarmService"></service>
<activity android:name="AlarmNotificationActivity"></activity>
------------------------------------------------------------------------------------------------

以下の2行をmanifesstタグ直下に配置します。
これは、スリープ状態を解除するために必要な権限です。
------------------------------------------------------------------------------------------------ 
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>
------------------------------------------------------------------------------------------------

【SampleActivity.java】
アラームをセットするために必要なのは以下の2行だけです。
実行する場所はどこでもいいと思います。ボタンを押したタイミングなど...

今回はテストのため簡略化しています。
便宜上引数を設けた方がいいと思います。
MyAlarmManager mam = new MyAlarmManager(this);
mam.addAlarm();

【MyAlarmManager.java】
import java.util.Calendar;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

public class MyAlarmManager {
    Context c;
    AlarmManager am;
    private PendingIntent mAlarmSender;
   
    public MyAlarmManager(Context c){
    this.c = c;
    am = (AlarmManager)c.getSystemService(Context.ALARM_SERVICE);
    Log.v("MyAlarmManger","初期化完了");
    }
   
    public void addAlarm(/*今はなにもなしで*/){
    mAlarmSender = PendingIntent.getService(c, -1, new Intent(c, MyAlarmService.class), PendingIntent.FLAG_UPDATE_CURRENT);
    // アラーム時間設定
    Calendar cal = Calendar.getInstance();
    cal.setTimeInMillis(System.currentTimeMillis());
    cal.add(Calendar.MINUTE, 1);
    cal.set(Calendar.SECOND, 0);
    cal.set(Calendar.MILLISECOND, 0);
    Log.v("MyAlarmManagerログ",cal.getTimeInMillis()+"ms");
    am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), mAlarmSender);
    Log.v("MyAlarmManagerログ","アラームセット完了");
    }
}

【MyAlarmService.java】
Serviceを継承してます。

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;

public class MyAlarmService extends Service {

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
    Log.v("MyAlarmServiceログ","Create");
    Thread thr = new Thread(null, mTask, "MyAlarmServiceThread");
    thr.start();
    Log.v("MyAlarmServiceログ","スレッド開始");
    }

    /**
     * アラームサービス
     */
    Runnable mTask = new Runnable() {
    public void run() {
        // ここでアラーム通知する前の処理など...

        Intent alarmBroadcast = new Intent();
        alarmBroadcast.setAction("MyAlarmAction");//独自のメッセージを送信します
        sendBroadcast(alarmBroadcast);
        Log.v("MyAlarmServiceログ","通知画面起動メッセージを送った");
        MyAlarmService.this.stopSelf();//サービスを止める
        Log.v("MyAlarmServiceログ","サービス停止");
    }
    };
}

【MyAlarmNotificationReceiver.java】
これは、サービスから送られて来たメッセージを受信する役割を担います。
今回はただ通知画面を起動するだけです。

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

public class MyAlarmNotificationReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
    Log.v("レシーバログ", "action: " + intent.getAction());
    Intent notification = new Intent(context,
        AlarmNotification.class);
    //ここがないと画面を起動できません
    notification.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    context.startActivity(notification);
    }

}

【AlarmNotificationActivity.java】
これが実際に表示されるアラーム通知画面です。
onStartでアラーム音を再生しています。
onDestroyでリソースを解放します。

import android.app.Activity;
import android.app.KeyguardManager;
import android.app.KeyguardManager.KeyguardLock;
import android.content.Context;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.util.Log;

public class AlarmNotification extends Activity {
    private WakeLock wakelock;
    private KeyguardLock keylock;

    MediaPlayer mp;

    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.alarm);
    Log.v("通知ログ", "create");
    // スリープ状態から復帰する
    wakelock = ((PowerManager) getSystemService(Context.POWER_SERVICE))
        .newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK
            | PowerManager.ACQUIRE_CAUSES_WAKEUP
            | PowerManager.ON_AFTER_RELEASE, "disableLock");
    wakelock.acquire();

    // スクリーンロックを解除する
    KeyguardManager keyguard = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
    keylock = keyguard.newKeyguardLock("disableLock");
    keylock.disableKeyguard();
    }

    @Override
    public void onStart() {
    super.onStart();
    if (mp == null)
        mp = MediaPlayer.create(this, R.raw.alarm);
    mp.start();
    }

    @Override
    public void onDestroy() {
    super.onDestroy();
    stopAndRelaese();
    }

    private void stopAndRelaese() {
    if (mp != null) {
        mp.stop();
        mp.release();
    }
    }
}


大まかにこんな感じでアラームが起動します。
必要に応じてコードは書き換えて下さい。
リソースファイルなどを用意していないと動きません。
コピペで動く保障はしません。

他にも手段はあります。
あくまでも一例としてみて頂ければと思います。

アドバイス、指摘などありましたらコメントをお願いいたします。

2012年3月29日木曜日

『 Android™アプリケーション技術者試験』合格!

受験期限ギリギリのチケットを活用して受験してきました。

会場は自宅から一番近いところで、
開始予定時刻15分前に行き、受付を済ます。

試験の説明があって、開始する。

出てくる問題が意外にも簡単でした。
ちょっと開発経験があり、問題集をやったことがある人なら合格できそうでした。

ライセンスの問題や、プログラムソース、実行結果、イベントなどなど

問題集に似た問題も何問か出ました

メモ用のシート1枚と油性ペンを渡される。
これは使っていいそうだ。
シートが足りなければ追加してもらえる。

ちなみに、Androidのバージョンとバージョン番号の関連づけをど忘れしてしまい、
一問微妙でした。

しかし、後に出て来た問題にそれが載っててラッキーでしたww
出題ミスなのか、意図的なのかはわからない。

【出題問題数】
70問

【結果】
74%で合格
(51問以上正答)

2012年3月20日火曜日

AndroidでGoogleMapにItemizedOverlayを付加する場合

サンプルソースではNullPointerが発生する。

解決方法は以下のページに書いてあるので割愛致します。
http://misapon.blogspot.jp/2010/10/itemizedoverlaymapviewnullpointerexcept.html

コンストラクタでpopulate()メソッドを呼び出すのがキモのようです。

2012年3月14日水曜日

Androidタブレット向けアプリ開発でNetworkOnMainThreadException

タイトルで分かるように、タブレット向けアプリではメインスレッド(UIスレッド)でネットワークアクセスができない。

しようとすると、例外が発生してしまう。

解決するには、別スレッドでネットワークにアクセスする必要がある!!

初めてタブレットアプリを作る人にはビックリですね。
今までの端末では動作していたのに!?ってなりますから

以下のブログでも紹介されています。

Android タブレット アプリ開発でNetworkOnMainThreadException発生

2012年3月1日木曜日

mediba adの不信なメールは不信じゃなかった

アプリに広告を導入しています。
mediba adというところを利用させて頂いてます。

本日突然、パスワード再設定のメールが来ました。
もちろん、再設定の申請はした覚えがまったくありません。

問い合わせにそういった旨をメールしました。

そしたら、サービス統合によるパスワード再設定です、というメールが利用者に送信されました。

安心しました。
アカウントが持ってかれたかとびくびくしましたよ...