2011年12月27日火曜日

アプリ作り奮闘中

今年中にアプリを公開したかったんですが、どうもヤバそうです。
sdk入れなおしたりしてるので、進まない。。。

公開するアプリはそのうち説明をblogにあげるつもりです。
なんとか間に合うといいけど。。。

2011年12月17日土曜日

Android Market デベロッパー登録

最近blogを全然up出来てませんでした。。。
急ぎでアプリを作ることになって、そちらに精一杯でした。
(アプリの事は別で書きますね。)

さて、本題。
今日はAndroid Marketにデベロッパー登録を行いました。
つまりアプリを公開出来る状態になった、と言う事です。

メモ書きとして、登録方法を残しておきます。
(これから開発者登録を考えている方は参考にして下さい。)


1. Android Marketページ(http://market.android.com/publish/)を表示し、Google Accountでログインする。



2. 開発者情報を入力するページが表示されるので、掲載情報の入力を行い「次へ」をクリックする。

デベロッパー名アプリの開発者として表示される名前
メールアドレスメールアドレス
ウェブサイトのURL運営しているウェブサイトのURL
電話番号市外局番の先頭の「0」を取り、日本の国番号を示す「81」を付ける。
※普通電話 03-1234-5678 の場合、+81-3-1234-5678 と入力。
※携帯電話 090-1234-5678 の場合、+81-90-1234-5678 と入力。



3. Google Checkoutを利用して開発者登録を続けるかどうかの確認ページが表示されるので、「次へ」をクリックする。



4. 注文明細が表示されるので、必要な項目にチェックをいれ、「今すぐ注文する」をクリックする。

(Google Checkout未登録の場合、クレジットカード情報を登録するページへ遷移します。
その場合は、必要情報を入力して、「同意して続行する」をクリックする事で注文明細の確認画面へ遷移します。)





5. 完了画面が表示される。




以上です。
デベロッパー登録には25ドル掛かりますが、一度登録をするとアプリをupし放題になります。
(おまけに今は円高ですしね。)

sirocoもとうとうデベロッパー登録をしたので、アプリ公開へ一歩前進しました。
冒頭にも述べたとおり、最近はアプリ作りをしていましたので、年内中に公開出来ればな~と思っています。

頑張るぞ~

2011年12月3日土曜日

PreferenceActivityへの画面遷移

前回はPreferenceActivityを使用して設定画面を作成しました。
今回は別画面のオプションメニューから設定画面を表示させてみます。

イメージがつきやすいように実行結果から。
まずはアプリケーションを起動します。
画面には特に何も表示させていません。

メニューボタンを押すと、オプションメニューが表示されます。

オプションメニューの設定ボタンをタップすると、設定画面が表示されます。


単純な遷移ですが、どんなアプリを作る場合でも役に立ちますので、
しっかり押さえていきます。

次にJavaのソースコードを見ていきます。
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;

public class PreferenceSampleActivity extends Activity {
 private final int REQUEST_CODE=0;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
 }

 @Override
 public boolean onCreateOptionsMenu(Menu menu) {
  MenuItem menuItem = menu.add(
    Menu.NONE,
    Menu.FIRST,
    Menu.NONE,
    "Preference");
  menuItem.setIcon(android.R.drawable.ic_menu_preferences);
  return true;
 }

 @Override
 public boolean onOptionsItemSelected(MenuItem item) {
  switch (item.getItemId()) {
  case Menu.FIRST:
    Intent intent = new Intent(this, PreferenceSample01.class);
    startActivityForResult(intent, REQUEST_CODE);
  return true;
  }
  return false;
 }

 @Override
 protected void onActivityResult(
   int requestCode,
   int resultCode,
   Intent data) {
  super.onActivityResult(requestCode, resultCode, data);
  if (REQUEST_CODE == resultCode) {
   // TODO 設定画面の変更値を受け取る
  }
 }
}

[17行目]
まずはオプションメニューの設定を、onCreateOptionsMenuメソッドを
オーバーライドする事で行っています。
MenuItemの生成と、アイコンの設定ですね。

[28行目]
次にオプションメニューのアイテムが選択された場合の手続きを
onOptionsItemSelectedメソッドをオーバーライドする事で行っています。
onCreateOptionsMenuで作成されたアイテムを選択された場合に、
Intentを利用して前回作成した設定画面へ遷移させています。

※switch分を使用しているのはオプションメニューのアイテムが増えることを想定して、
拡張出来るようにしている為です。

ここまでで設定画面への遷移は出来ます。
onActivityResultメソッドをオーバーライドしていますが、
今回は何もしていません。
次回くらいに設定画面で入力した内容を使って動作させたいので、記載してます。

"res/layout/preference.xml"は前回と同様です
(→ こちらをご参照あれ)。

"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"
    >
</LinearLayout>

今回は初めて2画面使用しましたので、
"AndroidManifest.xml"も記載します。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="jp.gr.java_conf.siroco.preference.sample"
      android:versionCode="1"
      android:versionName="1.0">
    <uses-sdk android:minSdkVersion="8" />

    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".PreferenceSampleActivity"
                  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=".PreferenceSample01" />
    </application>
</manifest>

以上です。
PreferenceAcitivityで設定画面を作るテクニックも重要ですが、
表示させる工程も必要ですので、この動作をチョイスしました。
いきなり設定画面ってアプリもそうないですからね~


sirocoの事を少し書くと、最近仕事が忙しくなってきたので、
なかなか学習時間がとれません。。。

ただ、アプリ作りの時間はsirocoにとって
とても楽しい時間にもなっているので、
出来る限りBlogもUPしていこうと思います。

2011年11月30日水曜日

東方神霊廟

たまにはAndroid以外の事も。

以前少し触れたけど、sirocoはゲームを作りたかった事がありました。
無理だったけどね。。。
(まだ諦めてないよ)

ゲームは子供のころから好きで、今でも少しやっています。
最近やっているのは東方Projectの最新作「東方神霊廟」。
紅魔卿からずっとやってきたけど、sirocoはへたっぴいなので
Nomalノーコンテニュークリアした事なかったのです。

けれど、先日、とうとうやりました!
ノーコンクリアです!!
勿論Nomalですが、sirocoにとっては凄い事です!
感激で、エンディング中はずっと震えてました。。。

あまりに嬉しかったので、アプリ関係ないけど、
載せちゃいました(^ - ^;)

2011年11月28日月曜日

PreferenceActivityを使用した設定画面

以前予告した通り、設定画面の作り方について学習していきます。

設定画面は大抵のアプリケーションに用意されていて、
sirocoのアプリにも、勿論、用意するつもりです。

設定画面の作成方法は色々とありますが、
PreferenceActivityを使った、最もシンプルな方法を紹介します。

今回は先に実行結果。

上記imageの通り、
「チェックボックス」、「エディットテキスト」、「リスト」、「リングストン」を表示します。
それぞれの要素が次の"res/layout/preference.xml"の各タグに紐付いています。
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
 xmlns:android="http://schemas.android.com/apk/res/android">
 <PreferenceCategory android:title="@string/title">
  <CheckBoxPreference
   android:key="checkbox_key"
   android:title="@string/checkbox_title"
   android:summary="@string/checkbox_summary" />
  <EditTextPreference
   android:key="edittext_key"
   android:title="@string/edittext_title"
   android:summary="@string/edittext_summary"
   android:dialogTitle="@string/edittext_dialog_title" />
  <ListPreference
   android:key="list_key"
   android:title="@string/list_title"
   android:summary="@string/list_summary"
   android:dialogTitle="@string/list_dialog_title"
   android:entries="@array/list_entries"
   android:entryValues="@array/list_entry_values" />
  <RingtonePreference
   android:key="ringtone_key"
   android:title="@string/ringtone_title"
   android:showDefault="true"
   android:summary="@string/ringtone_summary" />
 </PreferenceCategory>
</PreferenceScreen>

05行目:CheckBoxPreferenceタグがチェックボックスに、
09行目:EditTextPreferenceタグがエディットテキストに、
14行目:ListPreferenceタグがリストに、
21行目:RingtonePreferenceタグがリングストンに対応します。

綺麗な入れ子になっているので、理解しやすいと思います。

次は画面に表示する文字列と、リストの要素関連のxmlファイルです。
"res/values/strings.xml"
<?xml version="1.0" encoding="utf-8"?>
<resources>
 <string name="app_name">preferenceSample</string>
    <string name="title">設定画面Sample</string>
    <string name="checkbox_title">Checkbox</string>
    <string name="checkbox_summary">CheckboxのSummary</string>
    <string name="edittext_title">EditText</string>
    <string name="edittext_summary">EditTextのSummary</string>
    <string name="edittext_dialog_title">
        EditTextのダイアログタイトル
    </string>
    <string name="list_title">List</string>
    <string name="list_summary">ListのSummary</string>
    <string name="list_dialog_title">Listのダイアログタイトル</string>
    <string name="ringtone_title">Ringtone</string>
    <string name="ringtone_summary">RingtoneのSummary</string>
</resources>

"res/values/arrays.xml"
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="list_entries">
        <item>First</item>
        <item>Second</item>
        <item>Third</item>
    </string-array>
    <string-array name="list_entry_values">
        <item>FirstのValue</item>
        <item>SecondのValue</item>
        <item>ThirdのValue</item>
    </string-array>
</resources>

最後にJavaコード。
addPreferencesFromResourceメソッドで
設定画面の項目を定義したxmlファイル(preference.xml)を指定しているだけです。
import android.os.Bundle;
import android.preference.PreferenceActivity;

public class PreferenceSample01 extends PreferenceActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.layout.preference);
    }
}

表示された要素をタップした様子は次の通りです。



大半がxmlファイルの設定で行える為、手軽に作成が出来ます。
実際のアプリの設定画面では、そのアプリに適した内容をpreference.xmlに設定するわけです。
sirocoの場合、カメラアプリを作成しようとしているので、
フラッシュのon/offの切り替えや、画面サイズなどを定義するのかな~

PreferenceActivityについては、あと何度か学習して、
より実践的な設定画面を作ってみたいと思います。

2011年11月22日火曜日

ListViewの折り畳み

ListViewについて色々とやってきましたが、今回で最後にします。

ListViewはリストを画面に表示するクラスでしたが、
リストを選択すると更にリストが表示される、
階層表示を実装してみます。

まずはJavaのコードです。
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.SimpleExpandableListAdapter;
import android.widget.Toast;

public class ListView11 extends Activity{

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);

  // ExpandableListViewインスタンスを取得
  ExpandableListView listView =
    (ExpandableListView) findViewById(R.id.list);

  // 親のリストを格納するArrayListインスタンスを生成
  List<Map<String, Object>> parentsList =
    new ArrayList<Map<String, Object>>();

  // parentsListにデータを追加
  parentsList.add(getParentData("親1"));
  parentsList.add(getParentData("親2"));

  // 子のリストを格納するArrayListインスタンスを生成
  List<List<Map<String, Object>>> childrenList =
    new ArrayList<List<Map<String, Object>>>();

  // 子リストにデータを追加
  childrenList.add(getChildList("子1-1", "子1-2")); // 親1に対応
  childrenList.add(getChildList("子2-1", "子2-2")); // 親2に対応

  // SimpleExpandableListAdapterインスタンスを生成
  SimpleExpandableListAdapter adapter = new SimpleExpandableListAdapter(
    this,
    parentsList,
    android.R.layout.simple_expandable_list_item_1,
    new String[]{"parent_text"},
    new int[]{android.R.id.text1},
    childrenList,
    R.layout.row,
    new String[]{"child_text"},
    new int[]{R.id.child_text}
  );

  // 作成したアダプタをExpandableListViewにセットする
  listView.setAdapter(adapter);

  // クリック時のリスナを設定
  listView.setOnChildClickListener(
    new ExpandableListView.OnChildClickListener() {

   @SuppressWarnings("unchecked") // ジェネリクスを使用したキャストの為
   @Override
   public boolean onChildClick(
     ExpandableListView parent,
     View view,
     int groupPosition,
     int childPosition,
     long id) {

    // アダプタからデータを取得してトーストで表示
    ExpandableListAdapter adapter = parent.
      getExpandableListAdapter();
    Map<String, Object> childMap = (Map<String, Object>)adapter.
      getChild(groupPosition, childPosition);
    Toast.makeText(
      ListView11.this,
      childMap.get("child_text").toString(),
      Toast.LENGTH_SHORT
    ).show();
    return false;
   }
  });
 }

 /**
  * 親リストに格納するデータを返す
  *
  * @param object  親リストに格納するMapのvalue値
  * @return parentData 親リストに格納するMap
  */
 private Map<String, Object> getParentData(Object object) {
  Map<String, Object> parentData = new HashMap<String, Object>();
  parentData.put("parent_text", object);
  return parentData;
 }

 /**
  * 子リストに格納するデータを返す
  *
  * @param object  子リストに格納するMapのvalue値の配列
  * @return childList 子リストに格納するList
  */
 private List<Map<String, Object>> getChildList(Object... object) {
  List<Map<String, Object>> childList =
    new ArrayList<Map<String, Object>>();

  // 引数に渡されたオブジェクトの数だけ子リストを追加
  for (Object o : object) {
   Map<String, Object> childData = new HashMap<String, Object>();
   childData.put("child_text", o);
   childList.add(childData);
  }
  return childList;
 }
}
長ったるいコードですが、やっている事は単純です。

1. ExpandableListViewクラスのインスタンスを生成(22行目)
⇒これが画面に表示されるリストの骨格です。
名前の通りListViewを継承しています。

2. SimpleExpandableListAdapterクラスのインスタンスを生成(42行目)
⇒ExpandableListViewに値をセットする為のアダプタ。
親リストと子リストをコンストラクタで渡してやる事で、
階層表示を可能にします。

3. ExpandableListViewにSimpleExpandableListAdapterをセット(55行目)
⇒作成したアダプタをリストビューに設定する事で、
親リストと子リストが格納されます。

その他にクリックリスナーを設定していたり、
privateなメソッドで親リストや子リストの生成を行っていますが、
今回の主題であるリストの階層表示には直接関係ありません。。。

続いて"res/layout/main.xml"のコードです。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/parent"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
>
<ExpandableListView
    android:id="@+id/list"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
/>
</LinearLayout>
ここで設定しているExpandableListViewが親リストとなります。

"res/layout/row.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="wrap_content"
>
<TextView
    android:id="@+id/child_text"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
/>
</LinearLayout>
TextViewが子リストの要素となります。


上記のコードを実行すると、次のように表示されます。

親リストをタップする事で子リストが表示されます。

今回は親リストに対して、子リストを2件ずつ設定しましたが、
子リストにあたるArrayListの要素数だけ表示する事が可能です。


ListViewを4回程学習してきましたが、
各パターンごとに専用のアダプタが用意されており、
使い方さえわかれば初心者のsirocoでも実装は難しくないと感じました。

色々なAPIが用意されているのもAndroidの良いところですね~
次回はアプリには大抵用意されている「設定画面」を作ってみたいと思います。

2011年11月18日金曜日

ListViewの複数行選択

ListViewのコードを載せるのも、もう3回目。
だいぶ慣れてきました。
今回はリストを複数選択できるようにします。

ポイントとなるのは次の3点です。

  • android.R.layout.simple_list_item_multiple_choice
    Javaソースの26行目です。
    これをArrayAdapterのコンストラクタに渡すことで、チェックボックスが表示されます。
  • setChoiceMode(ListView.CHOICE_MODE_MULTIPLE)
    Javaソースの37行目です。
     コメントにある通り、これを実行する事で複数選択が可能となります。
  • android:choiceMode="multipleChoice"
    xmlの方の11行目。
    ここでも複数選択を指定してやります。
Javaコードは以下の通り
import android.app.Activity;
import android.os.Bundle;
import android.util.SparseBooleanArray;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;

public class ListView03 extends Activity implements OnItemClickListener{

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);

  // ListViewで表示するデータを作成
  for (int i = 0; i < mWords.length; i++) {
    mWords[i] = String.valueOf(i);
  }

  // リストアダプタを作成
  ArrayAdapter<String> adapter = new ArrayAdapter<String>(
    this,
    android.R.layout.simple_list_item_multiple_choice,
    mWords);

  // リストアダプタをリストビューにセット
  mListView = (ListView) findViewById(R.id.listview);
  mListView.setAdapter(adapter);

  // ListView内部のViewがフォーカス出来ないようにする
  mListView.setItemsCanFocus(false);

  // 複数選択可能にする
  mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);

  // クリックイベントを取得
  mListView.setOnItemClickListener(this);
 }

 @Override
 public void onItemClick(
   AdapterView<?> parent,
   View view,
   int position,
   long id) {

  // 選択状態を取得する
  SparseBooleanArray checked = mListView.getCheckedItemPositions();

  // 選択された要素をトーストで表示
  String word = "";
  for (int i = 0; i < mWords.length; i++) {
   word += mWords[i] +
     ":" +
     checked.get(i) +
     System.getProperty("line.separator");
  }
  Toast.makeText(this, word, Toast.LENGTH_LONG).show();
 }

 private ListView mListView;
 private String[] mWords = new String[10];
}
"res/layout/main.xml"のコードは以下の通り
<linearlayout
    android:layout_height="fill_parent"
    android:layout_width="fill_parent"
    android:orientation="vertical"
    xmlns:android="http://schemas.android.com/apk/res/android"
>
<listview
    android:id="@+id/listview"
    android:layout_height="fill_parent"
    android:layout_width="fill_parent"
    android:choicemode="multipleChoice"
>
</linearlayout>

AndroidManifest.xmlは割愛します(いつもと一緒だから。。。)。


リストをクリックするとToastが表示されます。
(チェックボックスが選択されているのがTrueになってます。)