Service 具有计时器问题的前台服务

Service 具有计时器问题的前台服务,service,timer,notifications,foreground,Service,Timer,Notifications,Foreground,我正在开发一个应用程序,它在给定的时间间隔内检查与服务器的连接。 我使用带有通知的前台服务。问题是,只要手机处于唤醒状态(屏幕打开),一切正常。从我按下电源按钮打开屏幕的那一刻起,服务开始表现出奇怪的行为。 我制作了一个精简版的服务来向您展示。 ForegroundService.java: 那么我做错什么了?这是我的应用程序中非常重要的一部分,因此必须修复这个bug。有人能帮帮我吗?当处于睡眠模式(CPU断电)时,Android将不执行应用程序代码 为了避免这种情况,您可以使用AlarmMan

我正在开发一个应用程序,它在给定的时间间隔内检查与服务器的连接。 我使用带有通知的前台服务。问题是,只要手机处于唤醒状态(屏幕打开),一切正常。从我按下电源按钮打开屏幕的那一刻起,服务开始表现出奇怪的行为。 我制作了一个精简版的服务来向您展示。
ForegroundService.java:

那么我做错什么了?这是我的应用程序中非常重要的一部分,因此必须修复这个bug。有人能帮帮我吗?

当处于睡眠模式(CPU断电)时,Android将不执行应用程序代码

为了避免这种情况,您可以使用AlarmManager类来安排手机从睡眠中启动的意图,并使用自定义广播接收器捕捉它:

然后,您应该使用PowerManager类获取唤醒锁,以确保至少CPU保持开启状态,以便执行应用程序代码,并在不再需要时释放它(这将允许手机返回睡眠模式,以避免无用的电池使用):

当然,您也可以在服务启动后立即获得WakeLock,直到服务关闭为止,但这种方法对电池不太友好

package service.App;
import android.R.drawable;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.IBinder;
import android.util.Log;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.sql.Date;
import java.text.SimpleDateFormat;
import java.util.Timer;
import java.util.TimerTask;

public class ForegroundService extends Service {
static final String ACTION_FOREGROUND = "com.example.android.apis.FOREGROUND";
static final String ACTION_BACKGROUND = "com.example.android.apis.BACKGROUND";
private static final Class<?>[] mStartForegroundSignature = new Class[] {int.class, Notification.class };
private static final Class<?>[] mStopForegroundSignature = new Class[] { boolean.class };
private Method mStartForeground;
private Method mStopForeground;
private Object[] mStartForegroundArgs = new Object[2];
private Object[] mStopForegroundArgs = new Object[1];
private Timer timer = new Timer();
long interv=10000;
int timeout=3000;
Intent notificationIntent;
PendingIntent contentIntent;
Notification notification;
CharSequence text;
SimpleDateFormat df;

void invokeMethod(Method method, Object[] args) {
    try {
        mStartForeground.invoke(this, mStartForegroundArgs);
    } catch (InvocationTargetException e) {
        Log.w("ApiDemos", "Unable to invoke method", e);
    } catch (IllegalAccessException e) {
        Log.w("ApiDemos", "Unable to invoke method", e);
    }
}

void startForegroundCompat(int id, Notification notification) {
    Scan();
    if (mStartForeground != null) {
        mStartForegroundArgs[0] = Integer.valueOf(id);
        mStartForegroundArgs[1] = notification;
        invokeMethod(mStartForeground, mStartForegroundArgs);
        return;
    }
}

void stopForegroundCompat(int id) {
    if (mStopForeground != null) {
        mStopForegroundArgs[0] = Boolean.TRUE;
        try {
            mStopForeground.invoke(this, mStopForegroundArgs);
        } catch (InvocationTargetException e) {
            Log.w("ApiDemos", "Unable to invoke stopForeground", e);
        } catch (IllegalAccessException e) {
            Log.w("ApiDemos", "Unable to invoke stopForeground", e);
        }
        return;
    }
}

@Override
public void onCreate() {

    notificationIntent = new Intent(this, ForegroundService.class);
    contentIntent = PendingIntent.getActivity(this, 0, notificationIntent,0);
    try {
        mStartForeground = getClass().getMethod("startForeground",mStartForegroundSignature);
        mStopForeground = getClass().getMethod("stopForeground",mStopForegroundSignature);
    } catch (NoSuchMethodException e) {
        return;
    }
}

@Override
public void onDestroy() {
    stopForegroundCompat(R.string.foreground_service_started);

    if (timer != null) {

        timer.cancel();
    }
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    handleCommand(intent);
    return START_STICKY;
}

void handleCommand(Intent intent) {
    if (ACTION_FOREGROUND.equals(intent.getAction())) {
        text = getText(R.string.foreground_service_started);

        notification = new Notification(R.drawable.icon, text, System
                .currentTimeMillis());

        contentIntent = PendingIntent.getActivity(this, 0, new Intent(this,
                Start.class), 0);

        notification.setLatestEventInfo(this,
                getText(R.string.local_service_label), text, contentIntent);

        startForegroundCompat(R.string.foreground_service_started,
                notification);

    } else if (ACTION_BACKGROUND.equals(intent.getAction())) {
        stopForegroundCompat(R.string.foreground_service_started);
    }

}

@Override
public IBinder onBind(Intent intent) {
    return null;
}


private void Scan() {
    timer.scheduleAtFixedRate(new TimerTask() {

        @Override
        public void run() {

            Socket s = null;
            int p = 81;
            long time;
            String url="www.google.com";
            SimpleDateFormat df;
            InetAddress ipaddress;
                try {

                    ipaddress = InetAddress.getByName(url);

                    try {
                        s = new Socket();
                        s.connect(new InetSocketAddress(url, p), timeout);
                        time = System.currentTimeMillis();
                        df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        Log.i("Server Monitor",
                                "A server is running on port " + p + " "
                                        + "@ IP address "
                                        + ipaddress.getHostAddress()
                                        + ". Date/Time: "
                                        + df.format(new Date(time)));
                        s.close();
                    } catch (IOException e) {
                        String ns = Context.NOTIFICATION_SERVICE;
                        NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);
                        long when = System.currentTimeMillis();
                        Notification notification = new Notification(drawable.ic_dialog_alert,"Server Monitor", when);
                        Context context = getApplicationContext();
                        CharSequence contentTitle = "Server Monitor";
                        CharSequence contentText = "No server on port." + p;
                        notification.setLatestEventInfo(context,contentTitle, contentText, contentIntent);
                        notification.defaults |= Notification.DEFAULT_SOUND;
                        final int HELLO_ID = 1;
                        mNotificationManager.notify(HELLO_ID, notification);

                    }
                } catch (UnknownHostException e) {
                    String ns = Context.NOTIFICATION_SERVICE;
                    NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);
                    long when = System.currentTimeMillis();
                    Notification notification = new Notification(drawable.ic_dialog_alert,"Server Monitor", when);
                    Context context = getApplicationContext();
                    CharSequence contentTitle = "Server Monitor";
                    CharSequence contentText = "Could not find host.";
                    notification.setLatestEventInfo(context,contentTitle, contentText, contentIntent);
                    notification.defaults |= Notification.DEFAULT_SOUND;
                    final int HELLO_ID = 1;
                    mNotificationManager.notify(HELLO_ID, notification);

                }

                if (s != null) {
                    try {
                        s.close();
                    } catch (IOException ioEx) {
                        Log.i("Server Monitor", "Unable to close socket "+ s);
                    }
                }
    }

    }, 0, interv);
}
}
package service.App;
import service.App.R;
import service.App.ForegroundService;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class Start extends Activity{
private Button ButtonStartService;
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    ButtonStartService = (Button)findViewById(R.id.ButtonStartService);

    ButtonStartService.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            Intent intent = new Intent(ForegroundService.ACTION_FOREGROUND);
            intent.setClass(Start.this, ForegroundService.class);
            startService(intent);
        }

    });
}
}