スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

Android: 日付→文字列

単にDate型・日付型の数値を文字列に変換したいだけだったが、結構ヒットしないもの。。

Calendar型を使えという記事は多かったが、なんとなく感じが悪いし。

VBでは、formatという関数と同じような挙動をしてくれればOKなんだが。

ということで、自分用まとめ。

ちなみに、エミュレーターのタイムゾーンに影響した時間が表示されます。

・うちのは地域がUSに設定されている模様で、実際の時間-9時間

・携帯にDLして実行したら、日本の今の時間を表示しれくれました。


ソースコード

Date date = new Date(); //VBのnowと一緒
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Log.d("Test", simpleDateFormat.format(date));

★ 注意点! ★

Date部分に赤波線が出てきて、マウスを近づけて「Import #Library」をするとき、間違えて“SQL”用のをインポートしないように!!

スポンサーサイト

Android: Intentのテスト

 サブ画面を呼び出すためのサンプルです。
Intentを利用します。
詳細はたくさんインターネットに出ていると思うので、極力シンプルに“明示的インテント”を書きました。


<注意!!>
AndroidManifest.xmlに、サブ画面の登録をしておかないと、こけます。
いっつも忘れてしまうんですが、、、
ちなみに、↓のような感じでマニュフェストに登録します。

        <activity
            android:name=".SubActivity"
            android:label="SubActivity" >
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>



サンプルは、
  • サブ画面のリストビューを表示
  • クリックしたら、サブ画面を閉じる
  • メインアクティビティで、“サブ画面が閉じられた”のを拾って、クリックされたアイテムを表示
といった流れです。
-----------------------------------------------
1.プロジェクトの新規作成
-----------------------------------------------
Eclipseで、プロジェクトを新規作成します。
ちなみに、私は以下の設定で作りました。
Target Name:Google APIs(Platform=8)
アプリケーション名:TestIntent
パッケージ名:com.fxscore.testintent
Activity名:TestIntentActivity
Minimum SDK:8
-----------------------------------------------
2.サブ画面のクラス作成
-----------------------------------------------
サブ画面のクラスを、Activityから派生させて作ります。
package com.fxscore.testintent;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
public class SubActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.layout_subactivity);
        // アダプター設定
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1);
        adapter.add("red");
        adapter.add("green");
        adapter.add("blue");
        ListView lv = (ListView) findViewById(R.id.sublv);
        lv.setAdapter(adapter);
        // リストビューのアイテムがクリックされた時の挙動
        lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                ListView lv = (ListView) parent;
                String item = lv.getItemAtPosition(position).toString();
                Toast.makeText(SubActivity.this, item, Toast.LENGTH_LONG).show();
                Intent intent = new Intent();  
                intent.putExtra("SUB_INPUT_STRING", item);  
                setResult(RESULT_OK,intent);  
                finish();  
            }
        });
}
}
★利用するリソース(レイアウト)★
(ファイル名:layout_subactivity.xml)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
<ListView
        android:id="@+id/sublv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >
    </ListView>
</LinearLayout>


-----------------------------------------------
3.メインアクティビティの修正
-----------------------------------------------
メインどころの「TestIntentActivity 」を、以下のように書き換えます。


package com.fxscore.testintent;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
public class TestIntentActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        Intent intent = new Intent( TestIntentActivity.this, SubActivity.class );
        //リクエストコード123で呼び出し
        this.startActivityForResult(intent, 123);
    }
    
    @Override  
    protected void onActivityResult(int requestCode, int resultCode, Intent intent) {  
        super.onActivityResult(requestCode, resultCode, intent);  
        
        if (requestCode == 123){  
            if (resultCode == RESULT_OK){  
                Bundle extras = intent.getExtras();  
                if (extras != null){ Log.d("res",extras.getString("SUB_INPUT_STRING")); }
                else               { Log.d("res", "extra is null"                    ); }  
            } else{  
                Log.d("aaa","OKじゃない");
            }  
        }
    }      
}

ちなみに、レイアウトはデフォルトのままでOKです。



-----------------------------------------------
4.マニュフェストの修正
-----------------------------------------------
↓な感じ。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.fxscore.testintent"
    android:versionCode="1"
    android:versionName="1.0" >
    <uses-sdk android:minSdkVersion="8" />
    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:name=".TestIntentActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".SubActivity"
            android:label="SubActivity" >
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
    </application>
</manifest>

以上です。

Android: ListViewをコーディングで作成

ListViewを、xmlのレイアウトを使わずにソースコードに自前で埋め込んで作成する方法です。
そのためには、BaseAdapterクラスを拡張して自前で作成する必要があります。
具体的には以下のとおり。でも、文字サイズとか、きちゃない。。

参考にさせてもらったサイト


-----------------------------------------------
1.プロジェクトの新規作成
-----------------------------------------------
Eclipseで、プロジェクトを新規作成します。
ちなみに、私は以下の設定で作りました。
Target Name:Google APIs(Platform=8)
アプリケーション名:TestListViewNoXML
パッケージ名:com.fxscore.testlistviewnoxml
Activity名:TestListViewNoXMLActivity
Minimum SDK:8
-----------------------------------------------
2.プログラム
-----------------------------------------------
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class TestListViewNoXMLActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // レイアウトをコーディングで作成
        LinearLayout linearLayout = new LinearLayout(this);
        linearLayout.setOrientation(LinearLayout.VERTICAL);
        setContentView(linearLayout);
        
        // ListViewを作成
        ListView lv = new ListView(this);
        String teststr[] = {"str1","str2","str3"};
        lv.setAdapter(new TestAdapter(this, teststr));
        // ListViewをレイアウトにセット
        linearLayout.addView(lv);
        
        // リストビューのアイテムがクリックされた時の挙動
        lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                ListView lv = (ListView) parent;
                String item = (String) lv.getItemAtPosition(position);
                Toast.makeText(TestListViewNoXMLActivity.this, item, Toast.LENGTH_SHORT).show();
            }
        });        
    }
    
    // BaseAdapterクラスを拡張して自前で作成
    private class TestAdapter extends BaseAdapter{
        private Context con;
        private String[] data ;
        // コンストラクタ
        public TestAdapter(Context context, String[] str) {
            con = context;
            data = str ;
        }
        // 必要関数
        public int getCount() {return data.length;}
        public Object getItem(int position) {return data[position];}
        public long getItemId(int position) {return position;}
        // Listの中身を生成
        public View getView(int position, View convertView, ViewGroup parent) {
            TextView tv;
            if(convertView == null){ tv = new TextView(con)    ; }
            else                   { tv = (TextView)convertView; }
            
            tv.setText(data[position]);
            tv.setTextSize(30) ; //文字サイズをここで調整
            return tv;
        }
    }
}

Android: 平凡クラスでアクティビティ

 自分のはまったこと、それは、
  • Googleアカウントの利用認証画面を表示させたい
    → メインアクティビティの直下で実施し、無事成功
  • その機能(認証画面の表示)を外に出したい(クラス化したい)
    → 認証画面を表示させるところで、エラーになる
  • 別画面を表示させなくても、「this」とかを使うもの(AccountManagerとか)でもエラーになる
この問題は、簡単なところで言うと、平凡クラスでトースト(toast:ぼーっと出てくる、中途半端なダイアログボックスみたいなやつ)するときなんかですかね。

エラーのポイントは、「別の画面を出すときは、コンテキストを渡してあげなきゃいけない」ということでした。
メインアクティティの直下で実施するときは、単に“this”としてあげればよかったんですが、別のクラスに持っていった場合、自分はアクティビティじゃないので、thisじゃ動きません。
ちなみに、“別の画面をだす”というのは、インテントという機能を使います。


以下のサンプルは、「メインアクティビティ以外のところ(別のクラス)で、Googleアカウントのログイン認証画面を表示させる」ものです。
-----------------------------------------------
1.プロジェクトの新規作成
-----------------------------------------------
Eclipseで、プロジェクトを新規作成します。
ちなみに、私は以下の設定で作りました。
  • Target Name:Google APIs(Platform=8)
  • アプリケーション名:TestContext
  • パッケージ名:com.fxscore.testcontext
  • Activity名:TestContextActivity
  • Minimum SDK:8
-----------------------------------------------
2.パーミッションの追加
-----------------------------------------------
サンプルなのでそこまでする必要もなかったのですが、せっかくなので「Googleアカウントの利用許可」画面を出す風なサンプルにしました。
そのために、以下のパーミッションをマニュフェストに記述する必要があります。
AndroidManifest.xmlに、以下のパーミッションを追加してください。
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS"/>
-----------------------------------------------
3.クラスの追加
-----------------------------------------------
左のパッケージエクスプローラで、「TestContext->src->com.fxscore.testcontextを右クリック->New->Class」として、クラスを作りましょう。
私は、クラス名を「TestClass」としました。
そして、以下のようなプログラムを記述してください。
このプログラムのミソは、「コンストラクタ」。変数名では「context」。
コンストラクタ=クラスの初期化時に、context=このアプリの親玉の居場所みたいな変数に値を入れてあげることです。
実際には、以下の4番で親玉がこのクラスを呼んでいます。
あとは、「AccountManager.get(context)」や「Toast」、「startActivity(intent)」で、親玉の居場所をAndroidに渡しながら処理を進めていってます。
package com.fxscore.testcontext;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AccountManagerCallback;
import android.accounts.AccountManagerFuture;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Toast;
public class TestClass {
Context context ;
TestClass(Context context){
this.context = context ;
}
public void test(){
   // Googleアカウントの検索
AccountManager mAccountManager = null;
if (mAccountManager == null) mAccountManager = AccountManager.get(context);
Account[] accounts = null;
accounts = mAccountManager.getAccountsByType("com.google");
mAccountManager.getAuthToken(accounts[0], "cl", false, new GetAuthTokenCallback(), null);
}
private class GetAuthTokenCallback implements AccountManagerCallback<Bundle> {
@Override
public void run(AccountManagerFuture<Bundle> arg0) {
Bundle bundle;
try {
bundle = arg0.getResult();
Intent intent = (Intent) bundle.get(AccountManager.KEY_INTENT);
context.startActivity(intent); //許可画面を出す
} catch (Exception e) {
Toast.makeText(context, "Error !", Toast.LENGTH_LONG).show();
}
}
}
-----------------------------------------------
4.テインアクティビティ(親玉)への追記
-----------------------------------------------
クラスを初期化し、test関数を呼び出します。
OnCreateの中に、以下の2文を追記してください。
親玉=このアプリのメインアクティビティが、自分の居場所(this)をクラスに教えてあげてるといった感じです。
        TestClass test = new TestClass(this);
        test.test();
以上で、外出しされた平凡クラスでも、ウィンドウを出したりトーストしたりといったことができるようになります。
■■■■■■■■■■■■■■■■■■■■■■■
 Sample Program(OnCreate)
■■■■■■■■■■■■■■■■■■■■■■■
package com.fxscore.testcontext;
import android.app.Activity;
import android.os.Bundle;
public class TestContextActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        TestClass test = new TestClass(this);
        test.test();
    }
}
■■■■■■■■■■■■■■■■■■■■■■■
 Sample Program(TestClass)
■■■■■■■■■■■■■■■■■■■■■■■
package com.fxscore.testcontext;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AccountManagerCallback;
import android.accounts.AccountManagerFuture;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Toast;
public class TestClass {
Context context ;
TestClass(Context context){
this.context = context ;
}
public void test(){
   // Googleアカウントの検索
AccountManager mAccountManager = null;
if (mAccountManager == null) mAccountManager = AccountManager.get(context);
Account[] accounts = null;
accounts = mAccountManager.getAccountsByType("com.google");
mAccountManager.getAuthToken(accounts[0], "cl", false, new GetAuthTokenCallback(), null);
}
private class GetAuthTokenCallback implements AccountManagerCallback<Bundle> {
@Override
public void run(AccountManagerFuture<Bundle> arg0) {
Bundle bundle;
try {
bundle = arg0.getResult();
Intent intent = (Intent) bundle.get(AccountManager.KEY_INTENT);
context.startActivity(intent); //許可画面を出す
} catch (Exception e) {
                Toast.makeText(context, "Error !", Toast.LENGTH_LONG).show();
}
}
}
■■■■■■■■■■■■■■■■■■■■■■■
 Sample Program(AndroidManifest.xml)
■■■■■■■■■■■■■■■■■■■■■■■
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.fxscore.testcontext"
    android:versionCode="1"
    android:versionName="1.0" >
    <uses-sdk android:minSdkVersion="8" />
    
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS"/>
    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:name=".TestContextActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

Android: 音声認識を使う

 Googleってすごいですね。Googleの音声認識を、みんなで使えるようにしてくれてます。
ということで、Googleの音声認識(RecognizerIntent)を使うサンプルです。


参考ページ:音声認識を使用するには

以下の内容は、↑の参考ページの“まんま”な感じです。。。
大変参考になりました。ありがとうございます。


■■■■■■■■■■■■■■■■■■■■■■■
 音声認識を使う
■■■■■■■■■■■■■■■■■■■■■■■

-----------------------------------------------
1.プロジェクトの新規作成
-----------------------------------------------
Eclipseで、プロジェクトを新規作成します。
ちなみに、私は以下の設定で作りました。
  • Target Name:Google APIs(Platform=8)
  • アプリケーション名:TestOnseiNinshiki
  • パッケージ名:com.fxscore.testonseininshiki
  • Activity名:TestOnseiNinshikiActivity
  • Minimum SDK:8



-----------------------------------------------
2.ListView形式に変更
-----------------------------------------------
過去の記事「Android: ListViewの使い方2」をご参考。
-----------------------------------------------
3.レイアウトの修正:ボタン追加
-----------------------------------------------
レイアウトに、ボタンを追加します。
res->layout->main.xmlに、以下を追加してください。
(リストビューの上にボタン追加)
 <Button
    android:id="@+id/button"
    android:text="Click to start"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"/>
-----------------------------------------------
4.プログラム修正1:ボタンが押された時の制御
-----------------------------------------------
ボタンが押されたら、インテントを作成&発行し、アクティビティ終了時に結果を表示させるといった流れです。
その橋渡しをするため、ID(REQUEST_CODE)を使います。

OnCreateの前に、以下の1行を追加してください。
private static final int REQUEST_CODE = 123456;
次に、ボタンが押された時の制御部分を書きます。
OnCreateの中に、以下を追記します。
なお、エミュレーターなど、マイク機能がついてない場合、例外処理にはいります。
なので、ここからのテストは、携帯本体でおこなう必要があります。。。


        Button button = (Button) findViewById(R.id.button);
        
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    // インテント作成
                    Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
                    intent.putExtra(
                            RecognizerIntent.EXTRA_LANGUAGE_MODEL
                          , RecognizerIntent.LANGUAGE_MODEL_FREE_FORM
                    );
                    intent.putExtra(
                            RecognizerIntent.EXTRA_PROMPT, "Voice Recognition Test"
                    ); // マイクの絵の下に出てくる文字です
                    
                    // インテント発行
                    startActivityForResult(intent, REQUEST_CODE);
                } catch (ActivityNotFoundException e) {
                    // マイク機能がなければ(エミュレータとか)、ここに飛びます
                    Toast.makeText(TestOnseiNinshikiActivity.this
                    , "マイク機能がない ? (ActivityNotFoundException)"
                    , Toast.LENGTH_LONG).show()
                    ;
                }
            }
        });

-----------------------------------------------
4.プログラム修正2:結果を表示させる関数
-----------------------------------------------
しゃべったあとの、認識結果を表示させる部分です。
アクティビティ終了時に呼び出されるonActivityResultをオーバーライドします。
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        // 自分が投げたインテントであれば応答する
        if (requestCode == REQUEST_CODE && resultCode == RESULT_OK) {
        // 結果文字列リストを作成
            ArrayList<String> results = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
            
            // リストビューに登録
            ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1);
            for (int i = 0; i< results.size(); i++) {
                adapter.add(results.get(i));
            }
            setListAdapter(adapter);
        }
        
        super.onActivityResult(requestCode, resultCode, data);
    }
以上です。
こんなに簡単に音声認識機能が使えるなんて、すごい。。。
■■■■■■■■■■■■■■■■■■■■■■■
 Sample Program
■■■■■■■■■■■■■■■■■■■■■■■
package com.fxscore.testonseininshiki;
import java.util.ArrayList;
import android.app.Activity;
import android.app.ListActivity;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.os.Bundle;
import android.speech.RecognizerIntent;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Toast;
public class TestOnseiNinshikiActivity extends ListActivity {
    private static final int REQUEST_CODE = 123456;
/** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        Button button = (Button) findViewById(R.id.button);
        
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    // インテント作成
                    Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
                    intent.putExtra(
                            RecognizerIntent.EXTRA_LANGUAGE_MODEL
                          , RecognizerIntent.LANGUAGE_MODEL_FREE_FORM
                    );
                    intent.putExtra(
                            RecognizerIntent.EXTRA_PROMPT, "Voice Recognition Test"
                    ); // マイクの絵の下に出てくる文字です
                    
                    // インテント発行
                    startActivityForResult(intent, REQUEST_CODE);
                } catch (ActivityNotFoundException e) {
                    // マイク機能がなければ(エミュレータとか)、ここに飛びます
                    Toast.makeText(TestOnseiNinshikiActivity.this
                    , "マイク機能がない ? (ActivityNotFoundException)"
                    , Toast.LENGTH_LONG).show()
                    ;
                }
            }
        });
    }
    // アクティビティ終了時に呼び出される
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        // 自分が投げたインテントであれば応答する
        if (requestCode == REQUEST_CODE && resultCode == RESULT_OK) {
        // 結果文字列リストを作成
            ArrayList<String> results = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
            
            // リストビューに登録
            ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1);
            for (int i = 0; i< results.size(); i++) {
                adapter.add(results.get(i));
            }
            setListAdapter(adapter);
        }
        
        super.onActivityResult(requestCode, resultCode, data);
    }
}
■■■■■■■■■■■■■■■■■■■■■■■
 レイアウト(res->layout->main.xml)
■■■■■■■■■■■■■■■■■■■■■■■
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
 
 <Button
    android:id="@+id/button"
    android:text="Click to start"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"/>
    
 <ListView android:id="@id/android:list"
           android:layout_width="match_parent"
           android:layout_height="match_parent" />
</LinearLayout>

Android: Google Tasksを操作

 GoogleTasks(日本名はToDoリスト?)というのをご存知ですか?
カレンダー(GoogleCalendar)の右横にひっそりとたたずんでる、ToDoリストと言われるやつです。
こいつを、Android携帯で操作しようという試みです。
操作は、ベタにHTTPGETです。

本当は専用ライブラリを使いたかったんですが、操作方法が全くわからない。。。

ちなみに、接続の認証はGoogleAPIというのを使ってます。
この認証に関しては、過去の記事「Android: Google APIの認証」参考にしてください。
※ ベタな接続(POST接続)でも問題ないです。

また、API Keyという、プログラムでGoogleサービスを利用するためのキーを設定する必要があります。
(以下の0番ご参考)



★☆ 注意点! ☆★
・ターゲットを、Android2.2以上(Platformが8以上)でプロジェクト作成。
・TargetNameを、「Google APIs(Platform=8以上)」でプロジェクト作成。「Android 2.2」とかだと、失敗します。
・ネット接続とかGoogleAccountを利用したりするので、Manifestにパーミッションを書き入れる
↑これは、認証部分で必要な箇所です。(自分が忘れないようにココに書き足しときました)



■■■■■■■■■■■■■■■■■■■■■■■
 GoogleTasksの実装
■■■■■■■■■■■■■■■■■■■■■■■

-----------------------------------------------
0.API Keyの入手
-----------------------------------------------

GoogleTasksを使うため、Google ConsoleからAPIKeyを入手する必要があります。
簡単な流れは、
  • https://code.google.com/apis/console/ にアクセス
  • 左の一覧から「Services」を選択
  • Tasks APIを「On」にする
  • 左の一覧から「API Access」を選択
  • そこにあらわれる「API Key」をメモる
といった手順です。
詳細は、「Google API Key Console」などのキーワードでググってみてください。

-----------------------------------------------
1.プロジェクトの新規作成
-----------------------------------------------
Eclipseで、プロジェクトを新規作成します。
ちなみに、私は以下の設定で作りました。
  • Target Name:Google APIs(Platform=8)
  • アプリケーション名:TestGoogleTasks
  • パッケージ名:com.fxscore.testgoogletasks
  • Activity名:TestGoogleTasksActivity
  • Minimum SDK:8

-----------------------------------------------
2.認証部分の仕込み
-----------------------------------------------
過去の記事「Android: Google APIの認証」ご参考にしてください。
マニュフェストにパーミッションを追加したり、OnCreateを改造したり、です。
まずは、一旦ここでテスト実行してみることをオススメします。

-----------------------------------------------
3.プログラム修正1:取得する関数部分の作成
-----------------------------------------------
OnCreateの中ではありません。
OnCreateの外に、以下のように記述してください。
また、上の0番で取得したAPIキーを自分のものに書き換えてください。
ちなみに、貼り付け直後は赤波線がうじゃうじゃ出てきます。これは、ライブラリがインポートされてないからで、マウスを近づけ“Import”をしこしこ選択してください。

<注意>なぜか、「JSONObject」だけは、マウスを近づけても“Import”が出てきませんでした。
もしそうなったら、手動で上の方(Import部分)に「import org.json.JSONObject;」と書き足してください。
    private void GetTasksList(String token){
    
        String url = "https://www.googleapis.com/tasks/v1/users/@me/lists?key=■■■自分のAPIKEY■■■";
        
        try
        {
            //Getで接続(ヘッダの設定)
            HttpGet hg = new HttpGet( url );
            hg.setHeader( "Authorization", "GoogleLogin auth=" + token) ;
            hg.setHeader( "Content-Type", "application/json" );
    
            //接続
            DefaultHttpClient cl = new DefaultHttpClient();
            HttpResponse rsp = cl.execute( hg );
            
            //ステータス判定
            int status = rsp.getStatusLine().getStatusCode();
            if ( status == HttpStatus.SC_OK ) {
                //戻り値取得
                String entity = EntityUtils.toString(rsp.getEntity());
    
                //JSONで扱えるよう、ちょっと加工
                entity = "["+entity+"]";
                //JSONデータの操作
                JSONArray jsons;
                try {
                    jsons = new JSONArray(entity);
                    for (int i = 0; i < jsons.length(); i++) {
                        JSONObject jsonObj = jsons.getJSONObject(i);
                        //各要素をログに吐き出す
                        Log.d("kind", jsonObj.getString("kind")) ;
                        Log.d("etag", jsonObj.getString("etag")) ;
                        //itemsがコアな部分→JSONで再分解
                        JSONArray jsons2 ;
                        jsons2  = new JSONArray(jsonObj.getString("items"));
                        for (int j = 0; j < jsons2.length(); j++) {
                            JSONObject jsonObj2 = jsons2.getJSONObject(j);
                            Log.d("id", jsonObj2.getString("id")) ;
                            Log.d("title", jsonObj2.getString("title")) ;
                        }
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            } else {
                Log.d("ERR", "Connection Error ?");
            }
        }
        catch ( Exception e )
        {
            Log.d("ERR", "Error"+e.toString());
        }
    }

-----------------------------------------------
3.プログラム修正2:関数の呼び出し
-----------------------------------------------
あとは、Tokenを発行した直後に以下の1文を付け足すだけです。
  • GetTasksList(bundle.getString(入手したトークン);
以上です。



■■■■■■■■■■■■■■■■■■■■■■■
 Sample Program
■■■■■■■■■■■■■■■■■■■■■■■
package com.fxscore.testgoogletasks;
import java.io.IOException;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AccountManagerCallback;
import android.accounts.AccountManagerFuture;
import android.accounts.AuthenticatorException;
import android.accounts.OperationCanceledException;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
public class TestGoogleTasksActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    
        // Googleアカウントの検索
        AccountManager mAccountManager = null;
        Account[] accounts = null;
        if (mAccountManager == null) mAccountManager = AccountManager.get(this);
        accounts = mAccountManager.getAccountsByType("com.google");
        for (Account ac : accounts) Log.d("G_Acc", ac.toString());
        
        AccountManagerFuture<Bundle> accountManagerFuture = 
                mAccountManager.getAuthToken(accounts[0], 
                        "cl",         // Google Calendar
                        false, new GetAuthTokenCallback(), null);        
    }
    
    
    private class GetAuthTokenCallback implements AccountManagerCallback<Bundle> {
        @Override
        public void run(AccountManagerFuture<Bundle> arg0) {
            Bundle bundle;
            try {
                bundle = arg0.getResult();
                Intent intent = (Intent) bundle.get(AccountManager.KEY_INTENT);
                if (intent != null) {
                    Toast.makeText(TestGoogleTasksActivity.this, "Click 'Allow' and restart this App", Toast.LENGTH_LONG).show();
                    startActivity(intent); //許可画面を出す
                } else {
                    //Tasksに登録されているリストを出すための関数を呼ぶ
                    GetTasksList(bundle.getString(AccountManager.KEY_AUTHTOKEN));
                }
            } catch (OperationCanceledException e) {
                e.printStackTrace();
            } catch (AuthenticatorException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } 
    }
    
    
    private void GetTasksList(String token){
    
        String url = "https://www.googleapis.com/tasks/v1/users/@me/lists?key=■■■自分のAPIKEY■■■";
        
        try
        {
            //Getで接続(ヘッダの設定)
            HttpGet hg = new HttpGet( url );
            hg.setHeader( "Authorization", "GoogleLogin auth=" + token) ;
            hg.setHeader( "Content-Type", "application/json" );
    
            //接続
            DefaultHttpClient cl = new DefaultHttpClient();
            HttpResponse rsp = cl.execute( hg );
            
            //ステータス判定
            int status = rsp.getStatusLine().getStatusCode();
            if ( status == HttpStatus.SC_OK ) {
                //戻り値取得
                String entity = EntityUtils.toString(rsp.getEntity());
    
                //JSONで扱えるよう、ちょっと加工
                entity = "["+entity+"]";
                //JSONデータの操作
                JSONArray jsons;
                try {
                    jsons = new JSONArray(entity);
                    for (int i = 0; i < jsons.length(); i++) {
                        JSONObject jsonObj = jsons.getJSONObject(i);
                        //各要素をログに吐き出す
                        Log.d("kind", jsonObj.getString("kind")) ;
                        Log.d("etag", jsonObj.getString("etag")) ;
                        //itemsがコアな部分→JSONで再分解
                        JSONArray jsons2 ;
                        jsons2  = new JSONArray(jsonObj.getString("items"));
                        for (int j = 0; j < jsons2.length(); j++) {
                            JSONObject jsonObj2 = jsons2.getJSONObject(j);
                            Log.d("id", jsonObj2.getString("id")) ;
                            Log.d("title", jsonObj2.getString("title")) ;
                        }
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            } else {
                Log.d("ERR", "Connection Error ?");
            }
        }
        catch ( Exception e )
        {
            Log.d("ERR", "Error"+e.toString());
        }
    }
}

Android: Google APIの認証

Googleのサービス(GoogleCalendarとかGoogleTasksとか)を使用する場合、GoogleAPIというのを使って操作すると便利だそうです。が、個人的には、とっても複雑。。。
ということで、認証部分をまとめました。カレンダーの追加登録とかTasksのリスト取得とか、Googleサービスを操作する場合、トークンという認証キーを使うのですが、そのトークンを取得するためのプログラムです。
「携帯(Android)に登録されているGoogleアカウントを利用」するケースと、「べたにID/パスワードを直打ち」するケースの2つ載せてます。

私は、頭が古い分、ベタな方が好きですね。「文書はパソコンで見るより紙にプリントして見たい」という人間ですから。


【追記:2012/4/30】
ベタじゃない方の件です。
よくサンプルとしてインターネットに載ってるやり方だと、token発行処理をコールバックルーチンで呼び出す=別処理に投げて、コールバックルーチンを呼び出す元となるところは処理終了という寸法でした。すなわち、tokenを戻り値とすることができない。。。

なので、
  • トークンを戻す(戻り値とする)関数を宣言
  • もし認証前だったらな、コールバックルーチンで別処理を呼ぶ(その処理自体は空白を戻す)
という2段階の関数としました。

【---追記終わり---】

ちなみに、GoogleAPIをいろいろググってみると「各種JARファイルをインストールする必要あり」みたいな記事が出ていますが、以下のプロジェクトでは特にそれをしていません。
以下のプロジェクト以外でいろいろとあーだこーだやって、“Eclipseにデフォルトで登録”みたいなことをされている可能性もあるのですが、よくわかりません。。。でも、以下のプロジェクトでは、特に何もしていないです。
なお、両方とも、注意点があります。これを知っとかないと、うまくいきません。自分は、かなりはまりました。。。
★☆ 注意点! ☆★
・ターゲットを、Android2.2以上(Platformが8以上)でプロジェクト作成。
・TargetNameを、「Google APIs(Platform=8以上)」でプロジェクト作成。「Android 2.2」とかだと、失敗します。
・ネット接続とかGoogleAccountを利用したりするので、Manifestにパーミッションを書き入れる
詳細は以下をご参考。
■■■■■■■■■■■■■■■■■■■■■■■
 ベタにID/Passwordを直打ちしてトークン取得
■■■■■■■■■■■■■■■■■■■■■■■
ID/PWをベタに入力して、HTTPのPOST接続でおこないます。
ベタな分、パーミッションは最低限(INTERNETだけ)です。
また、携帯に登録されているGoogleアカウントは使用しないので、Android2.2以下でも大丈夫だと思います。たぶん。。
-----------------------------------------------
1.プロジェクトの新規作成
-----------------------------------------------
Eclipseで、プロジェクトを新規作成します。
ちなみに、私は以下の設定で作りました。
・Target Name:Google APIs(Platform=8)
・アプリケーション名:TestGoogleAuth1
・パッケージ名:com.fxscore.testgoogleauth1
・Activity名:TestGoogleAuth1Activity
・Minimum SDK:8
-----------------------------------------------
2.マニュフェストにパーミッションを追加
-----------------------------------------------
プロジェクト名の直下にある「AndroidManifest.xml」に、以下を追加してください。
※ 貼り付け場所は、「<uses-sdk android:minSdkVersion="8" />」の下くらいで。
    <uses-permission android:name="android.permission.INTERNET"/>
-----------------------------------------------
3.プログラム修正
-----------------------------------------------
OnCreateの中に、POST接続部分を追記します。
OnCreate全体は、以下のとおりです。

※ Email(ID)とパスワードは自分のものに書き換えてください!!!


  ↓OnCreateの中身
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    
        // POST接続でTOKEN取得
        try
        {
            HttpPost method = new HttpPost( "https://www.google.com/accounts/ClientLogin" );
            
            // パラメータを生成
            ArrayList<NameValuePair> params = new ArrayList<NameValuePair>();
            params.add(new BasicNameValuePair("Email", "xxxxx@gmail.com"));
            params.add(new BasicNameValuePair("Passwd", "xxxxxxxx"));
            params.add(new BasicNameValuePair("service", "cl")); //カレンダー
            // パラメータを設定
            method.setHeader( "Content-Type", "application/x-www-form-urlencoded" );
            method.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
            
            // 実行
            DefaultHttpClient client = new DefaultHttpClient();
            HttpResponse httpResponse = client.execute(method);
            
            // 成功したら、トークン取得
            int status = httpResponse.getStatusLine().getStatusCode();
            if ( status == HttpStatus.SC_OK ) {
                String entity = EntityUtils.toString(httpResponse.getEntity()); //vbでいうresponseText
                //responseTextからベタにTokenを取得
                String token = entity.substring(entity.indexOf("Auth=")+5);
                token = token.substring(0,token.length()-1) ; //最後の改行文字を除去
                Toast.makeText(TestGoogleAuth1Activity.this, "Token=" + token, Toast.LENGTH_LONG).show();
                Log.d("TOKEN", token); //一応ログにも出してます
            } else {
                Log.d("ERR", "Status was not OK..."+String.valueOf(status));
            }
        }
        catch ( Exception e )
        {
            Log.d("ERR", "ERROR!"+e.toString());
        }
    }
以上でトークンが取得できるはずです。
■■■■■■■■■■■■■■■■■■■■■■■
 Google携帯のIDを利用
■■■■■■■■■■■■■■■■■■■■■■■

Google APIを使います。
ソースコードにID/PWを入力する部分を作る必要はありませんが、その分少々面倒かも。。
-----------------------------------------------
0.エミュレーターにGoogleアカウント登録
-----------------------------------------------
携帯に登録されているGoogleアカウントを使うということは、エミュレーターでテストする場合、<b>Googleアカウントを事前に登録</b>しておく必要があります!!
これは、携帯で操作するのと同じく、設定(Settings)の「アカウントと同期」をクリックして登録するのですが、この作業をする時、<b>Android2.2以上</b>じゃないとだめなんです。。
-----------------------------------------------
1.プロジェクトの新規作成
-----------------------------------------------
Eclipseで、プロジェクトを新規作成します。


ちなみに、私は以下の設定で作りました。
  • Target Name:Google APIs(Platform=8)
  • アプリケーション名:TestGoogleAuth2
  • パッケージ名:com.fxscore.testgoogleauth2
  • Activity名:TestGoogleAuth2Activity
  • Minimum SDK:8
-----------------------------------------------
2.マニュフェストにパーミッションを追加
-----------------------------------------------
プロジェクト名の直下にある「AndroidManifest.xml」に、以下を追加してください。
携帯に登録されてあるGoogleアカウントを利用するため、INTERENET以外のパーミッションも必要です。
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="android.permission.USE_CREDENTIALS"/>
    <uses-permission android:name="android.permission.INTERNET"/>
-----------------------------------------------
3.プログラム修正1:Googleアカウントの取得
-----------------------------------------------
今からのプログラム修正は、OnCreateの中にどんどん書き込んでいきます。
まず、Googleアカウントの取得部分です。


    // Googleアカウントの検索
    AccountManager mAccountManager = null;
    Account[] accounts = null;
    if (mAccountManager == null) mAccountManager = AccountManager.get(this);
    accounts = mAccountManager.getAccountsByType("com.google");
    for (Account ac : accounts) Log.d("G_Acc", ac.toString());
これだけです。一応、for文で取得されたアカウント名をログに書き出してます。

-----------------------------------------------
3.プログラム修正2:認証(OnCreateに追記)
-----------------------------------------------

以下の1文を、上のプログラムの下に書き足してください。

ちなみに、1つ目の変数はアカウント名(上のプログラムで取得されたGoogleアカウントの、1つ目(accounts[0])を使ってます)、2つ目は認証の範囲(cl(カレンダーのこと))です。
GetAuthTokenCallbackを呼び出しますが、まだ定義していないので、この時点ではGetAuthTokenCallbackに赤波線が付きます。


// アカウントタイプの一覧
// "cl", // Google Calendar
// "android", 
// "ah", // Google AppEngine 
// "mail", // Gmail
// "reader", // Google Reader
// "talk", // Gtalk
// "youtube", // YouTube 
        AccountManagerFuture<Bundle> future = mAccountManager.getAuthToken (accounts[0], "cl", false, null, null);
        String token = null ;
        try{
            Bundle bundle = future.getResult(); //認証がまだのときはここで例外発生
            token = bundle.getString(AccountManager.KEY_AUTHTOKEN);
            Log.d("Token", token);
  Toast.makeText(this, "token=[" + token + "]", Toast.LENGTH_LONG).show();
        }catch(Exception e){
        // 認証がまだのときは、認証画面を出すよう呼びかけて、ここからは抜ける
mAccountManager.getAuthToken(accounts[0], "cl", false, new GetAuthTokenCallback(), null) ;
        }


-----------------------------------------------
3.プログラム修正2:認証(GetAuthTokenCallback)
-----------------------------------------------
OnCreate文の外に、以下の関数を追記してください。
これで実装はすべて完了ですが、注意点があります。
一発目に実行したら、まずは「このアプリケーションにGoogleアカウントを使わせてもいいか?」という確認画面がでます。
ここで“許可(Allow)”をしてあげたのち、一旦終了してください。
そして、再度このアプリを起動したら、トークンの取得ができるようになります。
    private class GetAuthTokenCallback implements AccountManagerCallback<Bundle> {
        @Override
        public void run(AccountManagerFuture<Bundle> arg0) {
            Bundle bundle;
            try {
                bundle = arg0.getResult();
                Intent intent = (Intent) bundle.get(AccountManager.KEY_INTENT);
                if (intent != null) {
                    Toast.makeText(TestGoogleAuth2Activity.this, "Click 'Allow' and restart this App", Toast.LENGTH_LONG).show();
                    startActivity(intent); //許可画面を出す
                } else {
                    Log.d("Token", bundle.getString(AccountManager.KEY_AUTHTOKEN));
                }
            } catch (OperationCanceledException e) {
                e.printStackTrace();
            } catch (AuthenticatorException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } 
    }



以上です。


■■■■■■■■■■■■■■■■■■■■■■■
 Sample Program : ベタな方
■■■■■■■■■■■■■■■■■■■■■■■
package com.fxscore.testgoogleauth1;
import java.util.ArrayList;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
public class TestGoogleAuth1Activity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    
        // POST接続でTOKEN取得
        try
        {
            HttpPost method = new HttpPost( "https://www.google.com/accounts/ClientLogin" );
            
            // パラメータを生成
            ArrayList<NameValuePair> params = new ArrayList<NameValuePair>();
            params.add(new BasicNameValuePair("Email", "shin.oomura@gmail.com"));
            params.add(new BasicNameValuePair("Passwd", "shin9232"));
            params.add(new BasicNameValuePair("service", "cl")); //カレンダー
            // パラメータを設定
            method.setHeader( "Content-Type", "application/x-www-form-urlencoded" );
            method.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
            
            // 実行
            DefaultHttpClient client = new DefaultHttpClient();
            HttpResponse httpResponse = client.execute(method);
            
            // 成功したら、トークン取得
            int status = httpResponse.getStatusLine().getStatusCode();
            if ( status == HttpStatus.SC_OK ) {
                String entity = EntityUtils.toString(httpResponse.getEntity()); //vbでいうresponseText
                //responseTextからベタにTokenを取得
                String token = entity.substring(entity.indexOf("Auth=")+5);
                token = token.substring(0,token.length()-1) ; //最後の改行文字を除去
                Toast.makeText(TestGoogleAuth1Activity.this, "Token=" + token, Toast.LENGTH_LONG).show();
                Log.d("TOKEN", token); //一応ログにも出してます
            } else {
                Log.d("ERR", "Status was not OK..."+String.valueOf(status));
            }
        }
        catch ( Exception e )
        {
            Log.d("ERR", "ERROR!"+e.toString());
        }
    }
}
■■■■■■■■■■■■■■■■■■■■■■■
 Sample Program : Googleアカウントを使う方
■■■■■■■■■■■■■■■■■■■■■■■
package com.fxscore.testgoogleauth2;
import java.io.IOException;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AccountManagerCallback;
import android.accounts.AccountManagerFuture;
import android.accounts.AuthenticatorException;
import android.accounts.OperationCanceledException;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
import android.content.Intent;
public class TestGoogleAuth2Activity extends Activity {
    /** Called when the activity is first created. */
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        // Googleアカウントの検索
        AccountManager mAccountManager = null;
        Account[] accounts = null;
        if (mAccountManager == null) mAccountManager = AccountManager.get(this);
        accounts = mAccountManager.getAccountsByType("com.google");
        for (Account ac : accounts) Log.d("G_Acc", ac.toString());

        AccountManagerFuture<Bundle> future = mAccountManager.getAuthToken (accounts[0], "cl", false, null, null);
        String token = null ;
        try{
            Bundle bundle = future.getResult(); //認証がまだのときはここで例外発生
token = bundle.getString(AccountManager.KEY_AUTHTOKEN);
Log.d("Token", token);
Toast.makeText(this, "token=[" + token + "]", Toast.LENGTH_LONG).show();
        }catch(Exception e){
        // 認証がまだのときは、認証画面を出すよう呼びかけて、ここからは抜ける
mAccountManager.getAuthToken(accounts[0], "cl", false, new GetAuthTokenCallback(), null) ;
        }
    }
    
    
    private class GetAuthTokenCallback implements AccountManagerCallback<Bundle> {
        @Override
        public void run(AccountManagerFuture<Bundle> arg0) {
            Bundle bundle;
            try {
                bundle = arg0.getResult();
                Intent intent = (Intent) bundle.get(AccountManager.KEY_INTENT);
                if (intent != null) {
                    Toast.makeText(TestGoogleAuth2Activity.this, "Click 'Allow' and restart this App", Toast.LENGTH_LONG).show();
                    startActivity(intent); //許可画面を出す
                } else {
                    Log.d("Token", bundle.getString(AccountManager.KEY_AUTHTOKEN));
                }
            } catch (OperationCanceledException e) {
                e.printStackTrace();
            } catch (AuthenticatorException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } 
    }
}

Android: ListViewの使い方2

普段はActivityから派生させてると思いますが、ListActivityというものから派生できることを知りました。
これだと、とてもスッキリとリストビューがつくれます。


1.プロジェクトの新規作成
新規でAndroidのプロジェクトを作ります。
ちなみに、以下のサンプルソースは、
・アプリケーション名:TestListView
・パッケージ名:com.fxscore.testlistivew
・アクティビティ名:TestlistviewActivity
・SDKバージョン:8
・ターゲット:Android2.2
で作っています。

2.main.xmlのレイアウト変更

まず、レイアウト(res->layout->main.xml)を、以下のようにします。


android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
android:layout_width="match_parent"
android:layout_height="match_parent" />


の部分を追加するってことです。

3.プログラムの修正
派生元を、ActivityからListActivityに変更します。

public class TestListViewActivity extends ListActivity {

赤波線が出ると思うので、その時はライブラリをインポートしましょう。

次に、リストに文字列を登録する部分を追加します。
「setContentView・・・」の下に、以下のソースを追加してください。

ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1);
adapter.add("aaa");
adapter.add("bbb");
adapter.add("ccc");
setListAdapter(adapter);

以上で、リストビューが完成です。

4.(蛇足)クリックしたら、、、の挙動
3まででリストに文字列が表示されますが、「リストをクリックすると何かする」という場合は、以下のようなコマンドを追記します。
これを追記すると、「リストをクリックしたら、その項目名がトースト(ぼーっと文字が出てくる、中途半端なダイアログボックスみたいなやつ)される」という動きをするようになります。

@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
TextView textView = (TextView)v;
Toast.makeText(this, textView.getText().toString(), Toast.LENGTH_LONG).show();
}


全体のソースコードは、以下のとおりです。


※ 蛇足 ※
ごく一般的な日本の会社のサラリーマンですが(しかも長年)、ココに書いてる日本語が、社内用語のような非常に堅い文章になってるのに、気づく。。。


/*-------------------------------------------*/
/*--- Sample Program ------------------------*/
/*-------------------------------------------*/
package com.fxscore.testlistview;

import android.app.ListActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

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

ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1);
adapter.add("aaa");
adapter.add("bbb");
adapter.add("ccc");
setListAdapter(adapter);

}

@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
TextView textView = (TextView)v;
Toast.makeText(this, textView.getText().toString(), Toast.LENGTH_LONG).show();
}

}



※ 参考にさせていただいたページ
https://sites.google.com/site/chobimemo/android/listview/listview0


AndroidエミュレータにGoogleアカウントを登録

GoogleAPIを使ったAndroidのアプリを開発する際、認証のテストをする必要がある。
そのために、AndroidエミュレータにGoogleアカウントを登録しなくちゃいけないが、なかなかうまくいかず。。。
ということで、メモ。

・EclipseのAVD Managerで、エミュレータを作成。GoogleAPIs(Level7)で作成。
 →Level8じゃないとだめみたいな記事もあったが、7でもOKでした。(・・・実はNGだった。。)
 →やっぱりLevel8以上じゃないとだめだった。。。

また、GoogleAPIsとして作成しないと、GoogleAccountは登録できなかった。これが注意点。

Google APIのサンプル

GoogleのカレンダーやToDo(Tasks)をコントロールするAPI群の使い方まとめです。
※ VB6です

HTTP操作をするため、以下のライブラリを参照設定する必要があります。
「Microsoft WinHTTP Services」

手順は、まずログインプロセスでトークンを取得し、そのトークンを使って必要なAPIをHTTP経由で操作するといった感じです。
なので、したい操作によって接続先アドレスがちょいちょい変わります。

スケジュールやタスクを登録する際はPOST、登録されている情報を取得する際はGETですが、その際、JSONというデータ形式を使ってやりとりします。
※ JSONをデコードするクラスも記事投稿していますので、ご参照ください。
記事

日付・時間形式など、Google APIのヘルプページには載ってない気がするんですよね。。試行錯誤で形式を探り当てたので、形式で困ってらっしゃる方は以下ご参考。


● ログイン & トークン・承認コード取得
以下のような感じでログインし、APIをコントロールする際のトークンなどを取得します。
なお、接続先アドレスは、
Private Const URI_GOOGLE_LOGIN As String = "https://www.google.com/accounts/ClientLogin"
です。

Private http As WinHttp.WinHttpRequest

'*--------------------------------------------------------------------*
'*-- Google へのログイン ---------------------------------------------*
'*--------------------------------------------------------------------*
Public Function login(email As String, password As String) As Boolean
Dim Body As String

login = False

Body = "Email=" & email & "&Passwd=" & password & "&service=cl&source=Microsoft-VisualBasic-6.0"
Set http = New WinHttp.WinHttpRequest
http.Open "POST", URI_GOOGLE_LOGIN, False
http.SetRequestHeader "Content-Type", "application/x-www-form-urlencoded"
http.Send CVar(Body)

If http.Status <> HTTP_STATUS_OK Then
login = False
ErrMsg = http.StatusText
Exit Function
End If
If InStr(1, http.ResponseText, "Auth=") = 0 Then
login = False
ErrMsg = http.StatusText
Exit Function
End If

token = Right(http.ResponseText, Len(http.ResponseText) - InStrRev(http.ResponseText, "Auth=") - 4)
authorization = "GoogleLogin auth=" & token

login = True
ErrMsg = ""
End Function


●Tasksのコントロール(リスト取得)

ログインする際に取得したトークンを利用して、以下のような感じでアクセスします。
以下は、Tasksのリストを取得するためのものです。
※ RepStrは文字置換関数です。ググるとヒットしますので、そちらをご参照ください。

Private Const URI_GOOGLE_TASKS_TASKLISTID As String = "https://www.googleapis.com/tasks/v1/users/@me/lists?key=<>"


uri = RepStr(URI_GOOGLE_TASKS_TASKLISTID, "<>", API_KEY)
http.Open "GET", uri, False
http.Option(WinHttpRequestOption_EnableRedirects) = False
http.SetRequestHeader "Authorization", authorization
http.SetRequestHeader "Content-Type", "application/json"
http.Send


●Tasksのコントロール(Taskの取得)
同じく、リスト内にあるTaskを取得するための接続先です。
なお、TaskListIDは、上の「リスト取得」で取ることができる、リスト固有のIDです。

uri = RepStr(RepStr(URI_GOOGLE_TASKS, "<>", API_KEY), "<>", TaskListID)
http.Open "GET", uri, False
http.Option(WinHttpRequestOption_EnableRedirects) = False
http.SetRequestHeader "Authorization", authorization
http.SetRequestHeader "Content-Type", "application/json"
http.Send


●カレンダーの種類の取得

Private Const URI_GOOGLE_CALENDARLIST As String = "https://www.googleapis.com/calendar/v3/users/me/calendarList?key=<>"

uri = RepStr(URI_GOOGLE_CALENDARLIST, "<>", API_KEY)
http.Open "GET", uri, False
http.Option(WinHttpRequestOption_EnableRedirects) = False
http.SetRequestHeader "Authorization", authorization
http.SetRequestHeader "Content-Type", "application/json"
http.Send


●スケジュールの取得
スケジュールを普通に読み込むと、大量にデータが流れ込んでくると思うので、そこで固まります。(一回、大泣きしました。。)

なので、日付指定オプション(timeMin, timeMax)で期間を指定してあげましょう。
また、念のため、maxResults(とってくる上限個数)も指定しておいた方がいいかも。

指定する日付は、yyyy-MM-ddT00:00:00Z というようにTだのZだのが付きます。
2012/4/1だったら、2012-04-01T00:00:00Zですね。時間部分は省けないようでした。

Private Const URI_GOOGLE_CALENDAR As String = "https://www.googleapis.com/calendar/v3/calendars/<>/events?key=<>"

uri = RepStr(RepStr(URI_GOOGLE_CALENDAR, "<>", API_KEY), "<>", CalendarID)
http.Open "GET", uri _
& "&timeMin=" & Format(dt_from, "yyyy-MM-dd") & "T" & Format(dt_from, "HH:mm:ss") & "Z" _
& "&timeMax=" & Format(dt_to, "yyyy-MM-dd") & "T" & Format(dt_to, "HH:mm:ss") & "Z" _
& "&maxResults=100" _
, False
http.Option(WinHttpRequestOption_EnableRedirects) = False
http.SetRequestHeader "Authorization", authorization
http.SetRequestHeader "Content-Type", "application/json"
http.Send


● カレンダー登録
アクセス自体は上のような感じですが、渡すデータの形式でちょっと悩みました。
要はJSON形式なのですが、日付指定がちょっと変わった感じ。
 {・・・, "start":{"dateTime":"2012-04-01T12:00:00+09:00"}, ・・・}
といった感じです。詳細は以下ご参考。


Private Const URI_GOOGLE_CALENDAR As String = "https://www.googleapis.com/calendar/v3/calendars/<>/events?key=<>"


Dim sCmd As String
sCmd = "{ ""summary"":""" & Title & """,""description"":""" & Content & """,""location"":""" & Location & """,""start"": {""dateTime"": ""2012-04-27T12:00:00+09:00""}, ""end"": {""dateTime"": ""2012-04-27T12:30:00+09:00""}}"
' If DueDate <> 0 _
Then sCmd = sCmd & ",""due"": """ & Format(DueDate, "yyyy-MM-dd") & "T" & Format(DueDate, "HH:nn:ss") & ".000Z"" }" _
Else sCmd = sCmd & " }"

uri = RepStr(RepStr(URI_GOOGLE_CALENDAR, "<>", API_KEY), "<>", CalendarID)

http.Open "POST", uri, False
http.Option(WinHttpRequestOption_EnableRedirects) = False
http.SetRequestHeader "Authorization", authorization
http.SetRequestHeader "Content-Type", "application/json"
http.Send CVar(sCmd)


後ほどサンプルエクセルを掲載予定です。


VB6でJSONもどき

GoogleAPIやNOZBEのAPIを使う際、JSONのハンドリングは必須。

で、JSONをVB6で扱うためのクラスなりライブラリなりが見つからなかったので、自作。
特にJSONをデコード?デシリアリズ?(データを抽出)するのが難航。

以下サンプルです。
大カッコや中カッコの“くくり”を判定するロジックの部分が、InStrなどを駆使してもっとスマートに記述できるとおもうのですが、断念。もしうまく書き直していただける方がいらっしゃいましたら、是非フィードバックをお願いします。


Excel Sample
class file

無線LANで他のパソコンが見れない症状について

BuffaloのWHR-G301Nを購入し、無線LANの設定をしたが、同一ワークグループにいるのに他のPCが見えない。。。
ファイル共有やファイル転送も当然できない。
また、AndroidのPCFilelinkやESファイルエクスプローラからも他のPCが見れない・つながらない状況となる。

で、次の方法で無事解決。

マルチキャスト制御でSnooping機能を無効にする

ちなみに、これをして他のPCのファイルを“ストリーミング再生”してみたところ、極端に速度が落ちたので、再度“Snooping有効”と設定し、もう一回“無効”にし、ストリーミング再生を試したら、問題なくスムーズに再生。
なんだったんでしょ?

以上、備忘録でした。


上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。