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

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

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

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

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

Kotlin

Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。

Q&A

解決済

1回答

4100閲覧

Service()起動数秒後にアプリが落ちる

kakashi55

総合スコア25

Android

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

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

Kotlin

Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。

0グッド

0クリップ

投稿2021/11/12 14:17

○やりたいこと
Serviceのバックグラウンド挙動を安定させるためActivityとServiceを連携させる

○課題
以下サイトをもとに、ActivityとServiceの連携をおこなっております。

参考サイト
https://qiita.com/satken2/items/49dd76d848ceb208e937

しかし、以下エラーが発生しService起動数秒後にアプリが落ちます。

2021-11-12 23:03:18.165 1720-24063/? E/ActivityManager: ANR in com.example.servicetest PID: 23934 Reason: Context.startForegroundService() did not then call Service.startForeground(): ServiceRecord{1ee86ba u0 com.example.servicetest/.MyService}

○教えていただきたいこと
エラーが発生する原因を理解し、改善方法を教えていただきたいです。

MainActivity

1const val MSG_ACTIVITY_TO_SERVICE = 1 2const val MSG_SERVICE_TO_ACTIVITY = 2 3 4class MainActivity : AppCompatActivity() { 5 private var bound = false 6 private var mActivityMessenger: Messenger? = null 7 private var mServiceMessenger: Messenger? = null 8 private var mActivityHandler: ActivityHandler? = null 9 10 private val mConnection = object: ServiceConnection { 11 override fun onServiceConnected(name: ComponentName?, binder: IBinder?) { 12 mServiceMessenger = Messenger(binder) 13 try { 14 val msg = Message.obtain(null, MSG_ACTIVITY_TO_SERVICE, 0, 0) 15 msg.replyTo = mActivityMessenger 16 mServiceMessenger!!.send(msg) 17 } catch (e: RemoteException) { 18 e.printStackTrace() 19 } 20 bound = true 21 } 22 23 override fun onServiceDisconnected(name: ComponentName?) { 24 mServiceMessenger = null 25 bound = false 26 } 27 } 28 29 internal class ActivityHandler( 30 activity: MainActivity 31 ) : Handler() { 32 //define weak reference to activity 33 private val mActivity = WeakReference<MainActivity>(activity) 34 35 override fun handleMessage(msg: Message) { 36 when (msg.what) { 37 MSG_SERVICE_TO_ACTIVITY ->{ 38 //something 39 } 40 else -> super.handleMessage(msg) 41 } 42 } 43 } 44 45 override fun onCreate(savedInstanceState: Bundle?) { 46 Log.d("debug", "onCreate() mainactivity") 47 super.onCreate(savedInstanceState) 48 setContentView(R.layout.activity_main) 49 50 mActivityHandler = ActivityHandler(this) 51 mActivityMessenger = Messenger(mActivityHandler) 52 53 findViewById<Button>(R.id.start).setOnClickListener { 54 Log.d("debug","btnTapped") 55 if(bound) { 56 Log.d("debug", "bound = ture") 57 try { 58 val msg = Message.obtain(null, MSG_ACTIVITY_TO_SERVICE, 0, 0) 59 //val msg = Message.obtain(null, MSG_STOP_UTTERANCE, 0, 0) 60 msg.replyTo = mActivityMessenger 61 mServiceMessenger!!.send(msg) 62 63 intentGo() 64 65 } catch (e: RemoteException) { 66 e.printStackTrace() 67 } 68 } else { 69 Log.d("debug", "bound = false") 70 } 71 } 72 } 73 74 fun intentGo() { 75 Log.d("debug", "intentGo") 76 //start service 77 Intent(this, MyService::class.java).also { 78 Log.d("debug", "Intent") 79 it.action = ACTION_SET_TIMER 80 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { 81 Log.d("debug", "startForegroundService") 82 startForegroundService(it) 83 return 84 } 85 startService(it) 86 } 87 } 88 89 override fun onStop() { 90 Log.d("debug", "onStop") 91 super.onStop() 92 //unbind from the service 93 if(bound){ 94 unbindService(mConnection) 95 bound = false 96 } 97 } 98 99 override fun onStart(){ 100 Log.d("debug", "onStart") 101 super.onStart() 102 //bind to the service 103 Intent(this, MyService::class.java).also{ intent -> 104 bindService(intent, mConnection, Context.BIND_AUTO_CREATE) 105 } 106 } 107}

MyService

1class MyService: Service() { 2 private var mServiceMessenger: Messenger? = null 3 4 internal class ServiceHandler( 5 service: MyService 6 ) : Handler() { 7 private val mService = WeakReference<MyService>(service) 8 9 override fun handleMessage(msg: Message) { 10 when (msg.what) { 11 MSG_ACTIVITY_TO_SERVICE ->{ 12 //return some value 13 try { 14 val msg2 = Message.obtain(null, MSG_SERVICE_TO_ACTIVITY, 0, 0) 15 msg.replyTo.send(msg2) 16 } catch (e: RemoteException) { 17 e.printStackTrace() 18 } 19 } 20 else -> super.handleMessage(msg) 21 } 22 } 23 } 24 25 override fun onBind(intent: Intent?): IBinder { 26 Log.d("debug", "onBind") 27 mServiceMessenger = Messenger(ServiceHandler(this)) 28 return mServiceMessenger!!.binder 29 } 30 31 override fun onCreate() { 32 Log.d("debug", "onCreate service") 33 super.onCreate() 34 } 35 36 override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { 37 Log.d("debug", "onStartCommand") 38 39 Thread.sleep(1000) 40 41 val notification = NotificationCompat.Builder(this).apply { 42 var mContentTitle = "通知のタイトル" 43 var mContentText = "通知の内容" 44 setSmallIcon(R.mipmap.ic_launcher) 45 }.build() 46 47 startForeground(0, notification) 48 Log.d("debug", "startForeground") 49 50 return Service.START_NOT_STICKY 51 } 52}

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

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

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

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

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

jimbe

2021/11/13 04:59

ご提示のコードを AndroidStudio で Empty Activity を元にしたプロジェクトに張り付けて実行しましたが、 android:id="@+id/start" とレイアウトしたボタンを押しても D/debug: onCreate() mainactivity D/debug: onStart D/debug: btnTapped D/debug: bound = false とログに出るだけで何も起きません。 ご提示のコード以外にどうすれば再現出来るでしょうか。
jimbe

2021/11/13 05:05

失礼しました、AndroidManifest に service を入れるのを忘れていました。
guest

回答1

0

ベストアンサー

テストしていませんので見た目だけですが、 ANR で did not then call Service.startForeground() ですので、 Thread.sleep(1000) がいけないのではないでしょうか。
onStartCommand() は時間のかかる処理はしてはいけないと思います。


メッセージの部分はさておき、まずは以下等は如何でしょうか。
Android - Foreground Service実行

startForegroundService()でNotification登録

startForegroundService()でサービスが実行されると、実行されたサービスは、5秒以内に startForeground()を呼び出して、サービスが実行中であるNotificaitonを登録する必要があります。もし呼び出さない場合、システムはサービスを強制的に終了させます。

Service.startForeground()は次のように Notificaiton IDとNotificaitonオブジェクトを引数として受け取ります。 注意すべき点は、IDで0を渡すと、動作がないということです。 0以外の数字をIDで渡す必要があります。

Android O(API 26)以上のバージョンでNotificationを登録する前に、Notificaiton Channelを登録する必要があります。

といった記述があります。

投稿2021/11/12 17:39

編集2021/11/13 05:41
jimbe

総合スコア12648

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

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

kakashi55

2021/11/12 22:52

ご回答いただきありがとうございます。 Thread.sleep(1000) をコメントアウトしても同エラーが発生してしまいます。 その他の点でエラーを起こしている原因と対策方法がございましたら教えていただけないでしょうか。
kakashi55

2021/11/13 07:49

IDで0を渡すと、動作がないということです。 0以外の数字をIDで渡す必要があります。 →まさしくここを改善しましたら動作しました。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問