・初歩からスタートする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
[java]
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");}
}
}
[/java]
・FirstActivity.java
[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
[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
[/java]
(10)実行結果
(11)ファイル一覧
プロジェクト内のファイルを階層構造形式に表示します。
(12)全プロジェクトファイル
上記ファイル一覧DayOfTheWeekプロジェクト内の全ファイル(DayOfTheWeek.zip)を添付し一挙、全公開します。
(13)感想・概評
①日付はハイフン、カンマ、スラッシュなどを含めず最後はreturnでなく完了を入力します。数字かどうかをチェックする例外処理が施されているので、「アプリケーションは予期しないエラーが起きました」を表示して止まることはありません。エラーを知らせる音が出てアプリは終了します。
②入力値20120229はエラーになりませんが、20130229はエラーになります。
③C言語ではBeepやSleep関数が用意されていますが、javaでは簡単な関数は用意されていないようです。適切な処理を見つけるまで、かなり時間を要しましたが、同じ悩みをお持ちの方に参考になるでしょう。
④エンコード指定はencoding=”utf-8″に設定済みですが、ソースコードに妙な漢字が表示されていてもECLIPSE開発画面や実行表示結果が正しければそのままにしている箇所があります。
⑤動作の検証は全てにわたってはおりません。誤動作等があればご教示ください。
⑥スマートフォン向けに「アプリ甲子園」という全国大会を開催して小中高校生のソフト開発を応援している企業があります。次世代を背負う若者が大勢、育っていくことを願っています。このサイトが参考になれば幸いです。