如何保持android服务在后台运行?
我是为我大学最后一年的项目开发Android应用程序的新手。最近,我尝试创建一个android应用程序,它可以在后台运行服务,即使我的活动已被清除或关闭,例如通过最近的活动 我已经做了但仍然失败了:如何保持android服务在后台运行?,android,service,background,Android,Service,Background,我是为我大学最后一年的项目开发Android应用程序的新手。最近,我尝试创建一个android应用程序,它可以在后台运行服务,即使我的活动已被清除或关闭,例如通过最近的活动 我已经做了但仍然失败了: 试图返回START_粘性 尝试使用AlamManager重新安排服务的重新启动 我注意到这个问题只发生在新设备中。我的服务在emulator中运行良好,但在真实设备中运行不好。我使用的是Xiomi Redmi Note 3(Lolipop),我非常了解它的内置任务管理器。然而,即使我为我的应用程
- 试图返回START_粘性李>
- 尝试使用AlamManager重新安排服务的重新启动
package com.muzaffar.myApps.App;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.IBinder;
import android.os.SystemClock;
import android.widget.Toast;
import com.muzaffar.myApps.Lib.PhoneInfo;
import java.util.concurrent.TimeUnit;
public class myAppsServices extends Service {
private static final int FIRST_RUN_TIMEOUT_MILISEC = 5 * 1000;
private static final int SERVICE_STARTER_INTERVAL_MILISEC = 1 * 1000;
private static final int SERVICE_TASK_TIMEOUT_SEC = 10;
private final int REQUEST_CODE = 1;
private AlarmManager serviceReStarterAlarmManager = null;
private MyTask asyncTask = null;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
// Start of timeout-autostarter for our service (watchdog)
startServiceReStarter();
// Start performing service task
serviceTask();
/*Toast.makeText(this, "Service Started!", Toast.LENGTH_LONG).show();*/
}
/***
* _____ _
* / ____| (_)
* | (___ ___ _ __ __ __ _ ___ ___ ___
* \___ \ / _ \| '__|\ \ / /| | / __|/ _ \/ __|
* ____) || __/| | \ V / | || (__| __/\__ \
* |_____/ \___||_| \_/ |_| \___|\___||___/
*
* http://patorjk.com/software/taag/#p=display&h=1&v=0&c=c&f=Big&t=Shared%20Pref
*/
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(getApplicationContext(), "Services Has Been Started!", Toast.LENGTH_SHORT).show();
return START_STICKY;
}
/***
* _____ _ _ __ _ _ _ __ __
* | __ \ | | | |/ /(_)| || || \/ |
* | | | | ___ _ __ | |_ | ' / _ | || || \ / | ___
* | | | | / _ \ | '_ \ | __| | < | || || || |\/| | / _ \
* | |__| || (_) || | | || |_ | . \ | || || || | | || __/
* |_____/ \___/ |_| |_| \__| |_|\_\|_||_||_||_| |_| \___|
*
*
*/
private void StopPerformingServiceTask() {
asyncTask.cancel(true);
}
@Override
public void onDestroy() {
// performs when user or system kill our service
/*Toast.makeText(getApplicationContext(),"Services Has Been Destroyed!",Toast.LENGTH_SHORT).show();*/
StopPerformingServiceTask();
}
private void serviceTask() {
asyncTask = new MyTask();
asyncTask.execute();
}
class MyTask extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... params) {
try {
for (;;) {
TimeUnit.SECONDS.sleep(SERVICE_TASK_TIMEOUT_SEC);
// check does performing of the task need
if(isCancelled()) {
break;
}
// Initiating of onProgressUpdate callback that has access to UI
publishProgress();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onProgressUpdate(Void... progress) {
super.onProgressUpdate(progress);
//Toast.makeText(getApplicationContext(), "Please dont kill me, Im tired dying...T.T", Toast.LENGTH_LONG).show();
}
}
// We should to register our service in AlarmManager service
// for performing periodical starting of our service by the system
private void startServiceReStarter() {
Intent intent = new Intent(this, ServiceStarter.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, this.REQUEST_CODE, intent, 0);
if (pendingIntent == null) {
/*Toast.makeText(this, "Some problems with creating of PendingIntent", Toast.LENGTH_LONG).show();*/
} else {
if (serviceReStarterAlarmManager == null) {
serviceReStarterAlarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
serviceReStarterAlarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME,
SystemClock.elapsedRealtime() + FIRST_RUN_TIMEOUT_MILISEC,
SERVICE_STARTER_INTERVAL_MILISEC, pendingIntent);
}
}
}
}
package com.muzaffar.myApps.App;
导入android.app.AlarmManager;
导入android.app.pendingent;
导入android.app.Service;
导入android.content.Context;
导入android.content.Intent;
导入android.os.AsyncTask;
导入android.os.IBinder;
导入android.os.SystemClock;
导入android.widget.Toast;
导入com.muzaffar.myApps.Lib.PhoneInfo;
导入java.util.concurrent.TimeUnit;
公共类myAppsServices扩展服务{
私有静态最终整数首次运行超时毫秒=5*1000;
专用静态最终整备服务\u启动器\u间隔\u毫秒=1*1000;
专用静态最终整型服务任务超时秒=10;
私人最终int请求_代码=1;
专用AlarmManager服务重新启动ArmManager=null;
私有MyTask asyncTask=null;
@凌驾
公共IBinder onBind(意向){
返回null;
}
@凌驾
public void onCreate(){
super.onCreate();
//启动我们服务的超时自动启动程序(看门狗)
startServiceReStarter();
//开始执行服务任务
serviceTask();
/*Toast.makeText(此“服务已启动!”,Toast.LENGTH_LONG.show()*/
}
/***
* _____ _
* / ____| (_)
* | (___ ___ _ __ __ __ _ ___ ___ ___
* \___ \ / _ \| '__|\ \ / /| | / __|/ _ \/ __|
*| | | | | | | | | | | | | | | | | | | | | | | | | | |\
* |_____/ \___||_| \_/ |_| \___|\___||___/
*
* http://patorjk.com/software/taag/#p=display&h=1&v=0&c=c&f=Big&t=Shared%20Pref
*/
@凌驾
公共int onStartCommand(Intent Intent、int标志、int startId){
Toast.makeText(getApplicationContext(),“服务已启动!”,Toast.LENGTH\u SHORT.show();
返回开始时间;
}
/***
* _____ _ _ __ _ _ _ __ __
* | __ \ | | | |/ /(_)| || || \/ |
* | | | | ___ _ __ | |_ | ' / _ | || || \ / | ___
* | | | | / _ \ | '_ \ | __| | < | || || || |\/| | / _ \
* | |__| || (_) || | | || |_ | . \ | || || || | | || __/
* |_____/ \___/ |_| |_| \__| |_|\_\|_||_||_||_| |_| \___|
*
*
*/
私有无效停止执行服务任务(){
asyncTask.cancel(true);
}
@凌驾
公共空间{
//当用户或系统终止我们的服务时执行
/*Toast.makeText(getApplicationContext(),“服务已被销毁!”,Toast.LENGTH\u SHORT.show()*/
停止执行ServiceTask();
}
私有void serviceTask(){
asyncTask=新建MyTask();
asyncTask.execute();
}
类MyTask扩展了AsyncTask{
@凌驾
受保护的Void doInBackground(Void…参数){
试一试{
对于(;;){
时间单位。秒。睡眠(服务任务超时秒);
//检查是否需要执行任务
如果(isCancelled()){
打破
}
//启动有权访问UI的onProgressUpdate回调
出版进度();
}
}捕捉(中断异常e){
e、 printStackTrace();
}
返回null;
}
@凌驾
受保护的void onProgressUpdate(void…progress){
super.onProgressUpdate(进度);
//Toast.makeText(getApplicationContext(),“请不要杀我,我累得要死了…T.T”,Toast.LENGTH\u LONG.show();
}
}
//我们应该在AlarmManager服务中注册我们的服务
//通过系统定期启动我们的服务
私有void startServiceReStarter(){
Intent Intent=新的Intent(这是ServiceStarter.class);
PendingIntent PendingIntent=PendingIntent.getBroadcast(this,this.REQUEST_代码,intent,0);
if(pendingIntent==null){
/*Toast.makeText(这是“创建PendingEvent的一些问题”,Toast.LENGTH_LONG.show()*/
}否则{
如果(ServiceRestartArmManager==null){
serviceReStarterAlarmManager=(AlarmManager)getSystemService(报警服务);
serviceReStarterAlarmManager.setRepeating(AlarmManager.Alarm\u REALTIME,
SystemClock.elapsedRealtime()+第一次运行超时毫秒,
服务_启动器_间隔_毫秒,待定);
}
}
}
}
我的活动代码
package com.muzaffar.myApps.App;
导入android.app.ActivityManager;
导入android.app.admin.DevicePolicyManager;
导入android.content.ComponentName;
导入android.content.Context;
导入android.content.Intent;
导入android.content.pm.ActivityInfo;
导入android.graphi
package com.muzaffar.myApps.App;
import android.app.ActivityManager;
import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.muzaffar.spycare.App.SpycareServices;
import com.muzaffar.spycare.App.Util;
import com.muzaffar.spycare.R;
import com.muzaffar.spycare.Receiver.DeviceAdmin;
/**
* Created by OligoCoco on 11/2/2016.
*/
public class Main_Activity extends AppCompatActivity implements View.OnClickListener {
//Default PIN
public static final String DEFAULT_PIN = "1234";
//Import Instance Shared Pref
Util myPref=new Util(Main_Activity.this);
//ImportButton
Button btn_setting, btn_Stealth, btn_Test_Page;
public static Button btn_device_manager;
TextView txt_Start_Stop;
private boolean isRunning = false;
private EditText SecretCode;
String device_admin;
//Enable Device Admin
private ComponentName deviceAdmin;
private DevicePolicyManager devicePolicyManager;
private static final int REQUEST_CODE_ENABLE_ADMIN = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/*Initialize*/
deviceAdmin = new ComponentName(getApplicationContext(), DeviceAdmin.class);
devicePolicyManager = (DevicePolicyManager) getSystemService(DEVICE_POLICY_SERVICE);
/*Initialize Button*/
txt_Start_Stop = (TextView) findViewById(R.id.app_start_stop);
/*Return default status of txt_Start_Stop*/
showServiceStatus();
btn_setting = (Button) findViewById(R.id.app_setting);
btn_setting.setOnClickListener(this);
btn_device_manager = (Button) findViewById(R.id.app_device_manager);
device_admin = myPref.getSavedShared("device_admin");
if(device_admin==null || device_admin.equals("false") || device_admin.equals("")){
btn_device_manager.setText(R.string.app_device_manager);
btn_device_manager.setClickable(true);
btn_device_manager.setEnabled(true);
}else{
btn_device_manager.setText(R.string.app_device_manager_activated);
btn_device_manager.setClickable(false);
btn_device_manager.setEnabled(false);
}
btn_device_manager.setOnClickListener(this);
btn_Stealth = (Button) findViewById(R.id.app_start_stealth);
btn_Stealth.setOnClickListener(this);
SecretCode = (EditText) findViewById(R.id.app_secret_code);
SecretCode.setTextColor(Color.LTGRAY);
SecretCode.setText(myPref.getSavedShared("Secret_Code"));
//Start Services
startMonitoring();
//Request on potret
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
@Override
public void onStop(){
super.onStop();
myPref.saveToPref("Secret_Code",SecretCode.getText().toString());
final int flags = DevicePolicyManager.RESET_PASSWORD_REQUIRE_ENTRY;
if (devicePolicyManager.isAdminActive(deviceAdmin)) {
devicePolicyManager.resetPassword(myPref.getSavedShared("Secret_Code"), flags);
}
}
/***
* _____ _ __ __
* | __ \ (_) | \/ |
* | | | | ___ __ __ _ ___ ___ | \ / | __ _ _ __ __ _ __ _ ___ _ __
* | | | | / _ \\ \ / /| | / __|/ _ \ | |\/| | / _` || '_ \ / _` | / _` | / _ \| '__|
* | |__| || __/ \ V / | || (__| __/ | | | || (_| || | | || (_| || (_| || __/| |
* |_____/ \___| \_/ |_| \___|\___| |_| |_| \__,_||_| |_| \__,_| \__, | \___||_|
* __/ |
* |___/
*/
/*Device Manager*/
private void lock() {
devicePolicyManager.setPasswordQuality(deviceAdmin, DevicePolicyManager.PASSWORD_QUALITY_NUMERIC);
devicePolicyManager.setPasswordMinimumLength(deviceAdmin, 4);
final int flags = DevicePolicyManager.RESET_PASSWORD_REQUIRE_ENTRY;
devicePolicyManager.resetPassword(myPref.getSavedShared("Secret_Code"), flags);
}
@Override
protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE_ENABLE_ADMIN && resultCode == RESULT_OK) {
btn_device_manager.setText(this.getString(R.string.app_device_manager_activated));
btn_device_manager.setClickable(false);
btn_device_manager.setEnabled(false);
lock();
}else{
btn_device_manager.setText(this.getString(R.string.app_device_manager));
btn_device_manager.setClickable(true);
btn_device_manager.setEnabled(true);
}
}
/***
* _____ _ __ __ _ _ _
* / ____| | | | \/ | | | | | | |
* | | _ _ ___ | |_ ___ _ __ ___ | \ / | ___ | |_ | |__ ___ __| |
* | | | | | |/ __|| __|/ _ \ | '_ ` _ \ | |\/| | / _ \| __|| '_ \ / _ \ / _` |
* | |____| |_| |\__ \| |_| (_) || | | | | | | | | || __/| |_ | | | || (_) || (_| |
* \_____|\__,_||___/ \__|\___/ |_| |_| |_| |_| |_| \___| \__||_| |_| \___/ \__,_|
*
*
*/
/*Function to listen which button has been clicked and response correspondingly*/
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.app_device_manager:
defaultPIN();
if (devicePolicyManager.isAdminActive(deviceAdmin)) {
//If device admin is active
} else {
// Launch the activity to have the user enable our admin.
Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, deviceAdmin);
startActivityForResult(intent, REQUEST_CODE_ENABLE_ADMIN);
myPref.saveToPref("device_admin", "true");
}
break;
case R.id.app_setting:
defaultPIN();
Intent a = new Intent(getApplicationContext(), Setting_Activity.class);
startActivity(a);
break;
case R.id.app_start_stealth:
defaultPIN();
Intent b = new Intent(Intent.ACTION_MAIN);
b.addCategory(Intent.CATEGORY_HOME);
b.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(b);
break;
}
}
/*Function used to start the monitoring process*/
private void startMonitoring() {
//startService(new Intent(this, SpycareServices.class));
startService(new Intent(this, SpycareServices.class));
}
/*Function used to stop the monitoring process*/
private void stopMonitoring() {
//stopService(new Intent(this, SpycareServices.class));
stopService(new Intent(this, SpycareServices.class));
}
/*Function to change button status*/
private void showServiceStatus(){
// Show the current service state
/*if(isMyServiceRunning(SpycareServices.class,getApplicationContext())){*/
if(isMyServiceRunning(SpycareServices.class,getApplicationContext())){
txt_Start_Stop.setText(this.getString(R.string.stop_label));
txt_Start_Stop.setTextColor(Color.BLUE);
isRunning = true;
}else{
txt_Start_Stop.setText(this.getString(R.string.start_label));
txt_Start_Stop.setTextColor(Color.RED);
isRunning = false;
//If service not running
startMonitoring();
//Return
Intent a = new Intent(getApplicationContext(), Main_Activity.class);
startActivity(a);
}
}
/*Function to check if certain services is running*/
private boolean isMyServiceRunning(Class<?> serviceClass,Context context) {
ActivityManager manager = (ActivityManager)context. getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
/*Function to place default PIN*/
public void defaultPIN(){
String compA = myPref.getSavedShared("Secret_Code");
if(compA.isEmpty()){
Toast.makeText(getApplicationContext(), "PIN Cannot be empty, Applying default PIN "+DEFAULT_PIN, Toast.LENGTH_SHORT).show();
myPref.saveToPref("Secret_Code",DEFAULT_PIN);
//Set DMP Pass
final int flags = DevicePolicyManager.RESET_PASSWORD_REQUIRE_ENTRY;
if (devicePolicyManager.isAdminActive(deviceAdmin)) {
devicePolicyManager.resetPassword(DEFAULT_PIN, flags);
}
SecretCode.setText(myPref.getSavedShared("Secret_Code"));
}
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(getApplicationContext(), "Services Has Been Started!", Toast.LENGTH_SHORT).show();
return START_STICKY;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("LocalService", "Received start id " + startId + ": " + intent);
// We want this service to continue running until it is explicitly
// stopped, so return sticky.
return START_STICKY;
}
<service ...
android:process=":separate" >
...
</service>