Я разрабатываю приложение, которое проверяет соединение с сервером через заданный интервал.
Я использую сервис переднего плана с уведомлениями для этого. Проблема в том, что все работает нормально, пока телефон не спит (экран включен). С того момента, как я поворачиваю экран нажатием кнопки питания, сервис начинает вести себя странно.
Я сделал урезанную версию своего сервиса, чтобы показать вам.
ForegroundService.java:
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);
}
}
Таким образом, этот сервис проверяет соединение с www.google.com через порт 81 каждые 10 секунд. Я установил это на порт 81, чтобы он не работал, и протестировал уведомления. Когда это терпит неудачу, это показывает уведомление. С того момента, как я поворачиваю экран, в течение одной или нескольких минут нет никаких уведомлений, а затем он дает мне все уведомления одновременно. Ниже приведено действие, которое запускает службу.
Start.java:
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);
}
});
}
}
Так что я здесь делаю что-то не так? Это действительно важная часть моего приложения, поэтому эту ошибку действительно нужно исправить. Может кто-нибудь помочь мне, пожалуйста?