我正在尝试在后台运行服务。我的应用程序所做的是当用户检查复选框然后服务启动时以及取消选中时服务停止。哪个工作得很好。但问题是,当我从任务管理器关闭应用程序时,它也会停止服务。我想要的是即使它从任务管理器关闭后仍保持服务运行。然后,只有通过取消方框,用户自己才能停止该服务。
我怎样才能做到这一点?
这是我的代码
我的主要活动
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服务一样运行?
答案 0 :(得分:20)
我不确定你指的是哪个'任务管理器',因为不同的行为管理器会采取不同的行为,所以当用户进入设置 - >管理应用程序和 - >时,我的答案基于此操作。 force按照android给他的方式停止app。
假设您的服务是作为流程的一部分运行的,并且如果用户强制停止您的流程,那么您将无法永远再次运行该服务,直到用户手动启动您。这特别适用于 3.0及以上版本(检查你的版本)。当您认为有一个应用程序始终保持服务启动并且以某种方式使用户烦恼时,这似乎也是合乎逻辑的。因此,当用户在应用程序上命令命中(:)强制停止时,不应重新启动服务以继续窃听用户。
例如,想象一下会是什么如果您可以通过按住唤醒锁来创建仅在您的处理器时间吃过的应用程序,并且您无法杀死它们。这将是一场可怕的巨大安全灾难。
因此,不会以任何方式重启您的服务,直到用户启动您的某项活动为止。
此外,您无法禁用强制停止按钮AFAIK。您应该认为除了您的应用程序之外,设备上没有任何内容可以控制,并且(在有限的范围内)您被授予访问权限的资源。
最后,如果你想强迫停止,即使是gtalk app也会屈服于你的意志。只有当您使用Gtalk或其他使用gtalk服务的应用程序(例如PUSH Gmail)时才会启动它(对于gtalk不属于固件的手机)。另请在此处查看 Android C2DM :
答案 1 :(得分:7)
但问题是,当我从任务管理器关闭应用程序时,它也会停止服务。
正确。
我想要的是即使在任务管理器关闭后也能保持服务运行。然后,只有通过取消方框,用户自己才能停止该服务。
您可以使用C / C ++实现服务,将其构建到一些自定义固件中,并诱使人们在其设备上安装该固件。
当我们安装gtalk时,一旦我们登录,它就不会出现在任务管理器的活动应用程序选项卡中。但它在后台运行。
它是固件的一部分。
答案 2 :(得分:5)
我认为此链接可以帮助您。
它禁用了“程序包安装程序”设置中的“强制停止”按钮,因此,没有人可以停止您的应用程序。
答案 3 :(得分: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
答案 4 :(得分:1)
我不完全确定您可以阻止您的应用被TaskManager关闭。如果你仔细想想,那就是这样。想象一下,您有一个应用程序无法响应用户输入,也无法响应被任务管理器杀死。不好。但是我发现this问题与你的问题类似。您也可以按照here (scroll down on that page a little to just before 'starting a service'
所述让系统自动重新启动您的服务答案 5 :(得分:1)
如果您想第一次启动隐藏的应用,请使用我的方法 我像这样做了一个透明的Launcher活动
<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);
现在我可以通过用户手第一次运行应用程序,之后我随时使用我的接收器来午餐应用程序。
答案 6 :(得分:0)
让你的Service
在一个单独的过程中运行。 this blog中有一个很好的教程。
您可以在android:process
代码中指定<Service>
属性,以使您的应用在自己的流程中运行。
<service
android:name="MyServiceName"
android:process="my_process"
android:icon="@drawable/icon"
android:label="@string/service_name"
>
</service>
答案 7 :(得分:-1)
您可以尝试在onDestroy服务事件上重新启动服务。使用一些标志来查找用户是否关闭服务或其关闭的力量。
请注意,无法保证每次都会调用onDestroy。