18

我正在尝试在后台运行服务。我的应用程序所做的是当用户选中复选框然后服务启动以及未选中时服务停止。哪个工作得很好。但问题是当我从任务管理器关闭应用程序时,它也会停止服务。我想要的是即使在任务管理器关闭后也能保持服务运行。然后,停止该服务的唯一方法是用户自己通过取消选中该框。

我怎样才能做到这一点?

这是我的代码

我的主要活动

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 服务一样运行呢?

4

7 回答 7

21

我不确定您指的是哪个“任务管理器”,因为不同的“任务管理器”会有不同的行为,所以我的答案基于用户转到“设置”-->“管理应用程序”和-->“强制停止应用程序”时的操作android给了他。

假设您的服务作为进程的一部分运行,并且如果用户强制停止您的进程,则在用户手动启动您之前,您将无法再次运行该服务。这对于 3.0 及更高版本特别有效检查的)。当您认为有一个应用程序始终保持服务启动并以某种方式让用户烦恼时,这似乎也是合乎逻辑的。因此,当用户在应用程序上点按 (:) force-stops) 时,它不应重新启动服务以继续对用户进行窃听。

例如,想象一下如果您可以创建应用程序,该应用程序通过持有唤醒锁在您的处理器时间吃掉,并且您无法杀死它们,会发生什么。这将是可怕的和巨大的安全灾难。

因此,在用户启动您的一项活动之前,您将无法以任何方式重新启动您的服务。

您也不能禁用强制停止按钮 AFAIK。您应该认为,除了您的应用程序和(在有限的范围内)您被授予访问权限的资源之外,设备上的任何内容都不是您可以控制的。

最后,如果您想强制停止,即使是 gtalk 应用程序也会屈从于您的意愿。只有当您使用 Gtalk 或其他使用 gtalk 服务的应用程序(例如 PUSH Gmail)时,它才会启动(适用于 gtalk 不是固件一部分的手机)。还可以在这里查看Android C2DM

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

于 2012-05-22T18:36:28.730 回答
6

我认为这个链接会对你有所帮助。
在管理应用程序中禁用强制停止按钮

它禁用包安装程序设置中的强制停止按钮,因此没有人可以停止您的应用程序。

于 2013-09-02T06:44:43.447 回答
2

你不能阻止你的服务在任何情况下都被杀死。但是,您可以要求系统重新启动它。有两种情况:(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

于 2013-02-22T00:14:47.247 回答
1

我不完全确定您可以防止您的应用程序被 TaskManager 关闭。如果您考虑一下,这样做是有道理的。想象一下,您有一个应用程序无法响应用户输入,并且也无法响应被任务管理器杀死。不好。但是,我发现这个问题与您的问题相似。您也可以让系统自动重新启动您的服务,如此处所述(在该页面上向下滚动一点到“启动服务”之前

于 2012-05-20T08:16:32.220 回答
1

如果你想第一次启动一个隐藏的应用程序,请使用我的方法我制作一个像这样的透明启动器活动

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

现在我可以通过用户的手第一次运行应用程序,之后我可以随时使用我的接收器来午餐应用程序。

于 2017-09-02T01:53:20.263 回答
0

让您Service在单独的进程中运行。这个博客中有一个很好的教程。

您可以android:process在标签中指定属性<Service>以使您的应用程序在自己的进程中运行。

<service
android:name="MyServiceName"
android:process="my_process" 
android:icon="@drawable/icon"
android:label="@string/service_name"
>
</service>
于 2012-05-23T18:54:27.137 回答
-1

您可以尝试在服务的 onDestroy 事件上重新启动服务。使用一些标志来查找服务是否被用户关闭或其强制关闭。

请注意,不能保证每次都会调用 onDestroy。

于 2012-05-25T06:30:16.490 回答