【问题标题】:Restart the service even if app is force-stopped and Keep running service in background even after closing the app How?即使应用程序被强制停止,也要重新启动服务,即使在关闭应用程序后仍然在后台运行服务如何?
【发布时间】:2012-05-27 03:20:54
【问题描述】:

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

我怎样才能做到这一点?

这是我的代码

我的主要活动

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

【问题讨论】:

  • 你有没有发现什么?我也在寻找一种在强制停止后启动我的警报应用程序的方法。可以成功做到这一点的应用程序示例是 Alarm Clock Xtreme

标签: java android android-service


【解决方案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);

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

【讨论】:

    【解决方案2】:

    我认为这个链接会对你有所帮助。
    Disable force stop button in manage application

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

    【讨论】:

    • 是的,它正在工作 Prasahant,但你能告诉我现在如何启用它,如果我想卸载,那么我必须做什么?
    • @Pankaj:如果您想再次启用它,请转到设置 -> 安全 -> 设备管理员 -> 并取消选中应用程序的复选框。
    【解决方案3】:

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

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

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

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

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

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

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

    【讨论】:

    • 您提出了很好的观点,但我真的不明白这是不可能的。在 4.0 (ICS) 中,即使我强制关闭 Google 的日历应用程序,它仍然会激活通知。我也想知道如何做到这一点。有什么想法吗?
    • @Andy 你有没有发现什么?我也在寻找一种在强制停止后启动我的警报应用程序的方法。可以成功做到这一点的应用程序示例是 Alarm Clock Xtreme
    • 部分应用具有不同级别的系统权限。谷歌日历将成为固件的一部分或拥有该权限。它的证书和权限不同于其他应用程序
    • @Koger 不幸的是,您似乎对此无能为力。 Akhil 提出了很好的观点,所以我就放弃了。我基本上使用广播接收器而不是服务来设置我的应用程序,并运行一个运行广播接收器的警报。您可以做的是让您的应用程序在设备打开时运行一些代码,以便在需要时初始化您的东西。否则,当用户强制关闭时,它的Android神的话不运行它。我建议的最佳做法是让用户将您的应用添加到任务杀手的忽略列表中。
    • @SofiSoftwareLLC : 这些常量在运行时因资源紧缩而终止服务时使用。如果用户在 2.3 及以上版本中手动强制停止应用程序,则服务无法自动重启。
    【解决方案4】:

    让您的Service 在单独的进程中运行。 this blog 有一个很好的教程。

    您可以在&lt;Service&gt; 标签中指定android:process 属性,以使您的应用在自己的进程中运行。

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

    【讨论】:

    • 但是“强制停止”不会杀死与应用程序关联的所有进程吗?
    【解决方案5】:

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

    【讨论】:

      【解决方案6】:

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

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

      【讨论】:

      【解决方案7】:

      我不完全确定您是否可以防止您的应用被 TaskManager 关闭。如果您考虑一下,这样做是有道理的。想象一下,您有一个应用程序无法响应用户输入,并且也无法响应被任务管理器杀死。不好。但是,我发现this 问题与您的问题相似。您也可以按照here (scroll down on that page a little to just before 'starting a service'的描述让系统自动重新启动您的服务

      【讨论】:

      • 我的问题是应用程序可以从任务管理器中关闭,但它的服务不应该。从该应用启动的服务只能由用户手动关闭。
      • 或者第二种方法可能是应用程序不应该在任务管理器的活动应用程序选项卡中可见。所以它不能从那里关闭。就像 Gtalk 一样。当我们安装 gtalk 并登录后,它不会出现在任务管理器的活动应用程序选项卡中。但它在后台运行。
      • 嗯,它就像您桌面上的任务管理器。它还允许您杀死系统应用程序。所以,我看不出你为什么要努力避免被杀。我的意思是,Gmail 服务也允许自己被杀死。我想你必须忍受这一点。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-24
      • 1970-01-01
      相关资源
      最近更新 更多