簡體   English   中英

即使應用程序被強制停止,也要重新啟動服務;關閉應用程序后,仍要在后台運行服務。

[英]Restart the service even if app is force-stopped and Keep running service in background even after closing the app How?

我正在嘗試在后台運行服務。 我的應用程序要做的是,當用戶選中復選框,然后服務啟動,而未選中時,服務停止。 哪個工作正常。 但是問題是,當我從任務管理器中關閉應用程序時,它也停止了服務。 我想要的是即使從任務管理器關閉后也要保持服務運行。 然后,停止該服務的唯一方法是由用戶自己打開框。

我該如何實現?

這是我的代碼

我的主要活動

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服務一樣運行?

我不確定您指的是哪個“任務管理器”會以不同的方式執行操作,所以我將答案基於用戶進入“設置”->“管理應用程序”並->強制停止應用程序時的操作android給了他。

假設您的服務正在運行的進程的一部分,如果用戶強制停止的過程中,你是從以后再運行該服務,直到用戶手動啟動you.This防止尤其是從3.0版本以上有效(檢查你的)。 當您認為有一個應用程序始終保持服務啟動並以某種方式使用戶煩惱時,這似乎也合乎邏輯。 因此,當用戶在應用上命令命中(:)強制停止)時,它不應重新啟動服務以繼續困擾用戶。

例如,想象一下,如果您創建一個僅通過持有喚醒鎖就可以在處理器時間使用的應用程序,而又無法殺死它們,將會發生什么情況。 這將是可怕的,並且將是巨大的安全災難。

因此,在用戶啟動您的活動之一之前,您將無法以任何方式重新啟動服務。

同樣,您不能禁用強制停止按鈕AFAIK。 您應該認為,除了您的應用程序和(在一定程度上)授予您訪問權限的資源之外,設備上什么都沒有您可以控制。

最后,如果您想強制停止,即使gtalk應用程序也會屈服於您的意願。 僅當您使用Gtalk或使用gtalk服務的其他應用程序(例如PUSH Gmail)(對於gtalk不屬於固件的手機)時,它才會啟動。 還可以在這里查看Android C2DM

https://stackoverflow.com/a/11238779/1218762

但是問題是,當我從任務管理器中關閉應用程序時,它也停止了服務。

正確。

我想要的是即使從任務管理器關閉后也要保持服務運行。 然后,停止該服務的唯一方法是由用戶自己打開框。

您可以使用C / C ++實現服務,將其構建到某些自定義固件中,然后說服人們在其設備上安裝該固件。

安裝gtalk並登錄后,它不會出現在任務管理器的“活動應用程序”選項卡中。 但是它在后台運行。

它是固件的一部分。

我認為此鏈接將為您提供幫助。
在管理應用程序中禁用強制停止按鈕

它禁用了Package Installer設置中的“強制停止”按鈕,因此沒有人可以停止您的應用程序。

您不能在任何情況下都防止您的服務被終止。 但是,您可以要求系統重新啟動它。 有兩種情況:(1)該進程由於某種異常原因而終止(2)手機重新啟動。 在前者中,START_STICKY或START_REDELIVER_INTENT用於重新啟動服務。 在后者中,您需要為android.intent.action.BOOT_COMPLETED添加一個BroadcastReceiver。

您的代碼正在從onStartCommand返回START_STICKY,因此您選擇了服務重新啟動路徑之一:“如果此服務的進程在啟動時被殺死(從onStartCommand(Intent,int,int)返回之后),則將其保留在處於開始狀態,但不保留此交付意圖。稍后,系統將嘗試重新創建服務...”

“這種模式對於可以明確啟動和停止運行任意時間的事情是有意義的,例如執行背景音樂播放的服務。”

您也可以使用START_REDELIVER_INTENT。

請注意,如果您的服務正在做任何重要的工作,它需要在后台線程中運行。

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

我不確定您是否可以阻止TaskManager關閉您的應用。 如果您考慮一下,那么這樣做是有意義的。 想象一下,您有一個應用程序既無法響應用戶輸入,又無法響應被任務管理器殺死。 不好。 但是我發現這個問題與您的問題相似。 另外,您還可以讓系統按照此處所述自動重新啟動服務(在“啟動服務”之前向下滾動至該頁面略微

如果您想首次啟動隱藏的應用程序,請使用我的方法,例如,我進行透明的啟動器活動

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

因此,我將此代碼用於啟動器上的show 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);

現在,我可以用用戶的手第一次運行該應用程序,此后,我可以隨時使用接收方的午餐應用程序。

讓您的Service在單獨的過程中運行。 該博客中有一個很好的教程。

您可以在<Service>標記中指定android:process屬性,以使您的應用在其自己的進程中運行。

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

您可以嘗試在服務的onDestroy事件上重新啟動服務。 使用一些標志來查找服務是由用戶關閉還是由用戶強制關閉。

注意,不能保證每次都會調用onDestroy。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM