Android - 如果手机处于睡眠状态,后台服务无法运行

时间:2015-10-06 23:38:43

标签: java android service android-service

我正在尝试为我的学校申请一个包含后台服务的应用程序,该服务将下载学生的成绩和作业历史记录。 AlarmManager每小时调用一次该服务,它可以工作,但只有在设备启动时才能运行。一旦设备打开(从休眠状态;设备未完全关闭),AlarmManager就会触发服务。这是BroadcastReceiver的代码,其中包含AlarmManager:

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.support.v4.content.WakefulBroadcastReceiver;

public class ServiceAlarmReceiver extends WakefulBroadcastReceiver {    

private final String TAG = "com.example.ahsandroidapplication";

@Override
public void onReceive(Context context, Intent intent) {   

    Log.i(TAG, "Broadcast received");
    Intent gradeNotificationServiceIntent = new Intent(context, GradeNotificationService.class);
    //context.startService(gradeNotificationServiceIntent);
    startWakefulService(context, gradeNotificationServiceIntent);
}

public static void setAlarm(Context context){

    System.out.println("Service started");

    long alertTime = System.currentTimeMillis() + 1000 * 60 * 60;
    Intent alertIntent = new Intent(context, ServiceAlarmReceiver.class);

    alertIntent.setAction("com.example.ahsandroidapplication.servicealarmbroadcast");

    AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    //alarmManager.set(AlarmManager.RTC_WAKEUP, alertTime, PendingIntent.getBroadcast(context, 1, alertIntent, 
    //      PendingIntent.FLAG_UPDATE_CURRENT));
    alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, alertTime, 1000 * 3600, PendingIntent.getBroadcast(context, 
            GradeNotificationService.SERVICE_ALARM_BROADCAST_ID, alertIntent, 
            PendingIntent.FLAG_UPDATE_CURRENT));


}

public static void cancelAlarm(Context context)
{
    Intent intent = new Intent(context, ServiceAlarmReceiver.class);

    intent.setAction("com.example.ahsandroidapplication.servicealarmbroadcast");

    PendingIntent sender = PendingIntent.getBroadcast(context, 
            GradeNotificationService.SERVICE_ALARM_BROADCAST_ID, intent, 0);
    AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    alarmManager.cancel(sender);
}
}

由于仅在手机开机时收到广播,我认为问题出在接收器上。

该服务还有另一个问题。它应该在发布新成绩时发送推送通知,但它们永远不会被发送。

以下是服务类的代码:

import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;

import android.app.IntentService;
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.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.support.v4.app.NotificationCompat;

public class GradeNotificationService extends IntentService {

private Context context;

public GradeNotificationService() {
    super("GradeNotificationService");
    // TODO Auto-generated constructor stub
}

public static final int SERVICE_ALARM_BROADCAST_ID = 0;

@Override
protected void onHandleIntent(Intent intent) {
    // TODO Auto-generated method stub

    System.out.println("Grade notification services started");
    context = getApplicationContext();
    final Intent completeWakefulIntent = intent;

    if(gradesChanged()){

        getAssignments();
    }

    ServiceAlarmReceiver.completeWakefulIntent(completeWakefulIntent);
}


private boolean gradesChanged() {

//Massive blocks of code that will take you forever to read

}

private void getAssignments(){


//Massive blocks of code that will take you forever to read
//It is in this method that sendNotification() is used to send a notification
//(at least that's what it's supposed to be doing)


}

private void sendNotification(String title, String message){

    NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context);

    mBuilder.setSmallIcon(R.drawable.ic_launcher);
    mBuilder.setContentTitle(title);
    mBuilder.setContentText(message);
    mBuilder.setDefaults(NotificationCompat.DEFAULT_SOUND);
    mBuilder.setAutoCancel(true);

    Intent resultIntent = new Intent(context, MainInterface.class);

    PendingIntent resultPendingIntent = PendingIntent.getActivity(context, 0, resultIntent, 0);
    mBuilder.setContentIntent(resultPendingIntent);

    NotificationManager mNotificationManager = 
            (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    // mId allows you to update the notification later on.
    mNotificationManager.notify(1, mBuilder.build());

}

private boolean networkIsAvailable() {

    ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo netInfo = cm.getActiveNetworkInfo();
    // return netInfo != null && netInfo.isConnectedOrConnecting();

    NetworkInfo mWifi = cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI);

    return netInfo != null && netInfo.isConnectedOrConnecting()
            || mWifi.isConnected();

}

}

任何人都能告诉我,当手机处于睡眠状态时,我可以做些什么来运行此服务,或者为什么不发送任何通知?任何帮助都是适当的。

编辑:

这是大部分的清单。目标sdk为21,最小值为11:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WAKE_LOCK" />

<uses-sdk
    android:minSdkVersion="11"
    android:targetSdkVersion="21" />

<application
    android:allowBackup="true"
    android:label="@string/app_name" 
    android:icon="@drawable/ic_launcher">

    <service 
        android:name="com.example.ahsandroidapplication.GradeNotificationService"
        android:enabled="true" >
       <intent-filter>
           <action android:name="com.example.ahsandroidapplication.ServiceAlarmReceiver" />
       </intent-filter>
    </service>

    <receiver android:name=".ServiceAlarmReceiver"
        android:enabled="true">   
      <intent-filter>
         <action android:name="com.example.ahsandroidapplication.servicealarmbroadcast"></action>
      </intent-filter>
    </receiver>

    <receiver android:name=".BootReceiver"
    android:enabled="true">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED"></action>
        </intent-filter>
    </receiver>

    <activity
        android:name="MainInterface"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <activity android:name="MainLogin"
              android:label="@string/app_name">

    </activity>

    <service android:enabled="true"
         android:exported="false"
         android:isolatedProcess="false"
         android:label="@string/app_name"
         android:name="AspenManager" >
    </service> 

</application>

1 个答案:

答案 0 :(得分:0)

&#34;注意:从API 19(KITKAT)开始,警报传递不准确:操作系统将移动警报以最小化唤醒和电池使用。有新的API支持需要严格交付保证的应用程序;请参阅setWindow(int,long,long,PendingIntent)和setExact(int,long,PendingIntent)。 targetSdkVersion早于API 19的应用程序将继续查看之前在请求时准确传递所有警报的行为。&#34;

http://developer.android.com/reference/android/app/AlarmManager.html