質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.51%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Q&A

解決済

1回答

13654閲覧

AndroidでService内で発行したTimerが端末スリープ状態で勝手に止まる

peishun

総合スコア30

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

0グッド

0クリップ

投稿2016/04/22 06:41

AndroidでServiceを用いて秒単位でカウントダウン処理を行い、Receiverを用いてその値を受け、Activity側でカウントダウン値を表示しています。
端末がスリープ状態でも動作するようにServiceを用いているのですが、端末がスリープするとなぜかカウントダウンが数秒〜数十秒後に止まってしまします。

Nortificationを作成してstartForegroundをしてシステムからキルされづらくしたり、WakeLockを取得してCPUを常に起動させたりといった対策はしたのですが解決しません。

以下にソースコードを記載します。どなたか解決策を提示していただけないでしょうか?

「Service」のソースコードは以下です

java

1package jp.wings.nikkeiibp.napalerm.Process; 2 3import android.app.IntentService; 4import android.app.Notification; 5import android.app.NotificationManager; 6import android.app.PendingIntent; 7import android.app.Service; 8import android.content.Context; 9import android.content.Intent; 10import android.os.IBinder; 11import android.os.PowerManager; 12import android.support.annotation.Nullable; 13import android.support.v4.app.NotificationCompat; 14import android.util.Log; 15 16import java.util.Timer; 17import java.util.TimerTask; 18 19import jp.wings.nikkeiibp.napalerm.Activity.CountDownActivity; 20import jp.wings.nikkeiibp.napalerm.Common.IntentKeyWord; 21import jp.wings.nikkeiibp.napalerm.R; 22 23 24public class TimerService extends Service { 25 26 //タイマー処理を行うオブジェクト 27 private Timer mTimer = null; 28 29 /** スリープ時のスクリーン及びCPUの制御を行うオブジェクト */ 30 private PowerManager.WakeLock mWakeLock; 31 32 /** 設定した秒数 */ 33 private int mTimerSeconds; 34 35 @Override 36 public void onCreate() { 37 super.onCreate(); 38 39 //CPUやスリープ画面の制御オブジェクト取得 40 PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE); 41 mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Cowntdown_Start"); 42 43 //CPUを常にON状態にするのを開始(releaseするまで終了しない) 44 mWakeLock.acquire(); 45 46 } 47 48 @Nullable 49 @Override 50 public IBinder onBind(Intent intent) { 51 return null; 52 } 53 54 @Override 55 public int onStartCommand ( Intent intent, int flags, int startId ) { 56 57 //カウントダウンする時間を取得 58 mTimerSeconds = intent.getIntExtra ( IntentKeyWord.SET_SECONDS, 0 ); 59 Log.i ( "TimerService getSecond", "" + mTimerSeconds ); 60 61 //通知を作成 62 Notification notification = new NotificationCompat.Builder(this) 63 .setContentTitle(getString(R.string.nortification_title)) 64 .setContentText(getString(R.string.nortification_text)) 65 .setSmallIcon(R.mipmap.ic_launcher) 66 .build(); 67 68 69 //通知削除不可にする 70 notification.flags = Notification.FLAG_ONGOING_EVENT; 71 72 //通知マネージャー取得 73 NotificationManager manager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE); 74 75 //通知識別ID 76 final int NUM = 1; 77 78 //通知発行 79 manager.notify(NUM, notification); 80 81 //システムから殺されにくくする 82 startForeground(NUM,notification); 83 84 // タイマーの設定 1秒毎にループ 85 mTimer = new Timer (); 86 mTimer.schedule ( new TimerTask () { 87 @Override 88 public void run () { 89 //カウントダウン 90 mTimerSeconds--; 91 //レシーバーに通知 92 sendBroadCast(); 93 } 94 }, 1000, 1000 ); 95 96 return START_STICKY; 97 98 } 99 100 @Override 101 public void onDestroy () { 102 mWakeLock.release(); 103 // タイマー停止 104 if( mTimer != null ){ 105 mTimer.cancel(); 106 mTimer = null; 107 } 108 super.onDestroy (); 109 } 110 111 /** 112 * レシーバーに値を渡す 113 */ 114 protected void sendBroadCast() { 115 116 Intent broadcastIntent = new Intent(); 117 broadcastIntent.putExtra(IntentKeyWord.SET_SECONDS, mTimerSeconds); 118 Log.i ( "sendBroadCast setSecond", "" + mTimerSeconds ); 119 120 broadcastIntent.setAction("UPDATE_ACTION"); 121 getBaseContext().sendBroadcast(broadcastIntent); 122 } 123} 124

「Receiver」のソースコードは以下です

java

1package jp.wings.nikkeiibp.napalerm.Process; 2 3import android.content.BroadcastReceiver; 4import android.content.Context; 5import android.content.Intent; 6import android.os.Bundle; 7import android.os.Handler; 8import android.os.Message; 9import android.util.Log; 10 11import jp.wings.nikkeiibp.napalerm.Common.IntentKeyWord; 12 13public class TimerReceiver extends BroadcastReceiver{ 14 15 /** サービスから値を受け取ったときに動かす非同期処理 */ 16 public static Handler handler; 17 18 @Override 19 public void onReceive ( Context context, Intent intent ) { 20 21 Bundle getbundle = intent.getExtras (); 22 int seconds = getbundle.getInt ( IntentKeyWord.SET_SECONDS ); 23 Log.i ( "TimerReceiver getSecond", "" + seconds ); 24 25 if(handler !=null){ 26 27 Message msg = new Message(); 28 29 Bundle setbundle = new Bundle(); 30 31 setbundle.putInt ( IntentKeyWord.SET_SECONDS, seconds); 32 Log.i ( "TimerReceiver setSecond", "" + seconds ); 33 34 msg.setData(setbundle); 35 36 handler.sendMessage(msg); 37 } 38 } 39 40 /** 41 * 値受け取り時に実行する非同期処理の登録 42 */ 43 public void registerHandler(Handler handler) { 44 this.handler = handler; 45 } 46} 47

カウントダウンを表示するActivityのソースコードは以下

java

1 2public class CountDownActivity extends Activity { 3 4 /** サービスから値を受け取るレシーバー */ 5 private TimerReceiver mTimerReceiver; 6 7 /** 暗黙的インテントの値を受け取る際のフィルター */ 8 private IntentFilter mIntentFilter; 9 10 /** カウントダウン表示用テキスト */ 11 private TextView mCountText; 12 13 /** 時間をカウントダウンするサービス */ 14 private Intent mService; 15 16 @Override 17 protected void onCreate ( Bundle savedInstanceState ) { 18 super.onCreate ( savedInstanceState ); 19 setContentView ( R.layout.activity_count_down ); 20 21 mCountText = (TextView )findViewById( R.id.countDownText); 22 23 //インテントから値を取得 24 mService = new Intent(this , TimerService.class); 25 int time = getIntent ().getIntExtra ( IntentKeyWord.SET_SECONDS, 0 ); 26 27 //時分秒を計算 28 final int hour = time / 3600; 29 final int minute = ( time % 3600 ) / 60; 30 final int second = ( time % 3600 ) % 60; 31 32 //初期秒数をテキストに表示 33 setCountText(hour,minute,second); 34 35 //0時間0分の場合+1秒(マイナスにカウントし始めるのを防ぐ) 36 if(time == 0) 37 time = 1; 38 39 //サービスに秒数をセット 40 mService.putExtra ( IntentKeyWord.SET_SECONDS, time ); 41 Log.i ( "service setSecond", "" + time ); 42 43 //タイマーサービス開始 44 startService ( mService ); 45 46 //サービスのレシーバーをセット 47 setReceiver (); 48 49 } 50 51 @Override 52 protected void onDestroy() { 53 super.onDestroy(); 54 stopService(mService); 55 } 56 57 /** 58 * レシーバーをセット 59 * レシーバーはサービスから値を受け取るもの 60 */ 61 private void setReceiver(){ 62 mTimerReceiver = new TimerReceiver (); 63 mIntentFilter = new IntentFilter (); 64 mIntentFilter.addAction ( "UPDATE_ACTION" ); 65 registerReceiver ( mTimerReceiver, mIntentFilter ); 66 67 mTimerReceiver.registerHandler ( updateHandler ); 68 } 69 70 /** 71 * サービスから値を受け取った際の更新処理 72 */ 73 private Handler updateHandler = new Handler() { 74 @Override 75 public void handleMessage(Message msg) { 76 77 Bundle bundle = msg.getData (); 78 int time = bundle.getInt ( IntentKeyWord.SET_SECONDS ); 79 80 //カウントダウンが完了した 81 if(time == 0){ 82 83 //サービス終了 84 stopService(mService); 85 86 //次のアクティビティへ 87 goNotificaionAlert(); 88 89 }else{ 90 91 final int hour = time / 3600; 92 final int minute = ( time % 3600 ) / 60; 93 final int second = ( time % 3600 ) % 60; 94 95 //カウントダウン表示更新 96 setCountText(hour,minute,second); 97 98 } 99 } 100 }; 101 102 103 /** 104 * カウントダウンテキストをセットする 105 * @param hour 時間 106 * @param minute107 * @param second108 */ 109 private void setCountText(int hour,int minute,int second){ 110 mCountText.setText ( String.format ( "%02d",hour ) + 111 ":" + String.format ( "%02d",minute ) + 112 ":" + String.format ( "%02d",second )); 113 } 114 115 116} 117

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

https://groups.google.com/forum/#!topic/android-group-japan/OMGp8_9A5HE

上記に同じ現象で解決案も載ってます

投稿2016/04/26 13:26

dekaaki

総合スコア292

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.51%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問