「Androidアプリ」カテゴリーアーカイブ

Android application

Androidアプリ進展

なんでも一通りの経験を積まないと事が成功しないことは以前にも述べましたが、アプリ開発で今回も3日ほど悩んで解決した事柄を記します。位置情報を求めるべくLocationManagerがサポートするgetLastKnownLocationやrequestLocationUpdates関数を呼び出すところで実行時エラーが起きます。最初は何が何やら不明でしたがエラー発生箇所を特定し、上記関数で異常終了していることを突き止めました。 LOG-02 LogCatのログメッセージに AndroidRuntime(16524): FATAL EXCEPTION: main java.lang.SecurityException: Requires ACCESS_FINE_LOCATION permission の記述を見つけたので、permission指定が設定されていないことが原因と判明しました。多くの先駆者がデバイスアクセスを許可するため、AndroidManifest.xmlに <uses-permission android:name=”android.permission.ACCESS_FINE_LOCATION” /> のような指定をすべきと教えてくれます。一旦、プロジェクトを閉じてテキストエディタでXMLファイルを編集し、再びプロジェクトを開いてビルドしてもXMLの編集効果はありませんでした。編集はパッケージエクスプローラからAndroid.XMLを選び、追加-Uses Permission-Nameと指定し、右端の▼をクリックして許可名を選択します。 Manifest 要点はソースの修正などはテキストエディタでの変更が利くのに、XMLでは反映されないことがあるのでECLIPSEのツールによって修正したほうが無難ですということをお伝えします。

アンドロイドアプリのビルドエラー

アンドロイドアプリを開発中に、ビルドエラーが起きてエラー除去に四苦八苦することがあります。解決法は開発ツールのガイドメッセージやネット上に蓄積されているのでいつもお世話になっています。初心者にとって難解でもベテランには取るに足らないと思えるものは丹念に探しても回答が見つからないことがあります。

今回、2日ほどかけて解決に漕ぎ着けましたのでご報告いたします。このエラーは既存プロジェクト全体をコピーし、リネームして既存コードでプロジェクトの作成を試みるとき「Select at least one project」と出てプロジェクト作成できない現象です。

ProjectImport

上の例では、プロジェクトHelloAndroidWidgetをHelloAndroidWidget-01に複写を作り、プロジェクトを作ろうとしたときの症状です。コピーしたのだから名前が二重定義になっていると想定できるので、XML、JAVAファイルにある名前を一律に変更しても解決しません。

Project-1 「.PROJECT」の先頭部分 <?xml version=”1.0″ encoding=”UTF-8″?> <projectDescription> <name>HelloAndroidWidget</name>             ⇒ 変更する<name>HelloAndroidWidget-01</name>

プロジェクトのフォルダには、左に示す.projectファイルがあるので<name>タグのプロジェクト名を変更して、ファイル-新規-プロジェクト-既存コードからのAndroidプロジェクト-次へと指定してプロジェクトのインポートを実行します。これで「Select at least one project」のエラーは解決に向かうでしょう。

検索で数々の問題を解決してきました。1つお返しできましたが、まだまだ9999件ほどの借りがあるようだからがんばります。

スマホアプリ開発の難渋

スマートフォンのアプリ開発をしています。今までパソコンのシステム開発を長年、経験してきました。ここにきてスマホに宗旨替えしましたが、オブジェクト指向といいますか短いコードで盛りたくさんの処理をこなすことができます。主たる機能はAPI(Application Programming Interface)やライブラリ(Library)が担っていますが、きめ細かい処理はネイティブ処理に依存するようです。 Windowsプログラミングでは、ハードウェア制御処理、セキュリティに依存する処理はカーネルソフトウェアが担当します。この部分はコンピュータメーカーや端末機器メーカーが開発するのでユーザーが心配することはありませんでした。スマートフォンではこのあたりの境目がはっきりしないように思えます。カーネルソフトウェアに類する部分はネイティブ処理として組み込むことになります。よりよい機能を引き出すためにネイティブ処理を追いかけています。日経ソフトウェア2013年2月号、「Androidネイティブアプリ開発教室」などを手ほどきにボチボチ始めます。 蛇足:目より(耳より)な情報Androidとは ネットを検索していたら、120ページほどのアンドロイド初心者向け解説書を見つけました。東日本大震災からの復旧・復興を担う専門人材育成支援事業の一環として文部科学省から委託されたプロジェクトのようです。アンドロイド技術講座から無料で購読できます。読みやすく理解しやすいと感じましたので紹介します。

Androidアプリ開発環境構築4たび

4度目のAndroidアプリ開発環境構築です。コンピュータの世界は常に変動しています。2ヵ月半ほど開発ツールに触ってなかったら動作がおかしくなりました。この症状は多くの方が経験していて、AddInモジュールの同期が問題のようです。アドインツールを改訂しているときにエラーが起き、ニッチもサッチもいかなくなり、新規インストールすることにしました。前回同様、開発環境構築手順のあらましを示します。

1)ECLIPSEをインストールする
ECLIPSEの原本は英語版です。そのため、開発言語毎にまとめられたeclipse本体(日本語化済み)と幾つかのプラグイン群のセットのPleiades All in Oneをインストールします。http://mergedoc.sourceforge.jp/から以下の画面を表示させ、矢印で示した

PLEIADES4-2-2

「Pleiades All in One4.2.2a.v20130303(Eclipse4.2.2a SR2a Juno for Windowsベース)」の32ビット、Standard Edition、Ultimateを指定してダウンロードします。圧縮ファイルPleiades-e4.2-ultimate-32bit_20130303.zipを解凍して、PleiadesフォルダをAndroidツールフォルダにコピーします。

2)JDK(Java SE Development kit 7 update 17開発キット)のインストール
Javaアプリのライブラリやコンパイラが同梱されている「JDK」をダウンロードしてインストールします。ダウンロードしたjdk-7u17-windows-i586.exeを実行します。2013-05-26追記、17は21に改訂されています。

3)SDKのインストール
Androidアプリのライブラリやエミュレータなどを同梱した「Android SDK」をダウンロードしてインストールします。android-sdk_r21.1-windows.zipを解凍して「android-sdk-windows」フォルダをPleiadesフォルダにコピーします。2013-05-26追記、21.1は22に改訂されています。

4)ADT Pluginのインストール
ECLIPSE.exeを起動してAndroid SDKの各ソフトを使えるようにする「ADT Plugin」をインストールします。ヘルプ-新規インストール-追加-作業対象に https://dl-ssl.google.com/android/eclipse/の後、OKと入力し追加、すべて選択、次へ、次へ、使用条件の条項に同意します、完了と指定します。操作の切れ目で多少の時間がかかります。

5)細部の設定
Android SDKマネージャーとAndroid仮想デバイス・マネージャーにて、デバッグする機種の設定などを行います。

以上でおおまかな環境が整います。不足の場合はその都度、追加が可能です。

電子式ふくびき管理ソフト

買い物は多くの人々にとって楽しみです。ポイントカードや福引き抽選会はそれを助長しています。このたび、経営者、運営者側からみたアンドロイドスマートフォン向けの電子式福引き管理ソフトを開発しました。福引きはガラガラ、がらがらポンなどとも呼ばれ一定以上の買い物をした顧客にくじを引く権利を与え、抽選結果に応じた景品を配布して店の販売促進を図るものです。

FUKU-3

福引き抽選器は六角形あるいは八角形の箱に3~7種類の色から成る玉を入れ、ガラガラと回転させ飛び出た玉の色で当選の当たり外れを決する機器です。抽選の規模により数種の玉サイズがあって500,1000,2500,4000玉用に専門店から調達することができます。 ガラガラと抽選器を回すときのワクワク感は格別のものがあります。

特等賞が当たった場合は派手な音楽が欲しいところです。抽選会は商店街の組織単位だったり、一社単独だったりします。連合体の場合は、協賛の店名表示が欲しい感じです。また、抽選客が途切れた時には、キャンペーンメッセージが流れにぎわいを盛り上げたいものです。

これらのニーズに答えるべく、スマートフォン向け福引き管理ソフトを開発し、Google Playに無料で公開しました。スマートフォンは小さく、パソコンが現実的と思われますが、これからはスマホの伸びしろが見込まれますし、タブレットタイプのスマホは大きなサイズのものが揃っているのでスマートフォン向けを開発しました。くじの設定やくじを引く操作はすべて画面タッチによって行われます。

スマホでGoogle Playを起動し、アプリ-福引き管理ソフトで検索しaidesignと表示された福引きソフトをダウンロードして実行してください。特賞~五等賞の6区分のくじを引くことができます。デフォルトのくじ数を以下に示しますが「くじ設定」で自在に設定できます。「くじ設定」と「表示」は管理者権限を取得しないと実行できません。画面に表示されたヒントにしたがって管理者権限を取得します。

①    特賞 ………1
②    一等賞….…3
③    二等賞….…10
④    三等賞…….20
⑤    四等賞…….100
⑥    五等賞…….366

くじを引くには主メニューの「スタート」にタッチします。抽選器は回り始めるので特賞を念じころあいをはかって「ストップ」を押してくじを特定します。特賞と一等賞のときは長めのメッセージが、他は短いメッセージが流れます。5秒以内にストップを押さないと抽選は取り消されます。ペナルティはありませんので再挑戦できます。

このアプリケーションを終了させるにはBackKeyを押します。 ダウンロードは無料ですので、ご利用後のコメントをいだけたら幸いです。このソフトは試作版であり、管理者権限を得る時、鍵のあり場を教えているようなものですが本番ではまっさきに改訂されるべき項目でしょう。ご意見をお願い申し上げます。

アプリづくりの準備

・アプリづくりの初歩の初歩

アプリ開発について、初歩者でも開発環境を整えれば、サンプルコードを基準に動作までこぎつけられることを複数回にわたって公開してきました。今回は、開発環境を整える以前のお話です。園芸や工作はあまり得意ではありません。事を進めるにあたってシステム開発者として長年携わってきたソフトウェア開発に的を絞ります。具体的には、アンドロイドアプリを開発する手順について話を進めます。

1)予備知識を吸収する

風呂の椅子を作る場合、市販品や日曜大工クラブの作品を見たりします。木材、釘、金づちや道具袋の予備知識を吸収します。アンドロイドアプリを開発するにはどのような準備をすればよいか、予算はいくらかかるかに興味が絞られます。ANDROIDアプリはスマホやタブレットPCで動作するので実機があれば良いのだが、スマートフォンの実行をPC上で代行してくれるエミュレータがあり、とりあえずWindowsパソコン(PC)があれば十分です。OSはWindows7か8が望ましいです。WindowsXPでも問題ありませんが、新しいプラグインツールは古いOSになじまなくなっています。スマホのように自らのシステム開発環境を整えることができない場合、他の機器でシステム開発することをクロス開発と言います。セルフ開発の用語はほとんど使われません。

コンピュータミシンの場合も同様でパソコン上でソフトウェアを開発し、右図のようなROMに焼き付けてミシンに実装します。スマホではWindowsパソコンで開発したプログラムコードをUSBケーブルやLANを使って転送して実装します。上でプラグインという用語がすでに使われているようにパソコンをシステム開発ツールの要として利用するので、一般のパソコン利用者よりもパソコンに精通することが大切です。 予備知識としてクロス開発のほか、コンパイル、ビルド、機械語、高級言語、JAVA、プログラム、ライブラリなどの用語について理解されることが望ましいといえます。

・なぜアンドロイドなのか

スマートフォンにはiOS(アップル)とAndroid(Google)の2大OSがあります。アップル社のiOSが先行していましたが最近はAndroidが追い上げています。どちらを採用するかは好みもありますが、伸びしろが見込める後者を選びました。MaccintosshとIBM PCの時に似ているのですが、規格や回路図を公開したIBM PCが世界標準機となったことは広く知られています。iPHONE用ツールは有償ですが、アンドロイド系は開発ツールや規格などを無料で公開しており新規参入障壁は高くありません。OS別にビジネスモデルを比較を参照。

2)道具を準備する

ものを作るには道具を揃えなければなりません。霊長類で道具を使うのは人間だけと言われていましたが、チンパンジーがくぼみのある石にくるみを置いて石で割っている映像を放映していましたので、定説は覆されたのでしょう。アプリを開発するための道具は、テキストエディタ、コンパイラ、ライブラリ、デバッガ、エミュレータなどです。これらは統合開発ソフトなどとひとくくりにして呼ばれることがあります。かなり前はこれらのツールは数十万円する高価なものであり、開発を生業にする技術者しか目にすることができませんでした。現在は、すべてが無料で手に入れることができ、多くの人々がアプリケーション開発に参加できるようになりました。

アンドロイドアプリ開発に要する道具についてはこれまで何度も語っていますので、そちら(Androidアプリ開発環境構築、再び)を参照してください。

3)先人の作品を探求する

赤ん坊は親の真似をして知識を深めていきます。芸術も大御所の作品から多くの基礎を学びます。文化が進むほど学問は体系づけられてきました。昔は著作権を尊重する風土になく、秘密主義で先人のワザは簡単に伝承されませんでした。ごく限られた人に秘伝書が与えられノウハウが伝えられました。

今は、先達者の高度技術に触れることができます。先達の作品を鑑賞、解析、分析することによって自己の血肉にします。では鑑賞力、解析力を養うにはどうするのかということになりますが、まずは優れた技術に触れることから始まります。

4)先人の作品を模倣して作る

インターネットの普及で、有益なサンプル作品を目にすることができます。その多くは無料であり、営利目的に利用しなれば自由に使うことができます。どれが有用であるかの眼力が必要ですが徐々に目は肥えてきます。そして先人の作品そっくりに模倣して作ってみます。絵画においても大家の作品を眺めて模写することから始まります。

5)オリジナル作品を開発する

アプリ開発においても多くの先達者が、書籍やブログを通して優れた作品を発表しており、それらを手にして同様の結果が得られたのちに、まず簡単なオリジナル作品を開発してみましょう。Hello Worldを表示するものでも構いません。簡単なものを数多く手の内に入れ引き出しの中が満杯になるように頑張りましょう。 技量が向上し引き出しにものが溢れ出したら、高度な機能を有するアプリケーション開発に挑戦しましょう。

あみだくじ作成法

初歩からスタートするAndroidアプリ開発

目次

(1)あみだくじとは
(2)あみだくじの作り方
(3)画面設計と処理手順
(4)プログラムの設計とデザイン
(5)あみだくじ描画法
(6)音声出力
(7)実行結果
(8)SourceCode
(9)ファイル一覧
(10)プロジェクト全ファイル
(11)感想・概評
(12)関連情報

本文

以前にC言語であみだくじ作成法の一部を発表しましたが、ANDROID用に作り直しました。くじを作るところから始めます。以前にあみだくじ作成法を公開すると述べたことへの回答でもあります。 

(1)あみだくじとは

あみだくじを初めて体験される方のために、少し解説します。少人数(3~12人ほど)の仲間うちでくじをランダムに作って参加者全員、くじを引き当番人や当選者を決めるやりかたです。くじを作る場合、誰もがくじに手を加えることができ不正が起きないように配慮されます。コンピュータ処理では、乱数などを用いて不正への対策に当てます。

(2)あみだくじの作り方

紙やホワイトボードであみだくじを作る方法を吟味します。ここでは便宜上、6人の参加者の場合を述べます。


1)参加者ぶん6本の縦線を引きます。
2)縦線と縦線の間(枠内)に、間隔4~9で4本ほどの横線を引きます。
3)それを全枠内で実行します。
4)隣どおしで横線の縦位置が同じになることを避けます。
5)くじを引く人は0~5の任意の番号を一意的に確保し引当てます。
6)引いたくじの番号を決めるには各々、上から下に線をたどります。
7)三叉路に出会ったら右、左、下に進み、終点まで繰り返します。
8)終点に宝物やミッション指示書があれば、当選者になります。
9)上のくじでは当選者は2番者になります。

上記の処理をアルゴリズムに反映させます。
1)上図に示すように6×36のマトリックスを作ります。10人参加なら10x36になります。
2)マトリックス(node[x][y])の要素をすべてゼロクリアします。x:0~5,y:0~35。
3)node[x][y]のうち、左端のx=0を除きx:1~5で、横線用のポイントを決定します。
4)乱数を順に4箇発生させ、その値を縦位置に設定します。
5)間隔は4~9、左隣と同じ値を避けます。
6)縦位置の値が36以上になったら4回発生させる前に終了します。
7)乱数は時間データを種にして再現性と人為的な関与を排除します。
8)node[x][y]=2,node[x-1][y]=1に設定します。1は横線の始まり、2は終点です。
9)上記のあみだくじでは右図のnodeテーブル設定値になります。

(3)画面設計と処理手順

画面設計は参加者の入力とくじの表示並びに当選者の決定処理です。参加者名を入力して締切り後、参加者の人数に問題がなければあみだくじを表示する次のアクティビティに歩を進めます。

(4)プログラムの設計とデザイン

■プログラムの設計

前回に使ったインテントを今回も使用します。参加者の入力画面からくじ表示と当選者の決定画面を起動するために使います。

■画面設計

関数getResources()とgetConfiguration()を使って、スマートフォンの向きを検出して自動的に縦型、横型用画面が制御されます。
1)縦型画面

2)横型画面

■主なプログラムのモジュール構成

・delay.java           ディレー関数
・FirstActivity.java   参加者入力画面
・SecondActivity.jav   あみだくじ表示画面
(5)あみだくじ描画法

あみだくじを描画するには、あみだくじの作り方をプログラムに表現すべく、具体的に以下に示します。

1)参加者ぶん、ここではxが0から順に5まで繰り返します。
2)縦方向に0から35まで36行あり、順に描画対象かを確認します。
3)2次元配列のnodeの値は0が多く、他は1か2です。
4)1つのxに対し上から順に検索し、0以外が現れたら横線を引きます。
5)値が1ならば右に、2ならば左に向かって引きます。
6)横線はCanvasオブジェクトのdrawLinesを使用します。
7)次に、検索した値により探索地点を1加算(減算)して右(左)に移動します。
8)yは加算され終端(35)に達するまで繰り返します。
9)一人のくじを引き終り、宝物や地雷があれば、当選者に対する処理をします。
10)xを加算して次の人のくじを描画します。
11)最後の参加者の処理が終えたら終了です。

(6)音声出力

処理の切れ目やエラー発生、くじが三叉路を通過するときに音声が出力されます。C言語のBeep関数がなく、あらかじめ音声ファイルを読み込んで音データを用意して置かなければなりません。SoundPoolオブジェクトを利用し、サウンドファイルを読み込み音声を再生します。音声における書式付きprint関数のような機能はまだマスターできてないので、当選者をアナウンスするために10人ぶんの10個のファイルをあらかじめ用意しています。

(7)実行結果

(8)SourceCode

ソースコードを以下に示します。
1.delay

package example.android.kuji;

public class delay {
	public static void time(int millis)
	{
		try
		{
			Thread.sleep(millis);
		}
		catch(InterruptedException e){System.out.println(&quot;delay failed&quot;);}
	}
}

2.FirstActivity.java

package example.android.kuji;

import android.app.Activity;
import android.content.Intent;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.Bundle;
import android.text.Editable;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;

class gv{											/** global variable **/
	public static SoundPool sound;					// SoundPool
	public static int Si0;							// ちょうはんコマ…
	public static int Si1;							// 乱数を発生させ…
	public static int Si2;							// pyon
	public static int Si3;							// bororo
	public static int Idx[]={0,0,0,0,0,0,0,0,0,0};	// no0~no9
}

public class FirstActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState){// onCreateメソッド(画面初期表示イベントハンドラ)
        super.onCreate(savedInstanceState);			// スーパークラスのonCreateメソッド呼び出し
        setContentView(R.layout.firstlayout);		// レイアウト設定ファイルの指定

		Button button = (Button) findViewById(R.id.button1);// ボタンオブジェクト取得
		button.setOnClickListener(new LotteryListener());// ボタンオブジェクトにクリックリスナー設定
	}

	@Override
	public void onResume() {
		super.onResume();
		gv.sound = new SoundPool(2, AudioManager.STREAM_MUSIC, 0);
		gv.Si0 = gv.sound.load(this, R.raw.chohan, 1);
		gv.Si1 = gv.sound.load(this, R.raw.ransuu, 1);
		gv.Si2 = gv.sound.load(this, R.raw.pyon, 1);
		gv.Si3 = gv.sound.load(this, R.raw.bororo, 1);
		gv.Idx[0] = gv.sound.load(this, R.raw.no0, 1);
		gv.Idx[1] = gv.sound.load(this, R.raw.no1, 1);
		gv.Idx[2] = gv.sound.load(this, R.raw.no2, 1);
		gv.Idx[3] = gv.sound.load(this, R.raw.no3, 1);
		gv.Idx[4] = gv.sound.load(this, R.raw.no4, 1);
		gv.Idx[5] = gv.sound.load(this, R.raw.no5, 1);
		gv.Idx[6] = gv.sound.load(this, R.raw.no6, 1);
		gv.Idx[7] = gv.sound.load(this, R.raw.no7, 1);
		gv.Idx[8] = gv.sound.load(this, R.raw.no8, 1);
		gv.Idx[9] = gv.sound.load(this, R.raw.no9, 1);
    }

    // クリックリスナー定義
    class LotteryListener implements OnClickListener {
        // onClickメソッド(ボタンクリック時イベントハンドラ)
		public void onClick(View vw) {
			Log.v(&quot;FirstActivity &quot;,&quot;v.fortune=&quot; + v.fortune+&quot; v.LineCount=&quot; + v.LineCount);
			if(v.fortune == 99)	{								// SecondActivityが実行されている。
				v.fortune = 0;									// reset fortune
				gv.sound.play(gv.Si3, 1.0f, 1.0f, 0, 0, 1.0f);	// S bororo
				delay.time(1000);
				System.exit(0);
			}
			// テキストボックスオブジェクト取得
			EditText input = (EditText) findViewById(R.id.nametext);
			Editable str = input.getText();
			String string = str.toString();
			// 入力情報をトースト機能で画面表示

            // インテントの生成(呼び出すクラスの指定)
			Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
            // 選択された値をインテントに設定
            intent.putExtra(&quot;PARTY_MEMBER&quot;, string);
			//Log.v(&quot;tag_name&quot;, &quot;go new screen.&quot;);
            // 次のアクティビティの起動
            startActivity(intent);
        }
    }

	public boolean onKeyDown(int keyCode, KeyEvent event){	// Back-key
		Log.v(&quot;FirstActivity-onKeyDown&quot;, &quot;fortune=&quot;+v.fortune+&quot; KeyCode=&quot;+keyCode);
		if(keyCode == KeyEvent.KEYCODE_BACK)	v.fortune = 0;	// reset fortune
		return super.onKeyDown(keyCode, event);
	}
}

3.SecondActivity.java

package example.android.kuji;		// Amida.java ---&gt; Kuji.java

import java.util.Random;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.os.Bundle;
import android.util.Log;
import android.view.View;

class v{							/** global variable **/
	public static int index=2;		// side, vertical
	public static int x=5;			// position-x
	public static int y=450;		// position-y
    public static int LineCount=0;	// party_member
    public static String string;	// input data
	public static int fortune=0;	// fortune-number
	public static int i=0;			// menber/-id
	public static int end=-1;		// end-text
 	public static int node[][]= {	// random-value, 10*46
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},// 0
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},// 1
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},// 2
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},// 3
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},// 4
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},// 5
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},// 6
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},// 7
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},// 8
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} // 9
								};
	public static int co[]={Color.YELLOW , Color.BLUE , Color.CYAN , Color.DKGRAY ,	Color.GRAY ,
							Color.GREEN , Color.LTGRAY , Color.MAGENTA , Color.RED , Color.BLACK};
}

// MainClass
public class SecondActivity extends Activity {
    /** Called when the activity is first created. **/
    @Override
    public void onCreate(Bundle savedInstanceState) {	// ??????????
        super.onCreate(savedInstanceState);
		// make instance of ViewClass.
		MyCircleView view = new MyCircleView(getApplication());
        setContentView(view);					// set View.

		Log.v(&quot;SecondActivity&quot;, &quot;LineCount=&quot; + v.LineCount);
		// calc party-member.
        Intent data = getIntent();
        // get additinal info of intent;
        Bundle extras = data.getExtras();
        // get party-member from input-data.
        v.string = extras.getString(&quot;PARTY_MEMBER&quot;);

		Resources resources = getResources();	// screen direction
		Configuration config = resources.getConfiguration();
		v.index=2; v.x = 5; v.y = 450;
		v.LineCount = 0; v.i = 0;

		switch(config.orientation) {
		case Configuration.ORIENTATION_PORTRAIT:
			v.index = 0;
			break;
		case Configuration.ORIENTATION_LANDSCAPE:
			v.index = 1; v.x = 500; v.y = 20;
			break;
		}

		int end = -1;							// line of input.

		for(int i=0; i			int top = end + 1;
			int wrk = v.string.indexOf('\n', top);
			if(wrk == -1)	break;
			end = wrk;
			++v.LineCount;
		}
		v.fortune = 99;									// for abnormal-finish
		Log.v(&quot;SecondActivity&quot;, &quot;LineCount:&quot; + v.LineCount+&quot; Fortune=&quot;+v.fortune);
		if((v.LineCount &lt; 3) || (v.LineCount &gt; 10)){
			gv.sound.play(gv.Si3, 1.0f, 1.0f, 0, 0, 1.0f);	// S bororo
			delay.time(1000);
			System.exit(1);/*return;finish();*/
		}

		long seed = System.currentTimeMillis();			// current-time, milisecond
 		Random rnd = new Random(seed);
        v.fortune = rnd.nextInt(v.LineCount);			// random:0~(v.LineCount-1)

		for(int i=0; i			for(int j=0; j		}

		int k=0;										// yoko-line:4
/* gen */for(int i=1; i			int d=0;									// d:0~45, 46
			for(int j=0; j= 46)	{k=1;break;}				// finish,yoko-line:3
				if(v.node[i-1][d]==2){					// if equal, alert.
					d += 4;
					if(d &gt;= 46)	{k=1;break;}			// finish,yoko-line:3
					if(v.node[i-1][d]==2){
						++d;							// if equal, alert.
						if(d &gt;= 46)	{k=1;break;}		// finish,yoko-line:3
					}
				}
				//Log.v(&quot;SecondActivity-3&quot;, &quot;i=&quot;+i+&quot;j=&quot;+j+&quot;d=&quot;+d);
				v.node[i-1][d]=1;						// start
				v.node[i][d]=2;							// end
			}
/* gen */}												// -------------------
		if(k==0)	k = gv.Si1;							// ransuu
		else		k = gv.Si0;							// chohan
		gv.sound.play(k, 1.0f, 1.0f, 0, 0, 1.0f);		// L biyoon
		delay.time(2800);
    }													// ??????????
}

// display class
class MyCircleView extends View {						// View
	public MyCircleView(Context context) {				// initialize View
		super(context);
		setFocusable(true);
	}

/**/protected void onDraw(Canvas canvas) {				// actualy,method of display.
		Paint paint = new Paint();						// make paint-object
		super.onDraw(canvas);
		canvas.drawColor(Color.WHITE);					// set back-color.

		for(int i=0; i			int x=i*50+8;								// x-position
			float[] pts1 = {x+7, 25, x+7, 346};			// 2.vertical line
			canvas.drawLines(pts1, paint);				// basic line

			if(i != (v.LineCount-1)){					// ##########
			  for(int j=0; j				if(v.node[i][j]==1){					// amida-yoko
					float[] pts0 = {x+7, j*7+25, x+57, j*7+25};	// yoko
					canvas.drawLines(pts0, paint);		// yoko line
				}
			  }
			}											// ##########
		}												// display basic form.

		paint.setStrokeWidth(4.0f);						// line's thickness
	  if(v.i == v.LineCount){							// draw amida-line.
		for(v.i=0; v.i			display(gv.Si2, paint, canvas);				// pyon, all
		}												// final-proc

		int end = -1;									// display member-name
		paint.setColor(Color.BLACK);					// black line
		paint.setTextSize(24);							// member name
		paint.setTypeface(Typeface.DEFAULT_BOLD);		// thin

		for(int i=0; i			paint.setColor(v.co[i]);					// COLOR
			int x=i*50+8;								// display character
			int top = end + 1;
			end = v.string.indexOf('\n', top);
			String s = v.string.substring(top, end);	// MEMBER-NAME
			canvas.drawText(i + &quot;:&quot; + s, v.x+20, v.y+i*25+25, paint);

			String str = String.valueOf(i);				// 0 1 2 3 4 5 6
			if(i == v.fortune){
				Log.v(&quot;SecondActivity&quot;, &quot;i=&quot; + i+&quot; Fortune=&quot;+v.fortune);
				StringBuffer sb = new StringBuffer(str);
				str = sb.reverse().toString();
			}
			canvas.drawText(str, x, 20, paint);
		}
		paint.setColor(v.co[5]);						// GREEN
		canvas.drawText(&quot;笘&quot;, v.x, v.y+v.end*25+25, paint);	// atari

		paint.setTextSize(20);							// make display-object.
		paint.setColor(Color.MAGENTA);					// display party_member
		canvas.drawText(&quot;蜿ょ刈閠・・&quot; + v.LineCount + &quot;莠コ縺ァ縺吶€&quot;,v.x, v.y, paint);

		gv.sound.play(gv.Idx[v.end], 1.0f, 1.0f, 0, 0, 1.0f);	// s no0
		delay.time(250);
		paint.setTextSize(24);							// lucky mark
		paint.setColor(v.co[5]);						// GREEN
		canvas.drawText(&quot;笘&quot;, v.fortune*50+2, 395, paint);	// atari
		paint.setColor(Color.BLUE);						// announce lucky-man.
		canvas.drawText(&quot;蠖馴∈閠・・&quot;+v.end+&quot;逡ェ縺ァ縺吶€&quot;, 5, 417, paint);
		v.fortune = 99;									// if you down back-key, v.fortune=0.
		v.i = 0;
		return;		/*System.exit(0);*/
	  }
	  else{												// 0~(v.LineCount-1)
		display(gv.Si2, paint, canvas);					// pyon
		++v.i;
	  }
		invalidate();									// repeat
/**/}

	private void display(int si2, Paint paint, Canvas canvas) {		// draw a kuji.
			gv.sound.play(si2, 1.0f, 1.0f, 0, 0, 1.0f);	// s pyon
			delay.time(500);

			int y=0;
			int x=v.i;

			paint.setColor(v.co[v.i]);					// COLOR
			for(int j=0; j yoko
				if(v.node[x][j]&gt;0){
					float[] pts1 = {x*50+15, y*7+25, x*50+15, j*7+25};	// tate
					canvas.drawLines(pts1, paint);		// tate line

					y=j;
					int d=x;
					if(v.node[x][j]==1)	++x;
					else				--x;
					float[] pts2 = {d*50+15, j*7+25, x*50+15, j*7+25};	// yoko
					canvas.drawLines(pts2, paint);		// yoko line
				}
			}
			float[] pts1 = {x*50+15, y*7+25, x*50+15, 46*7+24};	// tate
			canvas.drawLines(pts1, paint);				// tate line

			paint.setTextSize(20);						// make display-object.
			String str = String.valueOf(v.i);			// 6 5 4 3 2 1 0
			canvas.drawText(str, x*50+8, 372, paint);
			if(x==v.fortune)	v.end = v.i;			// save forune-number
	}
}														// View
(9)ファイル一覧

ファイル一覧を階層構造形式に示します。音声ファイルがres\rawフォルダに収納されていることに注目ください。

.\AMIDAKUJI
│  .classpath
│  .project
│  amidakuji.apk
│  AndroidManifest.xml
│  default.properties
│  lint.xml
│  proguard.cfg
│  project.properties
│
├─assets
├─bin
│  │  AndroidManifest.xml
│  │  classes.dex
│  │  example.android.kuji.FirstActivity.apk
│  │  resources.ap_
│  │
│  ├─classes
│  │  └─example
│  │      └─android
│  │          └─kuji
│  │                  BuildConfig.class
│  │                  delay.class
│  │                  FirstActivity$LotteryListener.class
│  │                  FirstActivity.class
│  │                  gv.class
│  │                  MyCircleView.class
│  │                  R$array.class
│  │                  R$attr.class
│  │                  R$drawable.class
│  │                  R$id.class
│  │                  R$layout.class
│  │                  R$raw.class
│  │                  R$string.class
│  │                  R.class
│  │                  SecondActivity.class
│  │                  v.class
│  │
│  └─res
│      ├─drawable-hdpi
│      │      icon.png
│      │
│      ├─drawable-ldpi
│      │      icon.png
│      │
│      ├─drawable-mdpi
│      │      icon.png
│      │
│      └─drawable-xhdpi
│              icon.png
│
├─gen
│  └─example
│      └─android
│          └─kuji
│                  BuildConfig.java
│                  R.java
│
├─res
│  ├─drawable
│  ├─drawable-hdpi
│  │      icon.png
│  │
│  ├─drawable-ldpi
│  │      icon.png
│  │
│  ├─drawable-mdpi
│  │      icon.png
│  │
│  ├─drawable-xhdpi
│  │      icon.png
│  │
│  ├─layout
│  │      firstlayout.xml
│  │      main.xml
│  │      secondlayout.xml
│  │
│  ├─raw
│  │      bororo.wav
│  │      buin.wav
│  │      chohan.wav
│  │      no0.wav
│  │      no1.wav
│  │      no2.wav
│  │      no3.wav
│  │      no4.wav
│  │      no5.wav
│  │      no6.wav
│  │      no7.wav
│  │      no8.wav
│  │      no9.wav
│  │      pyon.wav
│  │      ransuu.wav
│  │
│  └─values
│          strings.xml
│
└─src
    └─example
        └─android
            └─kuji
                    delay.java
                    FirstActivity.java
                    SecondActivity.java
(10)プロジェクト

プロジェクト内の全ファイルをZIP形式で一挙、公開です。 AmidaKuji.ZIP

(11)感想・概評

1.あみだくじは遊び心で始まります。ひとりで全員のかばん6個を運ぶなど、仲間うちで負荷の大きい使役などは避けましょう。
2.のやっかいになるようなトトカルチョっぽいものもやめましょう。
3.あみだくじは、ひとりの当たり人を決める場合が多いのですが、冒頭の芋煮会準備くじにあるように多対多の対応づけに応用でき、ホテルの部屋割り、宴会の席順設定にも使えます。
4.あみだくじを記録するには、結果をファイル化してください。
5.あみだくじは、結果よりも途中のワクワク感を楽しむものです。このページを土台にしてビジュアル的に改良して楽しんでください。
6.くふうすれば、プロ野球ドラフト会議で競合者があった場合に、交渉権を決定するくじ引きに採用されるかも知れません。
7.あみだくじの参加者名を入力し終えて、「締め切り!」を押すと「乱数を発生させあみだくじ作成中です」がアナウンスされますが、稀に妙なメッセージが出力されことがありますが、これは開発者の遊び心です。ソースコードを詳しく眺めると出力条件がわかります。
8.javaはCと違ってstatic変数が初期化されず前回に実行されたメモリに残っている状態になり、Cから移植した場合に悩みの種となるようです。
9.今回の公開は「あみだくじ作成法」です。完成品ではありません。ご利用には利用規定をお読みください。
10.画面上の制限からテーブルサイズなど、解説した内容と実際のソースコードは異なっています。
11.くじ参加者名を全角文字で入力する代わりにアルファベットで、N,SA,A,SU,Yなどと入力する方法があります。
12.くじ運営者は最後に残ったものを引き当てた方が公平でしょう。
13.この作成手法を用いたあみだくじアプリを開発してGoogle Playに公開します。

2014-05-14追記

Google Playに以下の3点を出品しています。
①あみだくじ
②抽選機
③福引き管理ソフト

(12)関連情報

C,Java,JavaScriptによるあみだくじや福引きソフトの作り方をまとめてあります。
※※※※※

 

スマホで日付から曜日の算出

・初歩からスタートするAndroidアプリ開発

目次

(1)概要 (2)演算式 (3)サポート範囲 (4)画面設計と処理手順 (5)プログラミング構想 (6)入力値チェック処理 (7)eclipseパッケージ・エクスプローラーの起動 (8)ブロック構造 (9)SourceCode (10)実行結果 (11)ファイル一覧 (12)全プロジェクトファイル (13)感想・概評

本文

(1)概要 ツェラーの公式(Zeller’s congruence)を用いて西暦の年、月、日からその日が何曜日であるかを算出するANDROIDアプリケーションを開発します。ツェラーの公式は専門のフォーラムが存在するくらいに研究が盛んです。C言語の庵で述べましたが、技術月刊誌bitに記載された式を使います。 上左図は干支一覧です。エトは十干と十二支を組み合わせた60(10と12の最小公倍数)を周期としています。女の子を思う親心のため、出生率が下がる丙午(ひのえうま)は60年に一度、巡ってきます。 演算はガウス関数とモジュロ関数を必要としますが整数扱いと剰余演算子(%)を用いて表現すれば次の式になります。y:年,m:月,d:日とすれば、lに火曜日を0とする曜日が求まります。 (2)演算式 l = y + (m – 8) / 6; l = ((5 + (m + 9) % 12 * 26) / 10 + (l * 5) / 4 – l / 100 + l / 400 + d) % 7; // 0:火,1:水,2:木,3:金,4:土,5:日,6:月 (3)サポート範囲 グレゴリオ暦における日付から曜日を求めます。よってサポートする日付は1582年10月15日以降です。 (4)画面設計と処理手順 (5)プログラミング構想 このサイトではJavaの文法などにいっさい触れることなく、サンプルコードが実際に希望どおり実行できたことにより少しずつ先に進む方式です。しかしながら最低限のJavaの文法とガウス、モジュロなどの数学用語を理解する必要があります。今回はインテントを使用します。インテントは「意図、目的」などの意味があり、次のサービスを起動するために使用します。インテントは入力画面から表示画面を起動するために使います。インテントを手の内に入れましょう。 (6)入力値チェック処理 入力された日付が有効かどうかのチェック処理を以下に示します。入力日付は1582年10月15日以降をサポートし、うるう年かどうかを確認し月や日の有効性を調べます。 (7)eclipseパッケージ・エクスプローラーの起動 eclipseを起動するとパッケージ・エクスプローラーが現れるので、プロジェクトに関する様々なデータを作成しますが、何かの拍子にパッケージ・エクスプローラー画面が消えることがあります。赤矢印で示したボタンをクリックすれば、右のパッケージ・エクスプローラー画面が現れます。そのボタンさえ消えてしまったら、[ウィンドウ]-[ビューの表示]-[パッケージ・エクスプローラー]と指定して再び現れます。 (8)ブロック構造 文や画像などを表現するHTMLやC,JAVA言語ではブロック(塊まり)単位で表現されます。表現の基本はブロックやタグです。ブロックとタグに注目するとプログラミングや意志の伝達に役立ちます。ブロックは入れ子(ネスト)になることが多いですが、絡み合うことはありません。ブロックには始まりと終わりがあり、特定の記号から始まります。 ①ブロック構造 ②ブロック表現法 ・{                } ・.begin       .end ・<pre>       </pre> ・<strong>  </strong> ・<head>     </head> ・<title>       </title> ・<body>     </body> (9)SourceCode ・delay
package example.android.dayoftheweek;

public class delay {
 public static void time(int millis)
 {
 try
 {
 Thread.sleep(millis);
 }
 catch(InterruptedException e){System.out.println("delay failed");}
 }
}
・FirstActivity.java
package example.android.dayoftheweek;	// FirstActivity.java : 日付を入力し、正当性をチェックする

import android.app.Activity;
import android.content.Intent;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;

class gv{											/** global variable **/
	public static SoundPool sound;					// SoundPool
	public static int Si2;							// buin
	public static int Si3;							// bororo
	public static int day=0;						// yy-mm-dd
	public static int y;							// y
	public static int m;							// m
	public static int d;							// d
	public static int n;							// n
	public static int max[]={31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
	public static String[] week={"日","月","火","水","木","金","土"};
}

public class FirstActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState){// onCreateメソッド(画面初期表示イベントハンドラ)
        super.onCreate(savedInstanceState);			// スーパークラスのonCreateメソッド呼び出し
        setContentView(R.layout.firstlayout);		// レイアウト設定ファイルの指定

		Button button = (Button) findViewById(R.id.button1);// ボタンオブジェクト取得
		button.setOnClickListener(new LotteryListener());// ボタンオブジェクトにクリックリスナー設定
	}

	@Override
	public void onResume() {
		super.onResume();
		gv.sound = new SoundPool(2, AudioManager.STREAM_MUSIC, 0);
		gv.Si2 = gv.sound.load(this, R.raw.buin, 1);
		gv.Si3 = gv.sound.load(this, R.raw.bororo, 1);
    }

    // クリックリスナー定義
    class LotteryListener implements OnClickListener {
        // onClickメソッド(ボタンクリック時イベントハンドラ)
		public void onClick(View vw) {
			System.out.println("FirstActivity");
			// テキストボックスオブジェクト取得
			EditText input = (EditText) findViewById(R.id.nametext);
			String string = input.getText().toString();
			// 入力情報をトースト機能で画面表示
            //System.out.println("Number of itartion : " + string);
			try{
                gv.day = Integer.parseInt(string);
			}catch(NumberFormatException e){
				gv.sound.play(gv.Si3, 1.0f, 1.0f, 0, 0, 1.0f);	// bororo
 				System.out.println("数値でない値が入力されています");
				delay.time(1000);				// error
 				System.exit(0);					// プログラムを終了する
			}
			System.out.println("day = " + gv.day);

			gv.y = gv.day / 10000;				// 日付の正当性をチェックする
			gv.m = gv.day % 10000;				// 年、月、日を抽出する
			gv.d = gv.m % 100;
			gv.m /= 100;

			int normal = 0;						// errorありに設定
			gv.n = gv.y;
			if(gv.day >= 15821015){
				if(gv.y % 100 == 0)	gv.n = gv.y / 100;
				if(gv.n % 4 == 0)	gv.max[1] = 29;
				else				gv.max[1] = 28;

				if(gv.y >= 1582){
					gv.n = gv.m - 1;
					if((gv.n>=0) && (gv.n=1) && (gv.d・SecondActivity.java
 package example.android.dayoftheweek;	// SecondActivity.java : 日付から曜日を求め、表示する import android.app.Activity; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.os.Bundle; import android.util.Log; import android.view.View; // MainClass public class SecondActivity extends Activity {     /** Called when the activity is first created. **/     @Override     public void onCreate(Bundle savedInstanceState) {	// ??????????       super.onCreate(savedInstanceState); 	  // make instance of ViewClass. 	  MyCircleView view = new MyCircleView(getApplication()); 	  setContentView(view);								// set View. 	  Log.v("SecondActivity", "day=" + gv.day); 	  gv.n = gv.y + (gv.m - 8) / 6; 	  gv.n = ((5 + (gv.m + 9) % 12 * 26) / 10 + (gv.n * 5) / 4 - gv.n / 100 + gv.n / 400 + gv.d) % 7; 	  gv.n = (gv.n + 2) % 7;							// 0,1,2,3,4,5,6 -> 2,3,4,5,6,0,1
	  Log.v("SecondActivity", "n=" + gv.n);
    }													// ??????????
}

// display class
class MyCircleView extends View {						// View
	public MyCircleView(Context context) {				// initialize View
		super(context);
		setFocusable(true);
	}

/**/protected void onDraw(Canvas canvas) {				// actualy,method of display.
		Paint paint = new Paint();						// make paint-object
		super.onDraw(canvas);
		canvas.drawColor(Color.WHITE);					// set back-color.

		paint.setStrokeWidth(4.0f);						// line's thickness
		paint.setTextSize(20);							// lucky mark
		paint.setColor(Color.BLUE);						// announce lucky-man.
		canvas.drawText(gv.y+"蟷エ"+gv.m+"譛"+gv.d+"譌・縺ッ"+gv.week[gv.n]+"譖懈律縺ァ縺吶€", 10, 160, paint);
		gv.sound.play(gv.Si2, 1.0f, 1.0f, 0, 0, 1.0f);	// buin
		delay.time(1000);
		return;		/*System.exit(0);*/
/**/}
}														// End Of SecondActivity.java
(10)実行結果 (11)ファイル一覧 プロジェクト内のファイルを階層構造形式に表示します。 (12)全プロジェクトファイル 上記ファイル一覧DayOfTheWeekプロジェクト内の全ファイル(DayOfTheWeek.zip)を添付し一挙、全公開します。 DayOfTheWeek.ZIP (13)感想・概評 ①日付はハイフン、カンマ、スラッシュなどを含めず最後はreturnでなく完了を入力します。数字かどうかをチェックする例外処理が施されているので、「アプリケーションは予期しないエラーが起きました」を表示して止まることはありません。エラーを知らせる音が出てアプリは終了します。 ②入力値20120229はエラーになりませんが、20130229はエラーになります。 ③C言語ではBeepSleep関数が用意されていますが、javaでは簡単な関数は用意されていないようです。適切な処理を見つけるまで、かなり時間を要しましたが、同じ悩みをお持ちの方に参考になるでしょう。 ④エンコード指定はencoding=”utf-8″に設定済みですが、ソースコードに妙な漢字が表示されていてもECLIPSE開発画面や実行表示結果が正しければそのままにしている箇所があります。 ⑤動作の検証は全てにわたってはおりません。誤動作等があればご教示ください。 ⑥スマートフォン向けに「アプリ甲子園」という全国大会を開催して小中高校生のソフト開発を応援している企業があります。次世代を背負う若者が大勢、育っていくことを願っています。このサイトが参考になれば幸いです。

Androidアプリ開発環境構築、再び

Androidアプリ開発環境を再度、構築します。以下の画面に表示されているようにECLIPSEは時々、言うことを聞かなくなります。インストールは今回で3度目です。長時間使ったり、画面が落ち着いていないのに次の操作に無理やり進んだりすると不具合が起きるように感じます。再インストールにあたり、アンインストールすべきですが、省略してツール一式が格納されているフォルダをリネームするか他のドライブに移動します。これだけですとレジストリが不変なので再インストールに失敗することが多いのですが問題は起きていません。 バグは報告されているので、安定に向かうものと思います。そこで再構築は以下の通りです。 1)ECLIPSEのインストール GUIの統合開発ツールEclipse 本体と日本語化ツールがプラグインされたPleiades All in Oneが便利です。今回は「Pleiades All in One4.2.1.v20121007(Eclipse4.2.1 SR1 Juno for Windowsベース)」の32ビット、Standard Edition、Ultimateを指定してダウンロードします。圧縮ファイルPleiades-e4.2-ultimate-32bit_20121007.zipを解凍して、PleiadesフォルダをAndroidツールフォルダにコピーします。 2)JDK(Java SE Development kit 7 update 7開発キット)のインストール Javaアプリのライブラリやコンパイラが同梱されている「JDK」をダウンロードしてインストールします。ダウンロードしたjdk-7u7-windows-i586.exeを実行します。 3)SDKのインストール Androidアプリのライブラリやエミュレータなどを同梱した「Android SDK」をダウンロードしてインストールします。android-sdk_r17-windows.zipを解凍して「android-sdk-windows」フォルダをPleiadesフォルダにコピーします。 4)ADT Pluginのインストール ECLIPSE.exeを起動してAndroid SDKの各ソフトを使えるようにする「ADT Plugin」をインストールします。ヘルプ-新規インストール-追加-作業対象に https://dl-ssl.google.com/android/eclipse/の後、OKと入力し追加、すべて選択、次へ、次へ、使用条件の条項に同意します、完了と指定します。操作の切れ目で多少の時間がかかります。 以上でおおまかな環境が整います。不足の場合はその都度、追加が可能です。 参考サイト:www.andr0o0id.com/?p=1908

Androidアプリ第2弾

・初歩からスタートするAndroidアプリ開発

今回は、等差数列の和を求めるアプリを作ってみます。公差1でn項までの等差数列の和はn(n+1)/2で簡単に求めることができます。数式で表現すれば次のようになります。それでは早速、スタートします。


 

1)アルゴリズムは加算をn回繰り返して求めます。和をtとすればtをゼロに設定し、初項から順に加え新しいtとしてn項まで加算を繰り返します。n項の値が最初から分かっているので算出法は単純ですが、項数が増すほどn(n+1)/2で求めるよりも算出時間がかかり得策ではありません。

しかし、算出式のない大学共通学力試験の科目の合計点を求める場合などに応用できるので、敢えてこの方法を採用します。算出法が1つだけでない点に興味を抱いていただけるとありがたいです。

2)プロジェクトは前回と同様に、ECLIPSEプロジェクト新規作成画面で作成します。プロジェクト名とApplication NameにはSequenceを、ランチャーアイコンには星印を、Activity Nameにはcalculateを指定します。

 

 

3)srcフォルダのCalculate.javaに修正を加えます。

プロジェクト全ファイルは末尾に添付した圧縮を解凍して得られます。今回、プラグインツール[Syntax highlighter Evolved]をインストールしましたので、ソースコードに行番号が表示されて見やすくなりましたがコピー&ペーストしても行番号は付きません。

<SourceCode>

package com.sample.sequence; // 2012-11-12

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.os.Bundle;
import android.view.View;

// MainClass
public class Calculate extends Activity {
    /** Called when the activity is first created. **/
    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // make instance of ViewClass.
    MyCircleView view = new MyCircleView(getApplication());
    // set View.
    setContentView(view);
    }
}

// display class
@SuppressLint("DrawAllocation")
class MyCircleView extends View {
    // initialize View
    public MyCircleView(Context context) {
    super(context);
    setFocusable(true);
}

    // actualy,method of display.
    protected void onDraw(Canvas canvas) {
        int t = 0; // 和をクリアする
        for(int i = 0; i             t += i; // 順次、項値を加え、新しい和にする
        }
        Paint paint = new Paint(); // make paint-object
        super.onDraw(canvas);
        // set back-color.
        canvas.drawColor(Color.WHITE);
        paint.setTextSize(20); // make display-object.
        // make display-object.
        canvas.drawText("等差数列の和=" + t, 40, 100, paint); // 算出した和を表示する

    }
}

4)ビルドするために、「実行」します。

錠を右のスピーカまでドラッグして実行に移します。

5)ファイル一覧

C:.
│  .classpath
│  .project
│  AndroidManifest.xml
│  ic_launcher-web.png
│  proguard-project.txt
│  project.properties
│  Tree.TXT
│  
├─assets
├─bin
│  │  AndroidManifest.xml
│  │  classes.dex
│  │  jarlist.cache
│  │  resources.ap_
│  │  Sequence.apk
│  │  
│  ├─classes
│  │  └─com
│  │      └─user
│  │          └─sequence
│  │                  BuildConfig.class
│  │                  Calculate.class
│  │                  MyCircleView.class
│  │                  R$attr.class
│  │                  R$drawable.class
│  │                  R$id.class
│  │                  R$layout.class
│  │                  R$menu.class
│  │                  R$string.class
│  │                  R$style.class
│  │                  R.class
│  │                  
│  └─res
│      ├─drawable-hdpi
│      │      ic_action_search.png
│      │      ic_launcher.png
│      │      
│      ├─drawable-ldpi
│      │      ic_launcher.png
│      │      
│      ├─drawable-mdpi
│      │      ic_action_search.png
│      │      ic_launcher.png
│      │      
│      └─drawable-xhdpi
│              ic_action_search.png
│              ic_launcher.png
│              
├─gen
│  └─com
│      └─user
│          └─sequence
│                  BuildConfig.java
│                  R.java
│                  
├─libs
│      android-support-v4.jar
│      
├─res
│  ├─drawable-hdpi
│  │      ic_action_search.png
│  │      ic_launcher.png
│  │      
│  ├─drawable-ldpi
│  │      ic_launcher.png
│  │      
│  ├─drawable-mdpi
│  │      ic_action_search.png
│  │      ic_launcher.png
│  │      
│  ├─drawable-xhdpi
│  │      ic_action_search.png
│  │      ic_launcher.png
│  │      
│  ├─layout
│  │      activity_calculate.xml
│  │      
│  ├─menu
│  │      activity_calculate.xml
│  │      
│  └─values
│          strings.xml
│          styles.xml
│          
└─src
    └─com
        └─user
            └─sequence
                    Calculate.java

6)Sequenceプロジェクト内の全ファイル(Sequence.zip)を添付します。エラーが発生することなく実行までこぎつけられましたが、開発環境が異なりエラーが発生することがあるかも知れません。エラーのガイドメッセージやネットのお助け情報により解決できそうです。

Sequence