web-dev-qa-db-ja.com

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

私はデバイスが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");
    }
}
325
Alex

他の答えはよく見えますが、私はすべてを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>にタイプミスがありました
599
Timo Bruck

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

詳細 ここ セクションの中の=="受信完了"を聞いている放送受信機

83
inazaruk

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

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

溶液:

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

秒の場合:外部ストレージがマウントされる前に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

楽しい! )

66
user3439968

に加えて

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

また使う

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

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

34
Tony

質問の冒頭で、タイプミスがあることに注意してください。

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

の代わりに :

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

一つの小さな "_"とすべてのこの問題:)

20
Evgeny Erlihman

Settings> PowerFast Bootオプションが原因である可能性があることを私は今すぐ知りました

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

ところで、私はAndroid 2.3.3の上にHTC Incredible Sがあります。

それが役に立てば幸い。

13
Omer Akhter

あなたのマニフェストには、追加する必要があると思います。

<uses-permission Android:name="Android.permission.RECEIVE_BOOT_COMPLETED" />
12
RickNotFred

言及された答えとトリックのすべてを試みた後、私はようやくコードが私の電話で働かない理由を見つけます。 「Huawei Honor 3C Android 4.2.2」のようなAndroid携帯には、設定にStatup Managerメニューがあり、リストでアプリケーションをチェックする必要があります。 :)

6
Amir

私は追加の<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>

とにかく、レシーバはその意図を受け取るだけなので、if句の"Android.intent.action.BOOT_COMPLETED".equals(intent.getAction()を省略してみましたか?

5
Nick

このリンクを参照してください http://khurramitdeveloper.blogspot.in/2013/06/start-activity-or-service-on-boot.html サービスでブートを使用するためのステップ手順

4
Jaichander

外部ストレージをマウントする前に、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>
3

Android St​​udioを使用していて、オートコンプリートが非常に好きな場合は、Android St​​udio v 1.1.0を使用していることをお知らせする必要があります。次の許可が必要です

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

Android St​​udioオートコンプリートRECEIVE_BOOT_COMPLETEDすべてreceive_boot_completedのように小文字で、サービスを開始するためのチェックリストにチェックを入れたので、髪を引っ張り続けました。起動時に。もう一度確認しました

Android Studioは、この許可を小文字で自動補完します。

2
Haroon Dilshad

これは私がしたことです

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>
    ...

.そして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
San Juan

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

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);
    }
}

次に、あなたのサービスで、必ずwakeロックを解除します。

    @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" />
2
phreakhead

実際、私は昔からこの問題に遭遇していますが、本当に簡単に修正できます。"Android.intent.action.BOOT_COMPLETED"パーミッションとintent-filterを設定すれば、実際には何も問題はありません。

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

1
David Hx

私はレシーバクラスに空のコンストラクタを残す場合、私はこの問題に直面しました。空のコンサルタントを削除した後、onRreceive methosはうまく働き始めました。

0
redrom