Android アプリ開発 「MATRIX」

Androidアプリの開発に役立つサンプル集



サービスの基本的な使い方を知っておこう

基本的なサービスの使い方

今回は「サービス」の基本的な使い方です。「サービス」というのは長時間バックグラウンドで動きインターフェース画面を持たないアプリケーションです。基本的な作り方は意外に簡単で、サービスを継承したクラスを作った後、それを他から呼び出して実行させるだけです。

「サービス」を利用すれば画面を閉じても動き続ける必要がある「タイマー」アプリや「音楽プレイヤー」アプリなどが作れるようになりますね。

サンプルコード①(MainActivity.java

MainActivity クラスの中に「Service」を継承した「TestService」が入っていますが、コード増えると長くなってしまうので、その場合はそれぞれ別々のファイルに分けた方が良いですね。

public class MainActivity extends AppCompatActivity {

private Button button, button2;
private Intent intent;
private static TextView textView;

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

//サービス用のインテントを生成
intent = new Intent(getBaseContext(), TestService.class);
//レイアウトから表示用のテキストビューを取得
textView = (TextView)findViewById(R.id.infom);

//レイアウトからボタンを取得してクリックイベントを設定
button = (Button)findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startService(intent);
}
});

//レイアウトからボタン2を取得してクリックイベントを設定
button2 = (Button)findViewById(R.id.button2);
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
stopService(intent);
}
});
}

@Override
protected void onDestroy() {
super.onDestroy();
// アプリを終了したらサービス停止
stopService(intent);
}

//サービス本体
public static class TestService extends Service {

// サービスが作られると呼び出される
@Override
public void onCreate() {
super.onCreate();
}

// サービスが停止すると呼び出される
@Override
public void onDestroy() {
super.onDestroy();
// 画面に「サービス停止中」と表示
textView.setText("サービス停止中");
}

// バインドされると呼び出される(※内容がなくても省略不可能)
@Override
public IBinder onBind(Intent intent) {
// バインドしていないので内容はなし
return null;
}

// サービスが開始されると呼び出される
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// 画面に「サービス実行中」と表示
textView.setText("サービス実行中");
// 強制終了したら再起動させる戻り値
return START_REDELIVER_INTENT;
}
}
}

サンプルコード②(AndroidManifest.xml

「サービス」を継承したクラスを作ったら必ずマニフェストファイルにその存在を登録する必要があります。※下の方にある赤文字の行を追加します。

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<service android:name=".MainActivity$TestService" />
</application>

サンプルコード③(activity_main.xml

特に複雑なものではありません。サービスの状態を表示するテキストビューと、サービスの起動と停止をする2つのボタンがあるだけのシンプルな構造です。

<TextView
android:id="@+id/infom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="7dp"
android:text="サービス停止中"
android:textSize="30sp"
app:layout_constraintBottom_toTopOf="@+id/button"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />

<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="START"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="STOP"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button" />

実行結果

実行すると「サービス停止中」というテキスト表示と「START」と「STOP」というラベルのボタンが画面上に表示されます。

f:id:vw-dsg:20181019000238g:plain

「START」ボタンを押してサービスを起動すると「サービス停止中」という表示が「サービス実行中」という表示に変わります。

f:id:vw-dsg:20181019000303g:plain

開発者ツールで実行中のサービスを確認すると今回作った「Service Test」というアプリの名前が実行中のサービスリストの中にありました。

f:id:vw-dsg:20181019000319g:plain

「STOP」ボタンを押したりサンプルアプリを終了すると・・・実行中のサービス一覧からサンプルアプリ「Service Test」が削除されました。

f:id:vw-dsg:20181019000333g:plain

その他・備考

この方法の他にバインドしてサービスを動かす方法がありますが、少しだけ複雑になりますのでまた次の機会にサンプルを作って説明したいと思います。 

END

GPSを利用したスピードメーター(速度計)の作り方

GPSを利用したスピードメーター(速度計)

今回はGPSを利用したシンプルなスピードメーター(速度計)の作り方です。

Android Java には現在の速度を「m/s」単位で取得できる関数「getSpeed」があるので、GPSの位置情報からいちいち速度を計算する必要はありませんが、取得できる間隔が「1秒」と長いので、短時間で速度が変化するような場合の速度測定には向かないかもしれません。

サンプルコード①(MainActivity.java

詳しい説明はコード内のコメントを見てください。 

//メインアクティビティ(implementsGPSを監視できるようにしてある)
public class MainActivity extends AppCompatActivity implements LocationListener {

private LocationManager locationManager; //ロケーションマネージャー
private TextView textView; //速度表示用
private float speed = 0f; //速度用の変数

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//レイアウトファイルをセット
setContentView(R.layout.activity_main);
//アクションバーを隠す
ActionBar actionBar = getSupportActionBar();
actionBar.hide();
//ロケーションマネージャーに端末のロケーションサービスを関連付ける
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
//レイアウトファイルからテキストビューを取得する
textView = (TextView) findViewById(R.id.speed_text);
}

@Override
protected void onPause() {
super.onPause();
//ポーズ時にはGPS(位置情報)の取得を解除する
locationManager.removeUpdates(this);
}

@Override
protected void onResume() {
super.onResume();
//GPS(位置情報)の取得が許可があるのかをチェック
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

//GPSの使用が許可されていなければパーミッションを要求し、その後再度チェックが行われる
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);

return;
}
//ロケーションマネージャーにGPS(位置情報)のリクエストを開始する
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
}

@Override
public void onLocationChanged(Location location) {
  //
速度が出ている?
if(location.hasSpeed()) {
//速度が出ている時(km/hに変換して変数speedへ
speed = location.getSpeed() * 3.6f;
} else {
//速度が出ていない時
speed = 0;
}
//速度を表示する
textView.setText(speed + " km/h");
}

@Override
public void onStatusChanged(String s, int i, Bundle bundle) {
//必要に応じてプログラムを書く(省略はできない)
}

@Override
public void onProviderEnabled(String s) {
//必要に応じてプログラムを書く(省略はできない)
}

@Override
public void onProviderDisabled(String s) {
//必要に応じてプログラムを書く(省略はできない)
}
}

サンプルコード②(activity_main.xml

レイアウトは、画面の中央にスピードを表示するテキストビューがあるだけのシンプルな構造です。 

<TextView
android:id="@+id/speed_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0 km/h"
android:textSize="36sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />

実行結果

実行するとアプリが「位置情報(GPS)」使用の許可を要求してくる。

f:id:vw-dsg:20181008223619j:plain

「OK(ALLOW)」を選択するとすぐに速度の測定が開始されます。

f:id:vw-dsg:20181008223055j:plain

備考・その他

このサンプルアプリは、バックグラウンドに移動するとGPSを停止して速度の測定を一時中断する仕組みになっているので、バックグラウンドに残してあってもGPSで電力を消費することはありません。 

END

ブラウザを起動するボタンを作る方法

ブラウザを起動するボタンを作る

今回はボタンをクリックするとブラウザが起動して「Yahoo!」サイトを表示するサンプルを作ります。

動作の流れは、Uriに「Yahoo!」のアドレスをセットし、UriをセットしたIntent(ACTION_VIEW)を作成して、最後にそのIntentをstartActivityで開始します。

手続きが少々面倒ですが知っておいて損はありませんので、このサンプルで流れをしっかり覚えてしまいましょう。

サンプルコード①(MainActivity.java

詳しい説明はコード内のコメントを参考にしてください。

public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

//レイアウトファイルをセット
setContentView(R.layout.activity_main);
//アクションバーを取得
ActionBar actionBar = getActionBar();
//アクションバーを隠す
actionBar.hide();

//レイアウトファイルのボタンを取得
Button button = (Button)findViewById(R.id.button);
//取得したボタンにクリックイベントをセット
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//ブラウザで開きたいサイトをuriにセット
Uri uri = Uri.parse("http://yahoo.co.jp");
//uriを開くインテントを作成
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
//uriを開くアクティビティをスタートします
startActivity(intent);
}
});
}
}

サンプルコード②(activity_main.xml) 

レイアウトファイルは中央にボタンがあるだけの単純な構造です。

<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Yahoo!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

実行結果

中央のボタンをクリックすると…

f:id:vw-dsg:20181005211902p:plain

 

Yahoo!」のウェブサイトが表示されました。

f:id:vw-dsg:20181005211923p:plain

END