diff --git a/android/res/drawable/empty.xml b/android/res/drawable/empty.xml
new file mode 100644
index 00000000..a60e6350
--- /dev/null
+++ b/android/res/drawable/empty.xml
@@ -0,0 +1,2 @@
+
+
diff --git a/android/res/layout/notify_21.xml b/android/res/layout/notify_21.xml
deleted file mode 100644
index 806a23ec..00000000
--- a/android/res/layout/notify_21.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
-
-
-
-
diff --git a/android/res/values/strings.xml b/android/res/values/strings.xml
index e7ea572e..fe09b82c 100644
--- a/android/res/values/strings.xml
+++ b/android/res/values/strings.xml
@@ -126,4 +126,9 @@
- %d folders
+
+
+ Game engine
+ Game engine notifications
+
diff --git a/android/src/su/xash/engine/XashActivity.java b/android/src/su/xash/engine/XashActivity.java
index b1ebd62a..a086f0a3 100644
--- a/android/src/su/xash/engine/XashActivity.java
+++ b/android/src/su/xash/engine/XashActivity.java
@@ -481,7 +481,9 @@ public class XashActivity extends Activity {
}
}
- if( sdk >= 5 )
+ if( sdk >= Build.VERSION_CODES.O )
+ startForegroundService( new Intent( getBaseContext(), XashService.class ) );
+ else if( sdk >= 5 )
startService( new Intent( getBaseContext(), XashService.class ) );
mEngineReady = true;
@@ -962,10 +964,7 @@ public class XashActivity extends Activity {
if( icon.getWidth() < 16 )
return;
- XashService.notification.contentView.setImageViewUri( XashService.status_image, Uri.parse( "file://" + path ) );
-
- NotificationManager nm = ( NotificationManager )mSingleton.getApplicationContext().getSystemService( Context.NOTIFICATION_SERVICE );
- nm.notify( 100, XashService.notification );
+ XashService.not.setIcon(icon);
}
catch( Exception e )
{
@@ -982,9 +981,7 @@ public class XashActivity extends Activity {
if( sdk < 5 )
return;
- XashService.notification.contentView.setTextViewText( XashService.status_text, title );
- NotificationManager nm = ( NotificationManager )mSingleton.getApplicationContext().getSystemService( Context.NOTIFICATION_SERVICE );
- nm.notify( 100, XashService.notification );
+ XashService.not.setText(title);
}
public static String getAndroidID()
diff --git a/android/src/su/xash/engine/XashService.java b/android/src/su/xash/engine/XashService.java
index 69dcee19..31d56735 100644
--- a/android/src/su/xash/engine/XashService.java
+++ b/android/src/su/xash/engine/XashService.java
@@ -12,6 +12,7 @@ import android.view.*;
import android.os.*;
import android.util.*;
import android.graphics.*;
+import android.graphics.drawable.*;
import android.text.method.*;
import android.text.*;
import android.media.*;
@@ -36,9 +37,7 @@ import su.xash.engine.JoystickHandler;
public class XashService extends Service
{
- public static Notification notification;
- public static int status_image = R.id.status_image;
- public static int status_text = R.id.status_text;
+ public static XashNotification not;
@Override
public IBinder onBind(Intent intent)
@@ -46,7 +45,7 @@ public class XashService extends Service
return null;
}
- public static class exitButtonListener extends BroadcastReceiver
+ public static class ExitButtonListener extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent)
@@ -59,38 +58,15 @@ public class XashService extends Service
System.exit(0);
}
}
-
+
@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
- int status_exit_button = R.id.status_exit_button;
- int notify = R.layout.notify;
- if( XashActivity.sdk >= 21 )
- {
- status_image = R.id.status_image_21;
- status_text = R.id.status_text_21;
- status_exit_button = R.id.status_exit_button_21;
- notify = R.layout.notify_21;
- }
-
Log.d("XashService", "Service Started");
- Intent engineIntent = new Intent(this, XashActivity.class);
- engineIntent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
+ not = XashNotification.getXashNotification(this);
- Intent exitIntent = new Intent(this, exitButtonListener.class);
- final PendingIntent pendingExitIntent = PendingIntent.getBroadcast(this, 0, exitIntent, 0);
-
- notification = new Notification(R.drawable.ic_statusbar, "Xash3D", System.currentTimeMillis());
-
- notification.contentView = new RemoteViews(getApplicationContext().getPackageName(), notify);
- notification.contentView.setTextViewText(status_text, "Xash3D Engine");
- notification.contentView.setOnClickPendingIntent(status_exit_button, pendingExitIntent);
-
- notification.contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, engineIntent, 0);
- notification.flags |= Notification.FLAG_ONGOING_EVENT | Notification.FLAG_FOREGROUND_SERVICE;
-
- startForeground(100, notification);
+ startForeground(not.getId(), not.createNotification());
return START_NOT_STICKY;
}
@@ -122,4 +98,160 @@ public class XashService extends Service
}
stopSelf();
}
+
+ public static class XashNotification
+ {
+ public Notification notification;
+ public final int notificationId = 100;
+ public Context ctx;
+
+ public XashNotification(Context ctx)
+ {
+ this.ctx = ctx;
+ }
+
+ public Notification createNotification()
+ {
+ Intent engineIntent = new Intent(ctx, XashActivity.class);
+ engineIntent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
+
+ Intent exitIntent = new Intent(ctx, ExitButtonListener.class);
+ final PendingIntent pendingExitIntent = PendingIntent.getBroadcast(ctx, 0, exitIntent, 0);
+
+ notification = new Notification(R.drawable.ic_statusbar, ctx.getString(R.string.app_name), System.currentTimeMillis());
+
+ notification.contentView = new RemoteViews(ctx.getApplicationContext().getPackageName(), R.layout.notify);
+ notification.contentView.setTextViewText(R.id.status_text, ctx.getString(R.string.app_name));
+ notification.contentView.setOnClickPendingIntent(R.id.status_exit_button, pendingExitIntent);
+
+ notification.contentIntent = PendingIntent.getActivity(ctx.getApplicationContext(), 0, engineIntent, 0);
+ notification.flags |= Notification.FLAG_ONGOING_EVENT | Notification.FLAG_FOREGROUND_SERVICE;
+
+ return notification;
+ }
+
+ public void setIcon(Bitmap bmp)
+ {
+ notification.contentView.setImageViewBitmap( R.id.status_image, bmp );
+ NotificationManager nm = ctx.getSystemService(NotificationManager.class);
+ nm.notify( notificationId, notification );
+ }
+
+ public void setText(String title)
+ {
+ notification.contentView.setTextViewText( R.id.status_text, title );
+ NotificationManager nm = ctx.getSystemService(NotificationManager.class);
+ nm.notify( notificationId, notification );
+ }
+
+ public int getId()
+ {
+ return notificationId;
+ }
+
+ public static XashNotification getXashNotification(Context ctx)
+ {
+ if( XashActivity.sdk >= Build.VERSION_CODES.O )
+ return new XashNotification_O(ctx);
+ else if( XashActivity.sdk >= 21 )
+ return new XashNotification_v21(ctx);
+ return new XashNotification(ctx);
+ }
+ }
+
+ private static class XashNotification_v21 extends XashNotification
+ {
+ protected Notification.Builder builder;
+
+ public XashNotification_v21(Context ctx)
+ {
+ super(ctx);
+ }
+
+ @Override
+ public Notification createNotification()
+ {
+ Intent engineIntent = new Intent(ctx, XashActivity.class);
+ engineIntent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
+
+ Intent exitIntent = new Intent(ctx, ExitButtonListener.class);
+ final PendingIntent pendingExitIntent = PendingIntent.getBroadcast(ctx, 0, exitIntent, 0);
+
+ if(builder == null)
+ builder = new Notification.Builder(ctx);
+
+ notification = builder.setSmallIcon(R.drawable.ic_statusbar)
+ .setLargeIcon(Icon.createWithResource(ctx, R.mipmap.ic_launcher))
+ .setContentTitle(ctx.getString(R.string.app_name))
+ .setContentText(ctx.getString(R.string.app_name))
+ .setContentIntent(PendingIntent.getActivity(ctx.getApplicationContext(), 0, engineIntent, 0))
+ .addAction(new Notification.Action.Builder(R.drawable.empty, ctx.getString(R.string.exit), pendingExitIntent).build())
+ .setOngoing(true)
+ .build();
+
+ return notification;
+ }
+
+ @Override
+ public void setIcon(Bitmap bmp)
+ {
+ notification = builder.setLargeIcon(bmp).build();
+ NotificationManager nm = ctx.getSystemService(NotificationManager.class);
+ nm.notify( notificationId, notification );
+ }
+
+ @Override
+ public void setText(String str)
+ {
+ notification = builder.setContentText(str).build();
+ NotificationManager nm = ctx.getSystemService(NotificationManager.class);
+ nm.notify( notificationId, notification );
+ }
+ }
+
+ private static class XashNotification_O extends XashNotification_v21
+ {
+ private static final String CHANNEL_ID = "XashServiceChannel";
+
+ public XashNotification_O(Context ctx)
+ {
+ super(ctx);
+ }
+
+ private void createNotificationChannel()
+ {
+ // Create the NotificationChannel, but only on API 26+ because
+ // the NotificationChannel class is new and not in the support library
+ if (XashActivity.sdk >= Build.VERSION_CODES.O)
+ {
+ final NotificationManager nm = ctx.getSystemService(NotificationManager.class);
+
+ if(nm.getNotificationChannel(CHANNEL_ID) == null)
+ {
+ CharSequence name = ctx.getString(R.string.default_channel_name);
+ String description = ctx.getString(R.string.default_channel_description);
+ int importance = NotificationManager.IMPORTANCE_LOW;
+
+ NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
+ channel.setDescription(description);
+
+ // Register the channel with the system; you can't change the importance
+ // or other notification behaviors after this
+
+ nm.createNotificationChannel(channel);
+ }
+ }
+ }
+
+ @Override
+ public Notification createNotification()
+ {
+ createNotificationChannel();
+
+ builder = new Notification.Builder(ctx);
+ builder.setChannelId(CHANNEL_ID);
+
+ return super.createNotification();
+ }
+ }
};