MediaPlayerで再生したファイルをintentで遷移させた先でstopさせる その1

再生させたMediaPlayerをintentした先で停止させる方法です。
生成したMediaPlayerインスタンスを、intentした先でも引き継がなくてはいけません。

イメージとしては、
[MainActivity]で再生を開始し、次の画面に遷移。
遷移した[StopActivity]で停止するという動作ですが、これには別で定義したクラスを継承しなくてはいけません。

まずはレイアウトファイルから。
[activity_main.xml]

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="center"
    android:orientation="vertical" >

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginRight="8dp"
        android:onClick="PLAY"
        android:text="再生" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginRight="8dp"
        android:onClick="NEXT"
        android:text="移動" />

</LinearLayout>

再生ボタンを押すと、ファイルをループで再生。
移動ボタンを押すと、別のアクティビティへ。

[activity_stop.xml]

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="center"
    android:orientation="vertical" >

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginRight="8dp"
        android:onClick="STOP"
        android:text="停止" />

</LinearLayout>

次に、Activityのソースコードです。
ここで注意。普段はActivityを継承していますが、今回はオリジナルのクラス[AlarmActivity]を継承します。
[MainActivity]

public class MainActivity extends AlarmActivity {
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
	}

	public void PLAY(View v) {
		mpStart();
	}

	public void NEXT(View v) {
		Intent intentMain = new Intent(this, StopActivity.class);
		startActivity(intentMain);
		finish();
	}
}

[StopActivity]

public class StopActivity extends AlarmActivity {
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_stop);
	}

	public void STOP(View v) {
		mpStop();
	}
}

このように、非常にスッキリとしたシンプルな構成になります。
このままだとエラーが出まくりだと思います。

継承元である、AlarmActivityを作らなくてはいけません。
[AlarmActivity]

public class AlarmActivity extends Activity {
	static protected MediaPlayer mp;
	static protected AudioManager am;

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

		//MediaPlayerインスタンスの生成
		if (mp == null) {
			Uri uri = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.alarm);

			mp = MediaPlayer.create(this, uri);
			mp.setLooping(true);
		}

		if (am == null) {
			am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
		}
	}

	protected void mpStart() {
		if (!mp.isPlaying()) {
			mp.start();
		}
	}

	protected void mpStop() {
		if (mp.isPlaying()) {
			mp.stop();
		}
	}

	protected int getMaxVolume() {
		int max = am.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
		return max;
	}

	protected int getNowVolume() {
		int Vol = am.getStreamVolume(AudioManager.STREAM_MUSIC);
		return Vol;
	}

	protected void setVolume(int vol) {
		am.setStreamVolume(AudioManager.STREAM_MUSIC, vol, 0);
	}

}

Activityを継承したAlarmActivityを継承したMainActivityとStopActivity、という感じです。ちょっとややこしいですが……。
こうすることで、共通のMediaPlayerインスタンスを使うことができ、別のActivityからでも再生・停止の操作が可能です。

アラーム通知で、任意の音源をループ再生して任意のタイミングで停止する

アラーム通知で、任意の音源(ジングルなどのmp3ファイル)をループ再生して、好きなタイミングで止めるというのを実装してみます。
基本的には、下記の記事を参考に、組み合わせるだけです。
アプリで音声ファイルをループ再生して、任意のタイミングで止める
Androidアプリでアラーム通知をする その1

起動して、その1分後にアラーム通知が来るようにセットするコード。

[MainActivity]

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

	//アラームを識別するコード、任意なので重複しない好きな数値を設定
	int REQUEST_CODE = 140707;

	//1分後に通知を鳴らす
	Calendar cal = Calendar.getInstance();
	cal.add(Calendar.MINUTE, 1);
	long init_alarm = cal.getTimeInMillis();

	//指定の時間になったら起動するクラス
	Intent intent = new Intent(this, AlarmReceiver.class);
	intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
	PendingIntent sender = PendingIntent.getBroadcast(this, REQUEST_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT);

	//AlramManagerにPendingIntentを登録
	AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
	am.set(AlarmManager.RTC_WAKEUP, init_alarm, sender);
}

[res]-[raw]フォルダの中に、「alarm.mp3」というファイルを入れている。
音量をマックスまで上げているが、これはサンプル用に記述しているだけで、普通の配布アプリではユーザーに無断で音量をあげたりしない。
アラームを鳴らす時間は「int timeout = 30*1000;」で30秒としている。

[AlarmReceiver]

public class AlarmReceiver extends BroadcastReceiver {
	// notifications
	@Override
	public void onReceive(Context context, Intent data) {
		Resources res = context.getResources();

		Notification n = new Notification();
		//アイコンの設定
		n.icon = R.drawable.ic_launcher;
		//メッセージの設定
		n.tickerText = "メッセージ1";
		//通知を選択した時に自動的に通知が消えるための設定
		n.flags = Notification.FLAG_AUTO_CANCEL;

		// 通知をタッチしたときに起動するActivity
		Intent i = new Intent(context, StopActivity.class);

		PendingIntent pi = PendingIntent.getActivity(context, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);
		// 上から通知バーを下してきたときに表示される文章をセット
		n.setLatestEventInfo(context, res.getString(R.string.app_name), "メッセージ2", pi);

		//デフォルトLED点滅パターンを設定
		n.defaults |= Notification.DEFAULT_LIGHTS;

		// 設定したNotificationを通知する
		NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
		nm.notify(1, n);

		Uri uri = Uri.parse("android.resource://" + context.getPackageName() + "/" + R.raw.alarm);

		//音量設定を取得
		AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
		int Vol = am.getStreamVolume(AudioManager.STREAM_MUSIC); //[res]-[raw]の音源を再生するときの音量
		int max = am.getStreamMaxVolume(AudioManager.STREAM_MUSIC); //[res]-[raw]の音源を再生するときの最大音量
		System.out.println("Vol:" + Vol);
		System.out.println("max:" + max);
		//音量を上げる
		am.setStreamVolume(AudioManager.STREAM_MUSIC, max, 0);

		final MediaPlayer mp = MediaPlayer.create(context, uri);
		mp.setLooping(true);
		mp.start();

		int timeout = 30*1000;
		Handler handler = new Handler();
		handler.postDelayed(new Runnable() {
			@Override
			public void run() {
				if (mp.isPlaying())
					mp.stop();
			}
		}, timeout);
	}
}

[AndroidManifest.xml]

<receiver
    android:name="com.example.alarm_test.AlarmReceiver"
    android:process=":remote" />

Androidアプリでアラーム通知をする その2

前回の記事でアラームをセットする方法を書きました。

いったんセットしたアラームを、解除したいという場合もあると思います。

//アラームを識別するコード、任意なので重複しない好きな数値を設定
int REQUEST_CODE = 140625;

//ActivityAlarmReceiverを呼び出すインテントを作成
Intent intent = new Intent(context, AlarmReceiver.class);
//ブロードキャストを投げるPendingIntentの作成
PendingIntent sender = PendingIntent.getBroadcast(context, REQUEST_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT);
//AlarmManager取得
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
//PendingIntentをキャンセル
am.cancel(sender);
System.out.println("REQUEST_CODE" + REQUEST_CODE + " -> cancel");

このREQUEST_CODEに注意しましょう。
セットしたときと同じ値を宣言しておかないとキャンセルできませんよ。

Androidアプリでアラーム通知をする その1

Twitterアプリとかお知らせで画面の上のほうにピローンってきたりするじゃないですか。
あれ、正確にはpush通知でまた違うんですけど、アプリ内で時間をセットして同じように通知させることができます。
(push通知の実装のしかたはこちら Androidアプリでプッシュ通知を実装するとき

PendingIntentを登録する。
[MainActivity]

//アラームを識別するコード、任意なので重複しない好きな数値を設定
int REQUEST_CODE = 140625;

//通知を鳴らしたい時間をセットする
Calendar cal = Calendar.getInstance();
cal.set(y, m, d, 0, 0, 0);	//年、月、日、時、分、秒
cal.set(Calendar.MILLISECOND,0);	//ミリ秒

//ミリ秒で通知時間を設定する
long init_alarm = cal.getTimeInMillis();
System.out.println("REQUEST_CODE" + REQUEST_CODE + " -> init_alarm:" + init_alarm);

//指定の時間になったら起動するクラス
Intent intent = new Intent(this, AlarmReceiver.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
//普通のintentと同じように、KEYとの組み合わせで値を受け渡しできるよ
intent.putExtra("KEY", value);
//ブロードキャストを投げるPendingIntentの作成
PendingIntent sender = PendingIntent.getBroadcast(this, REQUEST_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT);

//AlramManager取得
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
//AlramManagerにPendingIntentを登録
am.set(AlarmManager.RTC_WAKEUP, init_alarm, sender);

Activity内での呼び出しはこれでOKです。

次は設定した時間になったら起動するAlarmReceiverです。

public class AlarmReceiver extends BroadcastReceiver {
	// notifications
	@Override
	public void onReceive(Context context, Intent data) {
		//変数の受け取り
		int value = data.getIntExtra("KEY", 0);

		Resources res = context.getResources();

		Notification n = new Notification();
		n.icon = R.drawable.ic_launcher; // アイコンの設定
		// 通知されたときに通知バーに表示される文章
		String set_text = "メッセージ 受け取った変数:" + value;	//受け取ったvalueに応じて文章を変更したりなど、ご自由に
		n.tickerText = set_text; // メッセージの設定
		n.flags = Notification.FLAG_AUTO_CANCEL; // 通知を選択した時に自動的に通知が消えるための設定

		// 通常の着信音を選択する
		// Uri uri =
		// RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE); //着信音
		// Uri uri =
		// RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
		// //通知音
		Uri uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM); // アラーム音
		n.sound = uri; // サウンド

		//通知をタッチしたときに起動するActivity
		Intent i = new Intent(context, SplashActivity.class);

		PendingIntent pi = PendingIntent.getActivity(context, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);
		// 上から通知バーを下してきたときに表示される文章をセット
		n.setLatestEventInfo(context, res.getString(R.string.app_name), set_text, pi);

		long[] vibrate_ptn = { 0, 100, 300, 1000 }; // 独自バイブレーションパターン
		n.vibrate = vibrate_ptn; // 独自バイブレーションパターンを設定

		n.defaults |= Notification.DEFAULT_LIGHTS; // デフォルトLED点滅パターンを設定

		// NotificationManagerのインスタンス取得
		NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
		nm.notify(1, n); // 設定したNotificationを通知する
	}
}

最後に、Receiverをマニフェストファイルに登録します。
バイブ機能を使用するので、パーミッションも追加しましょう。
[AndroidManifest.xml]
パーミッション

<uses-permission android:name="android.permission.VIBRATE" />

applicationタグの中のどこかに記述

<receiver
    android:name="○○(プロジェクト名).activity.AlarmReceiver"
    android:process=":remote" />

アプリで音声ファイルをループ再生して、任意のタイミングで止める

前回の記事で、音声ファイルを再生するコードを書きました。

あれだけだと、ファイルを1回再生してすぐ止まったと思います。
あのままだと実用性が低いので、今回はループ再生して、好きなだけ鳴らして、ある程度の時間が経ったら止める、という処理をやってみようと思います。

Uri uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM); // アラーム音

//音量設定を取得
AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
int Vol = am.getStreamVolume(AudioManager.STREAM_MUSIC); //[res]-[raw]の音源を再生するときの音量
int max = am.getStreamMaxVolume(AudioManager.STREAM_MUSIC); //[res]-[raw]の音源を再生するときの最大音量
System.out.println("Vol:" + Vol);
System.out.println("max:" + max);
//音量を上げる
am.setStreamVolume(AudioManager.STREAM_MUSIC, max, 0);

ここまでは一緒です。

MediaPlayerインスタンスの宣言から、ちょっと変えていきます。

final MediaPlayer mp = MediaPlayer.create(context, uri);
mp.setLooping(true);
mp.start();

int timeout = 30*1000;
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
	@Override
	public void run() {
		if (mp.isPlaying())
			mp.stop();
	}
}, timeout);

timeoutという変数で、音が鳴りやむまでの時間を設定しています。
ここでは30秒鳴って止めています。秒数を変えたいなら、この30を変えれば変更できます。

注意としては、mp.stop();を必ず実行するようにしてください。
これがないとマジでずっと鳴り続けます。Activityを閉じても、アプリを終了しても、ずっと、ずっと……。

Top