Android Service Notification と Audio 再生

■ TestServise.java

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;

import java.text.SimpleDateFormat;
import java.util.Locale;
import java.util.Timer;
import java.util.TimerTask;
import java.util.Date;
import android.os.Handler;

import android.support.v4.app.NotificationManagerCompat;
import android.support.v7.app.NotificationCompat;

import android.os.Build;


public class TestService extends Service {

private MediaPlayer mediaPlayer;
private int counter = 0;

private Timer mTimer;
private Handler mHandler = new Handler();

private Date nowDate;
private long now_msec;

private SimpleDateFormat dataFormat =
new SimpleDateFormat("mm:ss", Locale.US);

private int requestCode = 0;
private boolean fin_flag = false;

private Intent set_intent;


@Override
public void onCreate() {
super.onCreate();
Log.d("debug", "onCreate()");

// ..\res\raw\chime.mp3
mediaPlayer = MediaPlayer.create(this, R.raw.chime);
try{
mediaPlayer.prepare();
}catch( Exception e ){ }

}


@Override
public int onStartCommand(Intent intent, int flags, int startId) {

Log.d("debug", "onStartCommand()");

fin_flag = true;

requestCode = intent.getIntExtra("REQUEST_CODE", 0);

// Toast.makeText(getApplicationContext(), "requestCode:" + requestCode, Toast.LENGTH_SHORT).show();

set_intent = intent = new Intent(Intent.ACTION_MAIN);

// exe_notification();


// タイマーの設定 1秒毎にループ
mTimer = new Timer(true);
mTimer.schedule( new TimerTask(){
@Override
public void run(){
mHandler.post( new Runnable(){
public void run(){
Log.d( "TestService" , "Timer run" );

nowDate = new Date();
now_msec = nowDate.getTime() / 1000;

// if((now_msec % 1000) % 30 == 0) // とりあえずコメントアウト
// exe_notification();

if (requestCode < now_msec) {
if(fin_flag) {

fin_flag = false;

// Toast.makeText(getApplicationContext(), "時間になった:" + dataFormat.format(now_msec), Toast.LENGTH_SHORT).show();

// オーディオの 再生
audioStart();

sendMessage("こんにちは");

}
} else {

// Toast.makeText(getApplicationContext(), "time:" + dataFormat.format(now_msec), Toast.LENGTH_SHORT).show();

}
}
});
}
}, 1000, 1000);


return START_NOT_STICKY;
//return START_STICKY;
//return START_REDELIVER_INTENT;

}


protected void sendMessage(String msg){

Toast.makeText(getApplicationContext(), "sendMessage:", Toast.LENGTH_SHORT).show();

Intent broadcast = new Intent();
broadcast.putExtra("message", msg);
broadcast.setAction("DO_ACTION");
getBaseContext().sendBroadcast(broadcast);
}


private void exe_notification() {

Context context = getApplicationContext();
String channelId = "default";
String title = context.getString(R.string.app_name);


// 通知タップでアプリ起動
set_intent = new Intent(Intent.ACTION_MAIN);
set_intent.addCategory(Intent.CATEGORY_LAUNCHER);
set_intent.setClassName(getApplicationContext().getPackageName(), MainActivity.class.getName());
set_intent.setFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED | Intent.FLAG_ACTIVITY_NEW_TASK);

PendingIntent pendingIntent =
PendingIntent.getActivity(context, requestCode, set_intent, PendingIntent.FLAG_UPDATE_CURRENT);

// Android version で 分岐
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

// 20190205 新バージョンの Notification Android 8.0 以降

NotificationManager notificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

// Notification Channel 設定
NotificationChannel channel = new NotificationChannel(
channelId, title, NotificationManager.IMPORTANCE_DEFAULT);

if (notificationManager != null) {
notificationManager.createNotificationChannel(channel);

Notification notification = new Notification.Builder(context, channelId)
.setContentTitle("新タイトル")
.setSmallIcon(R.drawable.time)
.setContentText("新テキスト")
.setAutoCancel(false)
.setContentIntent(pendingIntent)
.setWhen(System.currentTimeMillis())
.build();

// startForeground
startForeground(1, notification);
}

} else {

// 20190205 旧バージョンの Notification

int defaults = 0;

defaults = defaults | Notification.DEFAULT_LIGHTS;
defaults = defaults | Notification.DEFAULT_SOUND;
defaults = defaults | Notification.DEFAULT_VIBRATE;
// defaults = defaults | Notification.PRIORITY_DEFAULT;


NotificationManagerCompat manager = NotificationManagerCompat.from(context.getApplicationContext());
Notification notification = new NotificationCompat.Builder(context.getApplicationContext())
.setAutoCancel(true)
.setContentTitle("旧タイトル")
.setContentText("旧テキスト")
.setTicker("旧ティッカー")
.setSmallIcon(R.drawable.time)
// .setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.drawable.push_kamon))
// .setSound(getAlarmUri())
.setDefaults(defaults)
.setContentIntent(pendingIntent)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.build();

manager.notify(0, notification);

}

}


private void audioStart() {
counter++;
Log.d("debug", "audioStart: " + String.valueOf(counter));

if (mediaPlayer != null) {

// ループ
// mediaPlayer.setLooping(true);

// ループしない
mediaPlayer.setLooping(false);

// 再生する
mediaPlayer.start();

// トースト
// String str = "audioStart";
// Toast toast = Toast.makeText(this, str, Toast.LENGTH_LONG);
// toast.show();

// 終了を検知するリスナー
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
Log.d("debug", "end of audio");

audioStop();

// Service終了
// stopSelf(); // ※これはいらない

}
});
}
}


private void audioStop() {
// 再生終了
mediaPlayer.stop();
// リセット
mediaPlayer.reset();
// リソースの解放
mediaPlayer.release();

mediaPlayer = null;
}


@Override
public void onDestroy() {
super.onDestroy();

Log.d("debug", "onDestroy()");

if (mediaPlayer != null) {
Log.d("debug", "end of audio");
// audioStop(); // なぜか Galaxy だと、音声が途中で止まる
}


// タイマーの 破棄
if (mTimer != null) {
mTimer.cancel();
mTimer = null;
}


// Service 終了
// stopSelf(); // Service は止めない

}


// @Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}


}

■ MainActivity.java

■ Service スタート

private void set_intent(int select_time){

setDate = new Date();
set_msec = setDate.getTime();
set_msec = select_time * 60 * 1000 + set_msec;

final Intent intent = new Intent(getApplicationContext(), TestService.class);
intent.putExtra("REQUEST_CODE", (int)(set_msec / 1000));

// サービス停止
// stopService( new Intent( MainActivity.this, TestService.class ) );
stopService(intent);

// サービス開始
// startService( new Intent( MainActivity.this, TestService.class ) );
startService(intent);

}

■ Notification 通知を消す

/*********************************************/
// ノーティフィケーションの通知アイコンを消す
/*********************************************/
private void delete_notification(){

// ノーティフィケーションの通知を消す
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.cancelAll();

}

■ BroadcastReceiver

import android.content.BroadcastReceiver;

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

// Toast.makeText(getApplicationContext(), "onCreate init_flag = " + String.valueOf(init_flag), Toast.LENGTH_SHORT).show();


// receiver
UpdateReceiver receiver = new UpdateReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction("DO_ACTION");
registerReceiver(receiver, filter);

}

protected class UpdateReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent){
Bundle extras = intent.getExtras();
String msg = extras.getString("message");
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();

switch_layout(2);
}
}

この記事が気に入ったらサポートをしてみませんか?