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

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

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

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

Android

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

Q&A

1回答

4357閲覧

Android のService+Receiver が端末スリープして数秒後に止まる

peishun

総合スコア30

Java

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

Android

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

0グッド

1クリップ

投稿2016/04/21 02:33

編集2016/04/21 05:55

AndroidでService+Receiverを実装しています。なぜかというとバックグランドでタイマー処理を実現したいからです。

Secerviceが1秒ごとに時間をカウントダウンして、Receiverがその値を取得してActivityに通知し、カウントダウンの様子を画面に表示するという処理をしています。

しかし、この時の電源ボタンを押してスリープ状態にすると30秒ぐらいでカウントダウンが止まってしまいます。
ちなみに、Android studioを起動したPCに接続してUSBデバッグモードで同じことをするとなぜかカウントダウンが止まりません。

Nortificationを作成し、startForgroundの実行等も行ってみましたが、解決しませんでした。

この現象に、どんな原因もしくはどんな対処法が考えられるでしょうか?

サービスのソースコードは以下のようになっています。

java

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

レーシーバは以下のようになっています

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}

カウントダウンを表示するアクティビティは以下の通りになっています

java

1package jp.wings.nikkeiibp.napalerm.Activity; 2 3import android.annotation.TargetApi; 4import android.app.Activity; 5import android.app.Service; 6import android.content.DialogInterface; 7import android.content.Intent; 8import android.content.IntentFilter; 9import android.graphics.Color; 10import android.graphics.Typeface; 11import android.media.AudioAttributes; 12import android.media.AudioManager; 13import android.media.MediaPlayer; 14import android.media.SoundPool; 15import android.os.Build; 16import android.os.Bundle; 17import android.os.Handler; 18import android.os.Message; 19import android.support.annotation.RawRes; 20import android.support.v4.app.NotificationManagerCompat; 21import android.support.v7.app.AlertDialog; 22import android.support.v7.app.NotificationCompat; 23import android.util.Log; 24import android.view.KeyEvent; 25import android.view.View; 26import android.view.WindowManager; 27import android.widget.TextView; 28import android.widget.Toast; 29 30import com.google.android.gms.ads.AdRequest; 31import com.google.android.gms.ads.AdView; 32 33import jp.wings.nikkeiibp.napalerm.Common.IntentKeyWord; 34import jp.wings.nikkeiibp.napalerm.Process.TimerReceiver; 35import jp.wings.nikkeiibp.napalerm.Process.TimerService; 36import jp.wings.nikkeiibp.napalerm.R; 37 38public class CountDownActivity extends Activity { 39 40 /** サービスから値を受け取るレシーバー */ 41 private TimerReceiver mTimerReceiver; 42 43 /** 暗黙的インテントの値を受け取る際のフィルター */ 44 private IntentFilter mIntentFilter; 45 46 /** カウントダウン表示用テキスト */ 47 private TextView mCountText; 48 49 /** 時間をカウントダウンするサービス */ 50 private Intent mService; 51 52 @Override 53 protected void onCreate ( Bundle savedInstanceState ) { 54 super.onCreate ( savedInstanceState ); 55 setContentView ( R.layout.activity_count_down ); 56 57 mCountText = (TextView )findViewById( R.id.countDownText); 58 59 //インテントから値を取得 60 mService = new Intent(this , TimerService.class); 61 int time = getIntent ().getIntExtra ( IntentKeyWord.SET_SECONDS, 0 ); 62 63 //時分秒を計算 64 final int hour = time / 3600; 65 final int minute = ( time % 3600 ) / 60; 66 final int second = ( time % 3600 ) % 60; 67 68 //初期秒数をテキストに表示 69 setCountText(hour,minute,second); 70 71 //サービスに秒数をセット 72 mService.putExtra ( IntentKeyWord.SET_SECONDS, time ); 73 Log.i ( "service setSecond", "" + time ); 74 75 //タイマーサービス開始 76 startService ( mService ); 77 78 //サービスのレシーバーをセット 79 setReceiver (); 80 81 } 82 83 @Override 84 protected void onDestroy() { 85 super.onDestroy(); 86 stopService(mService); 87 } 88 89 /** 90 * レシーバーをセット 91 * レシーバーはサービスから値を受け取るもの 92 */ 93 private void setReceiver(){ 94 mTimerReceiver = new TimerReceiver (); 95 mIntentFilter = new IntentFilter (); 96 mIntentFilter.addAction ( "UPDATE_ACTION" ); 97 registerReceiver ( mTimerReceiver, mIntentFilter ); 98 99 mTimerReceiver.registerHandler ( updateHandler ); 100 } 101 102 /** 103 * サービスから値を受け取った際の更新処理 104 */ 105 private Handler updateHandler = new Handler() { 106 @Override 107 public void handleMessage(Message msg) { 108 109 Bundle bundle = msg.getData (); 110 int time = bundle.getInt ( IntentKeyWord.SET_SECONDS ); 111 112 //カウントダウンが完了した 113 if(time == 0){ 114 115 //サービス終了 116 stopService(mService); 117 118 //カウントダウンの文字を00:00:00にする 119 setCountText(0,0,0); 120 121 //文字の色を変える 122 mCountText.setTextColor(Color.RED); 123 124 //文字を太くする 125 mCountText.setTypeface(Typeface.DEFAULT_BOLD); 126 127 //次のアクティビティへ 128 goNotificaionAlert(); 129 130 }else{ 131 132 final int hour = time / 3600; 133 final int minute = ( time % 3600 ) / 60; 134 final int second = ( time % 3600 ) % 60; 135 136 //カウントダウン表示更新 137 setCountText(hour,minute,second); 138 139 } 140 } 141 }; 142}

ちなみにマニュフェストファイルには以下の記述をしております。

xml

1<application 2 3 ・・・・・・・・・・・ 4 5 <service android:name=".Process.TimerService" /> 6 <receiver android:name=".Process.TimerReceiver" /> 7 8 9 ・・・・・・・・・・ 10</application>

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

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

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

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

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

aja

2016/04/21 03:39

カウントダウンをどのようにしているのでしょうか? コードを出してもらわないと...
peishun

2016/04/21 05:57

大変失礼いたしました。コードの追記をいたしました
guest

回答1

0

スリープの次にサスペンド(ディープスリープ)と呼ばれる状態があります。

スリープでは、画面表示は消えますが、まだCPUが完全に動いている状態で、
サスペンドでは、CPUの動作も制限し、最低限の機能だけ動かしている状態です。

USBデバッグ中は、このサスペンド状態に入ることがないみたいです。
(LogCatとか、デバッガーとか動かしているので、
CPUの動作を制限することが出来ないんでしょうかね?詳しくは分かりません)

USBデバッグを接続していない状態で、サスペンドにさせたくない場合は、
アプリ側から、WakeLockをPARTIAL_WAKE_LOCKで取得しておけば、
電源ボタンが押されても、サスペンドに移行させないことが出来たと思います。

投稿2016/04/21 05:39

abs123

総合スコア1280

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

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

peishun

2016/04/21 07:45 編集

解決したかと思ったのですが、まだ上手くいかなかったです。しかしサスペンドという状態が存在することが初耳だったので勉強になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問