web-dev-qa-db-ja.com

アプリが強制停止された場合でもサービスを再起動し、アプリを閉じた後もバックグラウンドでサービスを実行し続ける方法は?

バックグラウンドでサービスを実行しようとしています。私のアプリは、ユーザーがチェックボックスをオンにするとサービスが開始し、オフにするとサービスが停止します。これは完全に正常に機能しています。しかし、問題は、タスクマネージャーからアプリを閉じると、サービスも停止することです。私が欲しいのは、タスクマネージャーから閉じた後もサービスを実行し続けることです。次に、そのサービスを停止する唯一の方法は、ユーザー自身がボックスをチェック解除することです。

どうすればこれを達成できますか?

これが私のコードです

私の主な活動

public class SampleServiceActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    final CheckBox cb = (CheckBox) findViewById(R.id.checkBox1);

    cb.setOnCheckedChangeListener(new OnCheckedChangeListener() {
        public void onCheckedChanged(CompoundButton buttonView,
                boolean isChecked) {

            if(isChecked) {
                Toast.makeText(getBaseContext(), "Checked", Toast.LENGTH_LONG).show();
                startService(new Intent(getBaseContext(), MyService.class));
            } else {
                Toast.makeText(getBaseContext(), "Unchecked", Toast.LENGTH_LONG).show();
                stopService(new Intent(getBaseContext(), MyService.class));
            }
        }

    });
}
}

私のサービスクラス

public class MyService extends Service {
Notify n = new Notify();
@Override
public IBinder onBind(Intent arg0) {
    // TODO Auto-generated method stub
    return null;
}

public int onStartCommand(Intent intent, int flags, int startId) {
    Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
    n.initNotification(getBaseContext(), true);
    return START_STICKY;
}

//method to stop service
public void onDestroy() {
    super.onDestroy();
    n.cancelNotification(getBaseContext());
    Toast.makeText(this, "Service Stopped", Toast.LENGTH_LONG).show();
}
}

更新

このサービスを作成して、gtalkサービスのように実行するにはどうすればよいですか?

18
Om3ga

しかし、問題は、タスクマネージャーからアプリを閉じると、サービスも停止することです。

正しい。

私が欲しいのは、タスクマネージャーから閉じた後もサービスを実行し続けることです。次に、そのサービスを停止する唯一の方法は、ユーザー自身がボックスをチェック解除することです。

サービスをC/C++で実装し、それをいくつかのカスタムファームウェアに組み込み、そのファームウェアをデバイスにインストールするように人々を説得することができます。

Gtalkをインストールしてサインインすると、タスクマネージャーのアクティブなアプリケーションタブに表示されません。ただし、バックグラウンドで実行されます。

これはファームウェアの一部です。

7
CommonsWare

このリンクが役立つと思います。
アプリケーションの管理で強制停止ボタンを無効にする

パッケージインストーラー設定の[強制停止]ボタンを無効にして、誰もアプリケーションを停止できないようにします。

5
PrashantAdesara

すべての状況下でサービスが強制終了されるのを防ぐことはできません。ただし、システムに再起動するように要求できます。 2つのケースがあります:(1)何らかの異常な理由でプロセスが停止する(2)電話が再起動する。前者では、START_STICKYまたはSTART_REDELIVER_INTENTを使用してサービスを再起動します。後者では、Android.intent.action.BOOT_COMPLETEDのBroadcastReceiverを追加する必要があります。

コードはonStartCommandからSTART_STICKYを返しているので、サービス再開パスの1つを選択しました:「このサービスの開始中に(onStartCommand(Intent、int、int)から戻った後)このサービスのプロセスが強制終了された場合は、そのままにしておきます。開始状態ですが、この配信されたインテントを保持しません。後でシステムはサービスを再作成しようとします...」

「このモードは、バックグラウンドミュージックの再生を実行するサービスなど、明示的に開始および停止されて任意の期間実行されるものに適しています。」

START_REDELIVER_INTENTを使用することもできます。

サービスが重要な作業を行っている場合は、バックグラウンドスレッドで実行する必要があることに注意してください。

http://developer.Android.com/reference/Android/app/Service.html#START_STICKY

2

TaskManagerによってアプリが閉じられるのを防ぐことができるかどうかは完全にはわかりません。あなたがそれについて考えるならば、それがそのようであることは理にかなっています。ユーザー入力に応答せず、タスクマネージャーによる強制終了にも応答しないアプリがあるとします。良くない。しかし、私は this の質問を見つけました。これはあなたの質問に似ています。また、説明に従ってシステムに自動的にサービスを再起動させることもできます ここ(そのページを少し下にスクロールして、「サービスを開始する」直前)

1
Kerry

非表示のアプリを初めて起動する場合は、私の方法を使用してください。このような透過的なランチャーアクティビティを作成します

<activity Android:name=".MainActivity"
    Android:label="@string/app_name"
    Android:theme="@style/Theme.Transparent"
    Android:excludeFromRecents="true"
    >
    <intent-filter>
        <action Android:name="Android.intent.action.MAIN" />
            <category Android:name="Android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

そこで、このコードをoncreat()に配置して、アプリをランチャーに非表示にします[コード]

PackageManager p = getPackageManager();
    ComponentName componentName = new ComponentName(this, MainActivity.class); // activity which is first time open in manifiest file which is declare as <category Android:name="Android.intent.category.LAUNCHER" />
p.setComponentEnabledSetting(componentName,PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);

ランチャーのアプリ表示アイコンにこのコードを使用し、ブロードキャストレシーバーブートを使用するサービスクラスとネットワーク接続ブロードキャストレシーバークラスでも実行できるようにします(autostart.JavaおよびnetworkConnectinCheck.Java)。

PackageManager p = context.getPackageManager();
    ComponentName componentName = new ComponentName(context, MainActivity.class);
    p.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);

これで、ユーザーの手で初めてアプリを実行できるようになりました。その後は、レシーバーを使用していつでもアプリをランチできます。

1
Masoud A.

Serviceを別のプロセスで実行します。 このブログ に良いチュートリアルがあります。

Android:processタグに<Service>属性を指定して、アプリを独自のプロセス内で実行することができます。

<service
Android:name="MyServiceName"
Android:process="my_process" 
Android:icon="@drawable/icon"
Android:label="@string/service_name"
>
</service>
0
Ronnie