Androidアプリ作成〜Hello World~から一歩先へ

本日のアジェンダ

Lesson0:Hello Worldの復習

まずははじめに、Hello Worldで作られるファイル等について、簡単に見ていきたいと思います。
以下、英語版でのEclipseでの解説となります。もし、日本語化している場合には、適宜、読み替えてください。

Androidプロジェクトの作成

Android Projectを選びます。

Project Nameとして、適当な名前を設定します。図中では、「zackie_app」を指定しています。
Build Targetは、どのOSで利用するアプリを作ろうとしているのかを指定するものです。ここでは、Android 2.2を選びます。

Application Nameは、その名の通り、アプリケーションの名前となります。後で変更可能(strings.xmlのapp_nameに設定されるだけ)なので、適当な名前を記入してください。

作られたファイルを見てみよう

Eclipseのファイルエクスプローラ(左端)を見ると、以下のようなファイルができていることがわかります。押さえておきたいファイルについて、簡単に概要を説明します。

MainActivity.javaを見てみよう

それでは、メインのソースファイルである、MainActivity.javaファイルの中身を見ていきたいと思います。
MainActivity.javaファイルの中身を見ると、下記のようなソースが自動生成されていることがわかります。
package com.ntt.zackie_app;

import android.app.Activity;
import android.os.Bundle;

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

このコードを見て、「んん?もう無理ぽorz」と思ったそこのあなた、安心してください。ゆっくりやっていきますw
そもそも、Activityというのは、何なのでしょうか?
今日のポイント1:
Activity="Androidアプリの画面"のことです!
Androidのアプリは、一画面一画面を、Activityという単位で作っていきます。なので、Activityと聞いたら、「あ、Androidの画面のことね」という風に捉えてください。そして、ActivityとActivityをIntentといく仕組みでつないでいきます。HTMLファイルとHTMLファイルを、リンクという形でつないでいくWebアプリと似ています。
参考:『Androidアプリ作成の基本“Activity”とは何か?
今日のポイント2:
アプリが起動したらonCreate()から実行されます!
新しいプログラミングを学んだとき、「アプリを起動した後、どういう順番で実行されるのか」とか、「あるリクエストをサーバで受け取ったあと、サーバ内のプログラムはどういう順番で処理をしていくのか」という観点から、勉強をする人が多いのではないでしょうか?
Androidアプリの場合、アプリを起動すると、まず、onCreateというイベントが呼ばれ、onCreateの中に書かれたコードが実行されます。
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

上記の通り、たった4行しかありません。
今の時点では、「onCreateから処理されるんだ」くらいの理解だけで問題なしです。
今日のポイント3:
アプリ起動後、アプリの状態が変わるたびに、onCreate以外のいろいろなイベントが呼ばれます!アプリを細かく制御するためには、onCreate以外のイベントを自ら実装する必要があります!
Androidアプリは、アプリをインストールして初めて起動したあと、いろいろな状態を取ります。たとえば、アプリ起動後、ホームボタンを押して一回、バックグラウンドに移行させてもアプリが動き続けるのがAndroidの一つの特徴ですが、その状態は、アプリがフォアグラウンドにある状態とは異なります。
先ほど、アプリを起動すると、onCreateというイベントが呼ばれるということを書きました。Androidの状態が変わると、onCreate以外にもいろいろなイベントが呼ばれます。それが、『Activityのライフサイクル』と呼ばれるものです。
Androidのライフサイクルは、アプリを作る上で理解が欠かせない概念です。
たとえば、アプリを立ち上げるたびに、サーバから最新の情報を取ってきて表示するようなアプリ(たとえば、Twitterのタイムラインを表示するなど)を考えてみてください。
上記のライフサイクルを見ると、onCreateは、アプリ開始後、一回呼ばれますが、その後、強制終了して再度立ち上げない限り、呼ばれることがないことを示しています。もし、仮に、onCreateの中に、Twitterのタイムラインを取得するような処理を書いたとしましょう。そうすると、タイムラインを更新するためには、アプリを一回一回強制終了して立ち上げ直さないといけないことになってしまいます。
では、どこに書けばいいのか。もうお分かりですね。Activityが表示されるたびに実行されるonResumeの中に書けばいいのです。onResumeの中にタイムラインを更新する処理を書けば、バックグラウンドからフォアグラウンドに移行するたびに、onResumeが呼ばれ、希望通りの動きをさせることができます。
このように、Androidアプリを作成する場合には、どの状態のときに、どういう処理をさせたいのかということを考えながらコーディングしていくことが必要です。そのためには、慣れるまでは、onCreateやonResumeといったイベントが発行させるたびに、ログに書き出すといったことをやるのがいいと思います。
次の演習では、それに取り組んでみましょう。

演習1:各操作のときに、どういうイベントが発行されるか見てみよう

以下、ハイライトされた部分を追加しましょう。 MainActivity.java:
package com.ntt.zackie_app;

import java.text.SimpleDateFormat;
import java.util.Date;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;

public class MainActivity extends Activity {
    /** Called when the activity is first created. */
	
	//TextViewオブジェクトの宣言
	TextView textView1;
    
	@Override
    public void onCreate(Bundle savedInstanceState) {
    	Log.d("tag","onCreate is called");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        //TextViewの生成
        textView1 = (TextView)findViewById(R.id.hello);
        
        //Dateオブジェクトを作成
        Date date1 = new Date();
        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
        
        //テキストの内容として、日時を設定する。
        textView1.setText(sdf1.format(date1));
        
        
    }
    
    public void onStart(){
    	Log.d("tag","onStart is called");
    	super.onStart();
    	
    }
    
    public void onResume(){
    	Log.d("tag", "onResume is called");
    	super.onResume();
    }
    
    public void onPause(){
    	Log.d("tag","onPause is called");
    	super.onPause();
    	
    }
    
    public void onStop(){
    	Log.d("tag","onStop is called");
    	super.onStop();
    }
}
main.xmlについては、TextViewタグの中に、「android:id="@+id/hello」を追加してください。
main.xml:





演習1の解説

参考:プロジェクトファイル一式

Lesson1:ユーザインターフェースを変えてみる

Androidでユーザインターフェースを定義する方法には、二つのやり方があります。一つは、外部XMLファイルで定義する方法です。これは、たとえばWebアプリを作るときに、HTMLファイルでレイアウトを定義する方法と似たやり方です。
もう一つは、プログラムの中で動的にオブジェクトを配置していく方法です。もちろん、両方を組み合わせることも可能で、たとえば、初期画面はXMLファイルで定義してあげて、処理に応じて動的に値を変えていくといったことも可能です。
今回の演習では、外部XMLファイルで定義するやり方を中心に、やってみたいと思います。

演習2:ユーザインターフェースを変えてみよう

下記のコードをそれぞれ変えてみて、実行してみてください。
MainActivity.java
package com.ntt.zackie_app;

import java.text.SimpleDateFormat;
import java.util.Date;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

public class MainActivity extends Activity {
    /** Called when the activity is first created. */
	
	//TextViewオブジェクトの宣言
	TextView textView1;
    
	@Override
    public void onCreate(Bundle savedInstanceState) {
    	Log.d("tag","onCreate is called");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        //TextViewの生成
        textView1 = (TextView)findViewById(R.id.hello);
    }
    
    public void onStart(){
    	Log.d("tag","onStart is called");
    	super.onStart();
    	
    }
    
    public void onResume(){
        //Dateオブジェクトを作成
        Date date1 = new Date();
        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
        
        //テキストの内容として、日時を設定する。
        textView1.setText(sdf1.format(date1));
    	Log.d("tag", "onResume is called");
    	super.onResume();
    }
    
    public void onPause(){
    	Log.d("tag","onPause is called");
    	super.onPause();
    	
    }
    
    public void onStop(){
    	Log.d("tag","onStop is called");
    	super.onStop();
    }
    
    public void getLatLong(View view){
    	Log.d("tag","getLatLong is called!");
    }
}
main.xml
strings.xml


Hello World, MainActivity!
zackie_app
緯度
経度
緯度経度を取得!

演習2の解説

参考:プロジェクトファイル一式

Lesson2:位置情報を取得してみる

演習3:位置情報を取得してみる

下記のコードを入力して、実行してみてください。
Eclipseが自動的に補完してくれる部分がありますので、下記の順番で入力していくのがおすすめです。
MainActivity.java
package com.ntt.zackie_app;
 
import java.text.SimpleDateFormat;
import java.util.Date;
 
import android.app.Activity;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
 
public class MainActivity extends Activity implements LocationListener {
    /** Called when the activity is first created. */
     
    //TextViewオブジェクトの宣言
    TextView textView1;
    TextView textView_lat;
    TextView textView_lon;
    
    //LocationManagerオブジェクトの宣言
    private LocationManager locmanager;
     
    @Override
    public void onCreate(Bundle savedInstanceState) {
        Log.d("tag","onCreate is called");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
         
        //TextViewの生成
        textView1 = (TextView)findViewById(R.id.hello);
        textView_lat = (TextView)findViewById(R.id.latitude);
        textView_lon = (TextView)findViewById(R.id.longitude);
    }
     
    public void onStart(){
        Log.d("tag","onStart is called");
        super.onStart();
         
    }
     
    public void onResume(){
        //Dateオブジェクトを作成
        Date date1 = new Date();
        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
         
        //テキストの内容として、日時を設定する。
        textView1.setText(sdf1.format(date1));
        Log.d("tag", "onResume is called");
        super.onResume();
        
        locmanager = (LocationManager) getSystemService(LOCATION_SERVICE);
    }
     
    public void onPause(){
        Log.d("tag","onPause is called");
        super.onPause();
         
    }
     
    public void onStop(){
        Log.d("tag","onStop is called");
        super.onStop();
    }
     
    public void getLatLong(View view){
        Log.d("tag","getLatLong is called!");
        
        //GPSで取得する場合
        locmanager.requestLocationUpdates(locmanager.GPS_PROVIDER, 0, 0, this);
        //WiFiの情報を使う場合
        //locmanager.requestLocationUpdates(locmanager.NETWORK_PROVIDER, 0, 0, this);
    }

	public void onLocationChanged(Location location) {
		// TODO Auto-generated method stub
		Log.d("tag","onLocationChanged is calle");
		
		//取得できた緯度経度を表示
		
		//onLocationChangedイベントが発生したときに渡されるLocationオブジェクトの
		//getLatitude(),getLongitude()を見れば、
		//得られた緯度、経度がわかる。
		//Double型で渡されるので、それを、Double.toString()というメソッドで
		//String型に変換している。
		
		textView_lat.setText("緯度: " + Double.toString(location.getLatitude()));
		textView_lon.setText("経度: " + Double.toString(location.getLongitude()));
		
		//一度位置情報が取得できたら、取得をやめる。
		locmanager.removeUpdates(this);
		
	}

	public void onProviderDisabled(String provider) {
		// TODO Auto-generated method stub
		
	}

	public void onProviderEnabled(String provider) {
		// TODO Auto-generated method stub
		
	}

	public void onStatusChanged(String provider, int status, Bundle extras) {
		// TODO Auto-generated method stub
		
	}
}

AndroidManifest.xml




    
        
            
                
                
            
        
        
        
	
    
    







演習3の解説

今日のポイント4:
GPSや加速度センサなど、センサに関わるプログラムを書く場合には、それに応じたListenerをimplementsする。Listenerをimplementsしたら、必ず実装しなくてはいけないメソッドがあるので、Eclipseの指示に従って、実装する。
今日のポイント5:
GPSやインターネットとの通信など、ユーザのパーミッションが必要な機能を使う場合には、マニフェストファイルを書き換える!(忘れやすいのです。。。)
参考:プロジェクトファイル一式

今後の参考

参考/リンク

ログをタグで絞り込む方法

  1. LogCatのタブにある、+ボタンをクリックします。
  2. Filter Nameに適当な名前を入力します。by Log Tagに、フィルターで表示したいtag名を記入します。
  3. tagという新しいタブができ、そこには、tagという名前のタグだけが表示されるようになります。