Androidの起動時にサービスを開始しようとしています


332

Androidでデバイスが起動したときにサービスを開始しようとしましたが、機能しません。私はオンラインでいくつかのリンクを見てきましたが、どのコードも機能しません。何か忘れてる?

AndroidManifest.xml

<receiver
    android:name=".StartServiceAtBootReceiver"
    android:enabled="true"
    android:exported="false"
    android:label="StartServiceAtBootReceiver" >
    <intent-filter>
        <action android:name="android.intent.action._BOOT_COMPLETED" />
    </intent-filter>
</receiver>

<service
    android:name="com.test.RunService"
    android:enabled="true" />

BroadcastReceiver

public void onReceive(Context context, Intent intent) {
    if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
        Intent serviceLauncher = new Intent(context, RunService.class);
        context.startService(serviceLauncher);
        Log.v("TEST", "Service loaded at start");
    }
}

2
私は何をしたのか分からないが、今はうまくいくと思う。レシーバーのandroid:permission = "android.permission.RECEIVE_BOOT_COMPLETED"だったのかもしれない
Alex

<action android:name = "android.intent.action._BOOT_COMPLETED" />の余分な「_」をチェックしましたか
OneWorld

システムがレシーバーを呼び出せるように、Exportedはtrueでなければなりません。それともデフォルトで本当ですか?
Eugen Pechanec 16

回答:


601

他の答えは良さそうですが、私はすべてを1つの完全な答えにまとめると思いました。

AndroidManifest.xmlファイルには次のものが必要です。

  1. あなたの<manifest>要素では:

    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
  2. あなたには<application>要素(あなたのための完全修飾[または相対]クラス名を使用してくださいBroadcastReceiver):

    <receiver android:name="com.example.MyBroadcastReceiver">  
        <intent-filter>  
            <action android:name="android.intent.action.BOOT_COMPLETED" />  
        </intent-filter>  
    </receiver>

    (あなたが必要としないandroid:enabledexportedなど、属性:Androidのデフォルトは正しいです)

    MyBroadcastReceiver.java

    package com.example;
    
    public class MyBroadcastReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            Intent startServiceIntent = new Intent(context, MyService.class);
            context.startService(startServiceIntent);
        }
    }

元の質問から:

  • かどうかは明確ではない<receiver>要素がにあった<application>要素
  • の正しい完全修飾(または相対)クラス名BroadcastReceiverが指定されたかどうかは明確ではありません
  • にタイプミスがあった <intent-filter>

2
これはよさそうだ。私はこれを基礎として使用します、ありがとう:)。悲しげにチェックマークませんかupvotesまたは応答:(誰もがこれを確認します。?
Nanne

51
補足:内部メモリにアプリがインストールされていることを確認してください<manifest xmlns:android = "..." package = "..." android:installLocation = "internalOnly">
Bao Le

2
で述べたように、<受信機>タグ内のAndroid Jellybean 4.2.2で、私は、サービスを開始するために、完全修飾名ではなく、クラスの相対的な名前を使用する必要がありましたstackoverflow.com/questions/16671619/...
Piovezan

6
レシーバーが別のものに使用されている場合:<br> if( "android.intent.action.BOOT_COMPLETED" .equals(intent.getAction())){Intent serviceIntent = new Intent(context、Service_Location.class); // i.putExtra( "KEY1"、 "サービスが使用する値"); context.startService(serviceIntent); }
Gunnar Bernstein

2
代わりにdeveloper.android.com/reference/android/support/v4/content/…を拡張する必要があります。これは、デバイスウェイクアップイベントを受信して​​サービスに処理を渡すBroadcastReceiverを実装する一般的なパターンのヘルパーであり、移行中にデバイスがスリープ状態に戻らないようにします。このクラスは、部分的なwake lockの作成と管理を担当します。これを使用するには、WAKE_LOCK権限を要求する必要があります。
Damian

84

追加情報として:外部ストレージがマウントされる前に BOOT_COMPLETEがアプリケーション送信されます。したがって、アプリケーションが外部ストレージにインストールされている場合、BOOT_COMPLETEブロードキャストメッセージは受信されません。

詳細こちらのセクションのための放送受信機のリスニング「ブートが完了しました」


上記の問題を回避するために、開発者はアプリのマニフェストで「android:installLocation = "internalOnly"を設定できます。それは悪い考えですか?スマートフォンアプリの場合、すべてのユーザーの99.9%(私の推測)がアプリを正常にインストールした場合、外部ストレージではなく内部ストレージを使用することで、マニフェストに「internalOnly」を追加しても問題ないようです。これに関する考えやアイデアはありがたいです
AJW

69

デバイスの起動時にサービスを開始する方法(自動実行アプリなど)

まず、Android 3.1以降のバージョンでは、ユーザーがアプリを1度も起動したことがない場合、またはユーザーが「強制終了」したアプリの場合、BOOT_COMPLETEを受け取りません。これは、マルウェアがサービスを自動的に登録するのを防ぐために行われました。このセキュリティホールは、Androidの新しいバージョンでクローズされました。

解決:

アクティビティのあるアプリを作成します。ユーザーが一度実行すると、アプリはBOOT_COMPLETEブロードキャストメッセージを受信できます。

2番目:外部ストレージがマウントされる前にBOOT_COMPLETEが送信されます。アプリが外部ストレージにインストールされている場合、BOOT_COMPLETEブロードキャストメッセージは受信されません。

この場合、2つの解決策があります。

  1. アプリを内部ストレージにインストールする
  2. 内部ストレージに別の小さなアプリをインストールします。このアプリはBOOT_COMPLETEを受信し、外部ストレージで2番目のアプリを実行します。

アプリが既に内部ストレージにインストールされている場合、以下のコードは、デバイスの起動時にサービスを開始する方法を理解するのに役立ちます。


Manifest.xml内

許可:

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

BOOT_COMPLETEDレシーバーを登録します。

<receiver android:name="org.yourapp.OnBoot">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED"/>
    </intent-filter>
</receiver>

サービスを登録します。

<service android:name="org.yourapp.YourCoolService" />

レシーバーOnBoot.java:

public class OnBoot extends BroadcastReceiver
{

    @Override
    public void onReceive(Context context, Intent intent) 
    {
        // Create Intent
        Intent serviceIntent = new Intent(context, YourCoolService.class);
        // Start service
        context.startService(serviceIntent);

    }

 }

HTCでは、デバイスがRECEIVE_BOOT_COMPLETEDをキャッチしない場合は、マニフェストにこのコードを追加する必要があるかもしれません。

<action android:name="android.intent.action.QUICKBOOT_POWERON" />

レシーバーは次のようになります。

<receiver android:name="org.yourapp.OnBoot">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED"/>
        <action android:name="android.intent.action.QUICKBOOT_POWERON" />
    </intent-filter>
</receiver>

エミュレータや実​​際のデバイスを再起動せずにBOOT_COMPLETEDをテストする方法は?それは簡単です。これを試して:

adb -s device-or-emulator-id shell am broadcast -a android.intent.action.BOOT_COMPLETED

デバイスIDを取得する方法?IDで接続されているデバイスのリストを取得します。

adb devices

ADTのadbはデフォルトで次の場所にあります。

adt-installation-dir/sdk/platform-tools

楽しい!)


最初の段落は資本でした。デバッガーで実行できませんでした。
Estornes 2016

34

に加えて

<action android:name="android.intent.action.BOOT_COMPLETED" />  

また使用し、

<action android:name="android.intent.action.QUICKBOOT_POWERON" />

HTCデバイスはBOOT_COMPLETEDをキャッチしないようです


HTCデバイスのアクセス許可に同様のものを追加する必要がありますか?
ナンダ

2
これは状況によっては役立つかもしれませんが、HTC Fast Bootはシステム状態がファイルシステムに保存される休止状態の一種であり、Fast Boot android.intent.action.QUICKBOOT_POWERONからの復元時にのみ送信されることを理解しています。つまり、高速ブートからの回復時にアラームが保持されているため、アラームをリセットするなどの必要はありません。したがって<action android:name="android.intent.action.QUICKBOOT_POWERON" />、デバイスが起動したとユーザーが思ったときに何かしたい場合にのみ使用する必要があります。
HexAndBugs 2015

2
アプリ開発者の観点からは、動作がHTCデバイスでのみ発生する場合は、これを使用しないでください。なぜなら、BOOT_COMPLETEDは、ドキュメントによると、デバイスがオンになったときに常に送信されるからです。他のメーカーが高速起動の別の方法を考え出す可能性があり、私たちはそれぞれの仕様でコードをめちゃくちゃにすることになります。
Subin Sebastian 2015

@HexAndBugs Fast Bootが、システム状態がファイルシステムに保存される休止状態の形式であることを確認できましたか?システム状態が保存されていない場合、高速起動後の将来の通知に使用されるアラームをリセットできるようにしたい...助言してください。
AJW 2018

20

質問の最初にタイプミスがあることに注意してください:

<action android:name="android.intent.action._BOOT_COMPLETED"/>

の代わりに :

<action android:name="android.intent.action.BOOT_COMPLETED"/>

1つの小さな「_」とこのすべての問題:)


13

私はちょうどそれが> のFast Bootオプションのためかもしれないことをちょうど今知ったSettingsPower

このオプションをオフにすると、アプリケーションはこのブロードキャストを受信しますが、それ以外の場合は受信しません。

ちなみに私は持っAndroid 2.3.3ていHTC Incredible Sます。

それが役に立てば幸い。


間違いなく問題の原因。Android 4.0.3を実行するHTC Desire Cでも観察されました。
ゼリミール2013年


7

上記のすべての回答とトリックを試した後、コードが携帯電話で機能しない理由をようやく見つけました。「Huawei Honor 3C Android 4.2.2」などの一部のAndroidスマートフォンの設定にはStatup Managerメニューがあり、アプリをリストでチェックする必要があります。:)


5

追加の- <category>タグがありますが、違いがあるかどうかはわかりません。

<receiver android:name="BootIntentReceiver">  
        <intent-filter>  
            <action android:name="android.intent.action.BOOT_COMPLETED" />  
            <category android:name="android.intent.category.HOME" />  
        </intent-filter>  
</receiver>

"android.intent.action.BOOT_COMPLETED".equals(intent.getAction()とにかくレシーバーがそのインテントのみを受け取るため、if-clauseを省略してみましたか?


試してみましたが、うまくいきませんでした。<uses-permission android:name = "android.permission.RECEIVE_BOOT_COMPLETED" />
Alex

2
念のため:AndroidManifestのタグにandroid.intent.category.HOMEを追加すると、Hackを使用して互換モードをオフにした後でも、Samsung Galaxy Tabが互換モードでアプリを実行します。これが他のタブでも同じかどうかはわかりません。HOMEカテゴリーは一切設定しないことをお勧めします。不要です。
moonlightcheese


3

外部ストレージをマウントする前にBOOT_COMPLETEが送信されます。アプリが外部ストレージにインストールされている場合、BOOT_COMPLETEブロードキャストメッセージは受信されません。これを防ぐには、アプリケーションを内部ストレージにインストールします。あなたはmenifest.xmlにこの行を追加するだけでこれを行うことができます

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:installLocation="internalOnly"
... >

一部のHTCデバイスは、実際の再起動ではなくディープハイバネーションのような「高速ブート」機能を有効にできるため、BOOT_COMPLETEインテントを与えるべきではありません。これを回復するには、レシーバー内にこのインテントフィルターを追加できます。

            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <action android:name="android.intent.action.QUICKBOOT_POWERON" />
            </intent-filter>

あなたが示唆するように、上記の問題を防ぐために、開発者はアプリのマニフェストに「android:installLocation = "internalOnly"を設定できます。それは悪い考えですか?スマートフォンアプリの場合、すべてのユーザーの99.9%(私の推測)外部ストレージではなく内部ストレージを使用してアプリを通常どおりインストールすると、マニフェストに「internalOnly」を追加しても問題ないようです。これについてのご意見やご感想をお寄せください。– AJW
AJW

3

これは私がやったことです

1.レシーバークラスを作成しました

public class BootReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        //whatever you want to do on boot
       Intent serviceIntent = new Intent(context, YourService.class);
       context.startService(serviceIntent);
    }
}

2.マニフェスト

<manifest...>
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    <application...>
        <receiver android:name=".BootReceiver" android:enabled="true" android:exported="false">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>
    ...

3.MainActivityでレシーバを「設定」する必要があるすべての後、それはonCreate内にある可能性があります

...
 final ComponentName onBootReceiver = new ComponentName(getApplication().getPackageName(), BootReceiver.class.getName());
        if(getPackageManager().getComponentEnabledSetting(onBootReceiver) != PackageManager.COMPONENT_ENABLED_STATE_ENABLED)
        getPackageManager().setComponentEnabledSetting(onBootReceiver,PackageManager.COMPONENT_ENABLED_STATE_ENABLED,PackageManager.DONT_KILL_APP);
...

私がApiDemosから学んだ最後のステーキ


2

Android Studioを使用していて、オートコンプリートが非常に好きな場合は、通知する必要があります。AndroidStudio v 1.1.0を使用していて、次の権限でオートコンプリートを使用しました

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

そして、Android StudioはRECEIVE_BOOT_COMPLETEDすべて小文字のようにすべてオートコンプリートし、receive_boot_completed起動時にサービスを開始するためのチェックリストをすでにチェックしていたので、髪を抜いていきました。もう一度確認しました

Android Studioは、この権限を小文字でオートコンプリートします。


2

@Damianがコメントしたように、このスレッドの答えはすべて間違っています。このように手動で行うと、デバイスがスリープ状態になる途中でサービスが停止するリスクがあります。最初にwake lockを取得する必要があります。幸い、サポートライブラリは、これを行うクラスを提供します。

public class SimpleWakefulReceiver extends WakefulBroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        // This is the Intent to deliver to our service.
        Intent service = new Intent(context, SimpleWakefulService.class);

        // Start the service, keeping the device awake while it is launching.
        Log.i("SimpleWakefulReceiver", "Starting service @ " + SystemClock.elapsedRealtime());
        startWakefulService(context, service);
    }
}

次に、サービスで、必ずウェイクロックを解放します。

    @Override
    protected void onHandleIntent(Intent intent) {
        // At this point SimpleWakefulReceiver is still holding a wake lock
        // for us.  We can do whatever we need to here and then tell it that
        // it can release the wakelock.

...
        Log.i("SimpleWakefulReceiver", "Completed service @ " + SystemClock.elapsedRealtime());
        SimpleWakefulReceiver.completeWakefulIntent(intent);
    }

WAKE_LOCKパーミションをメインフェストに追加することを忘れないでください:

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

少し疑問があります。私のサービスサービスIntentServiceではない場合、この方法は使用できません。単純なサービスではonHandleIntendメソッドをオーバーライドできないためです。
paolo2988 2015

私も同じ問題を抱えています。手伝ってくれませんか?ありがとう!stackoverflow.com/questions/35373525/starting-my-service
Ruchir Baronia

たぶん使用onNewIntent()?または、IntentServiceのソースを確認し、サービスを一致させるために何をする必要があるかを確認することもできます...
phreakhead

1

実際、私は少し前にこの問題に遭遇しました、そしてそれは修正するのは本当に本当に簡単です、あなたが"android.intent.action.BOOT_COMPLETED"パーミッションとインテントフィルターをセットアップするならば、あなたは実際には何も間違っていません。

Android 4.Xの場合、起動時にサービスを開始する前にブロードキャストリスナーを実行する必要があることに注意してください。つまり、まずアクティビティを追加し、ブロードキャストレシーバーが実行されたら、アプリは期待どおりに機能するはずです。しかし、Android 4.Xでは、アクティビティなしで起動時にサービスを開始する方法が見つかりませんでした。セキュリティ上の理由から、Googleがそれを行ったと思います。


0

レシーバークラスに空のコンストラクターを残した場合、この問題に直面しました。空のコントローラーを削除した後、onRreceiveメソッドは正常に動作し始めました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.