2014-10-26 16:47:18 +01:00
|
|
|
/*
|
|
|
|
Copyright 2013-2014 appPlant UG
|
|
|
|
|
|
|
|
Licensed to the Apache Software Foundation (ASF) under one
|
|
|
|
or more contributor license agreements. See the NOTICE file
|
|
|
|
distributed with this work for additional information
|
|
|
|
regarding copyright ownership. The ASF licenses this file
|
|
|
|
to you under the Apache License, Version 2.0 (the
|
|
|
|
"License"); you may not use this file except in compliance
|
|
|
|
with the License. You may obtain a copy of the License at
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing,
|
|
|
|
software distributed under the License is distributed on an
|
|
|
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
|
|
KIND, either express or implied. See the License for the
|
|
|
|
specific language governing permissions and limitations
|
|
|
|
under the License.
|
2014-11-04 16:51:32 +00:00
|
|
|
*/
|
2014-10-26 16:47:18 +01:00
|
|
|
|
|
|
|
package de.appplant.cordova.plugin.background;
|
|
|
|
|
2014-11-04 16:51:32 +00:00
|
|
|
import java.util.Timer;
|
|
|
|
import java.util.TimerTask;
|
|
|
|
|
|
|
|
import org.json.JSONObject;
|
|
|
|
|
|
|
|
import android.annotation.SuppressLint;
|
2014-10-26 16:47:18 +01:00
|
|
|
import android.app.Notification;
|
|
|
|
import android.app.PendingIntent;
|
|
|
|
import android.app.Service;
|
|
|
|
import android.content.Context;
|
|
|
|
import android.content.Intent;
|
|
|
|
import android.content.res.Resources;
|
2015-06-03 16:33:09 +01:00
|
|
|
import android.graphics.Color;
|
2014-10-26 16:47:18 +01:00
|
|
|
import android.os.Build;
|
|
|
|
import android.os.Handler;
|
|
|
|
import android.os.IBinder;
|
2015-01-01 17:24:37 +01:00
|
|
|
import android.util.Log;
|
2014-10-26 16:47:18 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Puts the service in a foreground state, where the system considers it to be
|
|
|
|
* something the user is actively aware of and thus not a candidate for killing
|
|
|
|
* when low on memory.
|
|
|
|
*/
|
|
|
|
public class ForegroundService extends Service {
|
|
|
|
|
|
|
|
// Fixed ID for the 'foreground' notification
|
|
|
|
private static final int NOTIFICATION_ID = -574543954;
|
|
|
|
|
|
|
|
// Scheduler to exec periodic tasks
|
|
|
|
final Timer scheduler = new Timer();
|
|
|
|
|
|
|
|
// Used to keep the app alive
|
|
|
|
TimerTask keepAliveTask;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Allow clients to call on to the service.
|
|
|
|
*/
|
|
|
|
@Override
|
|
|
|
public IBinder onBind (Intent intent) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Put the service in a foreground state to prevent app from being killed
|
|
|
|
* by the OS.
|
|
|
|
*/
|
|
|
|
@Override
|
|
|
|
public void onCreate () {
|
|
|
|
super.onCreate();
|
|
|
|
keepAwake();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onDestroy() {
|
|
|
|
super.onDestroy();
|
|
|
|
sleepWell();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Put the service in a foreground state to prevent app from being killed
|
|
|
|
* by the OS.
|
|
|
|
*/
|
|
|
|
public void keepAwake() {
|
|
|
|
final Handler handler = new Handler();
|
|
|
|
|
2015-01-01 17:24:37 +01:00
|
|
|
if (!this.inSilentMode()) {
|
|
|
|
startForeground(NOTIFICATION_ID, makeNotification());
|
|
|
|
} else {
|
|
|
|
Log.w("BackgroundMode", "In silent mode app may be paused by OS!");
|
|
|
|
}
|
2014-10-26 16:47:18 +01:00
|
|
|
|
2014-12-14 13:38:36 +01:00
|
|
|
BackgroundMode.deleteUpdateSettings();
|
|
|
|
|
2014-10-26 16:47:18 +01:00
|
|
|
keepAliveTask = new TimerTask() {
|
|
|
|
@Override
|
|
|
|
public void run() {
|
|
|
|
handler.post(new Runnable() {
|
2014-11-04 16:51:32 +00:00
|
|
|
@Override
|
2014-10-26 16:47:18 +01:00
|
|
|
public void run() {
|
|
|
|
// Nothing to do here
|
|
|
|
// Log.d("BackgroundMode", "" + new Date().getTime());
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
scheduler.schedule(keepAliveTask, 0, 1000);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Stop background mode.
|
|
|
|
*/
|
|
|
|
private void sleepWell() {
|
|
|
|
stopForeground(true);
|
|
|
|
keepAliveTask.cancel();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create a notification as the visible part to be able to put the service
|
|
|
|
* in a foreground state.
|
|
|
|
*
|
|
|
|
* @return
|
|
|
|
* A local ongoing notification which pending intent is bound to the
|
|
|
|
* main activity.
|
|
|
|
*/
|
2014-11-04 16:51:32 +00:00
|
|
|
@SuppressLint("NewApi")
|
2014-10-26 16:47:18 +01:00
|
|
|
@SuppressWarnings("deprecation")
|
|
|
|
private Notification makeNotification() {
|
2014-12-14 13:38:36 +01:00
|
|
|
JSONObject settings = BackgroundMode.getSettings();
|
2014-11-04 16:51:32 +00:00
|
|
|
Context context = getApplicationContext();
|
|
|
|
String pkgName = context.getPackageName();
|
|
|
|
Intent intent = context.getPackageManager()
|
2014-10-26 16:47:18 +01:00
|
|
|
.getLaunchIntentForPackage(pkgName);
|
|
|
|
|
2014-11-04 16:51:32 +00:00
|
|
|
Notification.Builder notification = new Notification.Builder(context)
|
2014-11-04 16:59:33 +00:00
|
|
|
.setContentTitle(settings.optString("title", ""))
|
|
|
|
.setContentText(settings.optString("text", ""))
|
|
|
|
.setTicker(settings.optString("ticker", ""))
|
|
|
|
.setOngoing(true)
|
|
|
|
.setSmallIcon(getIconResId());
|
2014-10-26 16:47:18 +01:00
|
|
|
|
2015-06-03 16:33:09 +01:00
|
|
|
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
|
|
|
if(settings.optBoolean("isPublic") == true) {
|
|
|
|
notification.setVisibility(Notification.VISIBILITY_PUBLIC);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!settings.optString("color").equals("")) {
|
|
|
|
try {
|
|
|
|
notification.setColor(Color.parseColor(settings.optString("color")));
|
|
|
|
} catch (Exception e) {
|
|
|
|
Log.e("BackgroundMode", settings.optString("color") + " is not a valid color");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-04 16:51:32 +00:00
|
|
|
if (intent != null && settings.optBoolean("resume")) {
|
2014-10-26 16:47:18 +01:00
|
|
|
|
2014-11-04 16:51:32 +00:00
|
|
|
PendingIntent contentIntent = PendingIntent.getActivity(
|
|
|
|
context, NOTIFICATION_ID, intent, PendingIntent.FLAG_CANCEL_CURRENT);
|
2014-11-04 14:48:14 +00:00
|
|
|
|
|
|
|
notification.setContentIntent(contentIntent);
|
|
|
|
}
|
2014-10-26 16:47:18 +01:00
|
|
|
|
2014-12-14 13:38:36 +01:00
|
|
|
|
2014-10-26 16:47:18 +01:00
|
|
|
if (Build.VERSION.SDK_INT < 16) {
|
|
|
|
// Build notification for HoneyComb to ICS
|
|
|
|
return notification.getNotification();
|
|
|
|
} else {
|
|
|
|
// Notification for Jellybean and above
|
|
|
|
return notification.build();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Retrieves the resource ID of the app icon.
|
|
|
|
*
|
|
|
|
* @return
|
|
|
|
* The resource ID of the app icon
|
|
|
|
*/
|
2015-01-01 17:24:37 +01:00
|
|
|
private int getIconResId() {
|
2014-10-26 16:47:18 +01:00
|
|
|
Context context = getApplicationContext();
|
|
|
|
Resources res = context.getResources();
|
|
|
|
String pkgName = context.getPackageName();
|
|
|
|
|
|
|
|
int resId;
|
|
|
|
resId = res.getIdentifier("icon", "drawable", pkgName);
|
|
|
|
|
|
|
|
return resId;
|
|
|
|
}
|
2015-01-01 17:24:37 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* In silent mode no notification has to be added.
|
|
|
|
*
|
|
|
|
* @return
|
|
|
|
* True if silent: was set to true
|
|
|
|
*/
|
|
|
|
private boolean inSilentMode() {
|
|
|
|
JSONObject settings = BackgroundMode.getSettings();
|
|
|
|
|
|
|
|
return settings.optBoolean("silent", false);
|
|
|
|
}
|
2014-10-26 16:47:18 +01:00
|
|
|
}
|