mirror of
https://github.com/AngelAuraMC/Amethyst-Android.git
synced 2025-09-17 08:35:37 -04:00
VUI fixes & improvements pt.2
Added GameService for the time the game runs Added refcount to ProgressService (renamed from LazyService) Moved notification channel creation to Tools Now the game behaves better in the background Now the game fully exits on swipe-up
This commit is contained in:
parent
93396eff44
commit
a824c5f4f5
@ -114,8 +114,8 @@
|
||||
|
||||
</provider>
|
||||
|
||||
<service android:name=".services.LazyService">
|
||||
</service>
|
||||
<service android:name=".services.ProgressService"/>
|
||||
<service android:name=".services.GameService" android:process=":game"/>
|
||||
|
||||
</application>
|
||||
|
||||
|
@ -32,6 +32,7 @@ import net.kdt.pojavlaunch.customcontrols.keyboard.TouchCharInput;
|
||||
import net.kdt.pojavlaunch.multirt.MultiRTUtils;
|
||||
|
||||
import net.kdt.pojavlaunch.prefs.*;
|
||||
import net.kdt.pojavlaunch.services.GameService;
|
||||
import net.kdt.pojavlaunch.utils.*;
|
||||
import net.kdt.pojavlaunch.value.*;
|
||||
import net.kdt.pojavlaunch.value.launcherprofiles.LauncherProfiles;
|
||||
@ -77,7 +78,7 @@ public class MainActivity extends BaseActivity {
|
||||
if(LauncherProfiles.mainProfileJson == null) LauncherProfiles.update();
|
||||
minecraftProfile = LauncherProfiles.mainProfileJson.profiles.get(LauncherPreferences.DEFAULT_PREF.getString(LauncherPreferences.PREF_KEY_CURRENT_PROFILE,""));
|
||||
MCOptionUtils.load(Tools.getGameDirPath(minecraftProfile));
|
||||
|
||||
GameService.startService(this);
|
||||
initLayout(R.layout.activity_basemain);
|
||||
getWindow().setBackgroundDrawable(null);
|
||||
|
||||
|
@ -39,6 +39,7 @@ import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_NOTCH_SIZE;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.app.NotificationManagerCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.fragment.app.FragmentTransaction;
|
||||
@ -188,6 +189,15 @@ public final class Tools {
|
||||
return Tools.DIR_GAME_NEW;
|
||||
}
|
||||
|
||||
public static void buildNotificationChannel(Context context){
|
||||
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return;
|
||||
NotificationChannel channel = new NotificationChannel(
|
||||
context.getString(R.string.notif_channel_id),
|
||||
context.getString(R.string.notif_channel_name), NotificationManager.IMPORTANCE_HIGH);
|
||||
NotificationManagerCompat manager = NotificationManagerCompat.from(context);
|
||||
manager.createNotificationChannel(channel);
|
||||
}
|
||||
|
||||
private static boolean mkdirs(String path) {
|
||||
File file = new File(path);
|
||||
return file.mkdirs();
|
||||
|
@ -0,0 +1,69 @@
|
||||
package net.kdt.pojavlaunch.services;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.app.Service;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.os.IBinder;
|
||||
import android.os.Process;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.app.NotificationCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import net.kdt.pojavlaunch.R;
|
||||
import net.kdt.pojavlaunch.Tools;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
public class GameService extends Service {
|
||||
private static final WeakReference<Service> sGameService = new WeakReference<>(null);
|
||||
public static void startService(Context context) {
|
||||
Intent intent = new Intent(context, GameService.class);
|
||||
ContextCompat.startForegroundService(context, intent);
|
||||
}
|
||||
|
||||
public static void stopService() {
|
||||
Service gameService = sGameService.get();
|
||||
if(gameService != null)
|
||||
gameService.stopSelf();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
Tools.buildNotificationChannel(getApplicationContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
if(intent != null && intent.getBooleanExtra("kill", false)) {
|
||||
stopSelf();
|
||||
Process.killProcess(Process.myPid());
|
||||
return super.onStartCommand(intent, flags, startId);
|
||||
}
|
||||
Intent killIntent = new Intent(getApplicationContext(), GameService.class);
|
||||
killIntent.putExtra("kill", true);
|
||||
PendingIntent pendingKillIntent = PendingIntent.getService(this, 0, killIntent, Build.VERSION.SDK_INT >=23 ? PendingIntent.FLAG_IMMUTABLE : 0);
|
||||
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, "channel_id")
|
||||
.setContentTitle(getString(R.string.lazy_service_default_title))
|
||||
.setContentText(getString(R.string.notification_game_runs))
|
||||
.addAction(android.R.drawable.ic_menu_close_clear_cancel, getString(R.string.notification_terminate), pendingKillIntent)
|
||||
.setSmallIcon(R.mipmap.ic_launcher_round);
|
||||
startForeground(2, notificationBuilder.build());
|
||||
return START_NOT_STICKY; // non-sticky so android wont try restarting the game after the user uses the "Quit" button
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTaskRemoved(Intent rootIntent) {
|
||||
//At this point in time only the game runs and the user poofed the window, time to die
|
||||
stopSelf();
|
||||
Process.killProcess(Process.myPid());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return null;
|
||||
}
|
||||
}
|
@ -1,88 +0,0 @@
|
||||
package net.kdt.pojavlaunch.services;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.Service;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.os.IBinder;
|
||||
import android.os.Process;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.app.NotificationCompat;
|
||||
import androidx.core.app.NotificationManagerCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import net.kdt.pojavlaunch.R;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
/**
|
||||
* Lazy service which allows the process not to get killed.
|
||||
* Can be created from context, can be killed statically
|
||||
*/
|
||||
public class LazyService extends Service {
|
||||
private static final String NOTIF_TITLE = "notif_title";
|
||||
private static final String NOTIF_DESC = "notif_desc";
|
||||
|
||||
private static WeakReference<Service> sLazyService = new WeakReference<>(null);
|
||||
|
||||
/** Simple wrapper to start the service */
|
||||
public static void startService(Context context){
|
||||
Intent intent = new Intent(context, LazyService.class);
|
||||
ContextCompat.startForegroundService(context, intent);
|
||||
}
|
||||
|
||||
|
||||
/** Kill the service if it is still running */
|
||||
public static void killService(){
|
||||
Service service = sLazyService.get();
|
||||
if(service != null)
|
||||
service.stopSelf();
|
||||
}
|
||||
|
||||
public LazyService(){
|
||||
super();
|
||||
// TODO handle multiple service creation ?
|
||||
sLazyService = new WeakReference<>(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
if(intent.getBooleanExtra("kill", false)) {
|
||||
Process.killProcess(Process.myPid());
|
||||
return super.onStartCommand(intent, flags, startId);
|
||||
}
|
||||
buildNotificationChannel();
|
||||
Intent killIntent = new Intent(getApplicationContext(), LazyService.class);
|
||||
killIntent.putExtra("kill", true);
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "channel_id")
|
||||
.setContentTitle(getString(R.string.lazy_service_default_title))
|
||||
.setContentText(getString(R.string.lazy_service_default_description))
|
||||
.addAction(android.R.drawable.ic_menu_close_clear_cancel, getString(R.string.notification_terminate), PendingIntent.getService(this, 0, killIntent, Build.VERSION.SDK_INT >=23 ? PendingIntent.FLAG_IMMUTABLE : 0))
|
||||
.setSmallIcon(R.mipmap.ic_launcher_round);
|
||||
startForeground(1,builder.build());
|
||||
return super.onStartCommand(intent, flags, startId);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return null;
|
||||
}
|
||||
|
||||
private void buildNotificationChannel(){
|
||||
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return;
|
||||
|
||||
NotificationChannel channel = new NotificationChannel(
|
||||
getResources().getString(R.string.notif_channel_id),
|
||||
getResources().getString(R.string.notif_channel_name), NotificationManager.IMPORTANCE_HIGH);
|
||||
NotificationManagerCompat manager = NotificationManagerCompat.from(getApplicationContext());
|
||||
|
||||
manager.createNotificationChannel(channel);
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
package net.kdt.pojavlaunch.services;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.app.Service;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.os.IBinder;
|
||||
import android.os.Process;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.app.NotificationCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import net.kdt.pojavlaunch.R;
|
||||
import net.kdt.pojavlaunch.Tools;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* Lazy service which allows the process not to get killed.
|
||||
* Can be created from context, can be killed statically
|
||||
*/
|
||||
public class ProgressService extends Service {
|
||||
|
||||
private static WeakReference<Service> sProgressService = new WeakReference<>(null);
|
||||
private static final AtomicInteger sReferenceCount = new AtomicInteger(0);
|
||||
|
||||
/** Simple wrapper to start the service */
|
||||
public static void startService(Context context){
|
||||
Intent intent = new Intent(context, ProgressService.class);
|
||||
if(sReferenceCount.get() < 0) sReferenceCount.set(0);
|
||||
sReferenceCount.getAndIncrement();
|
||||
ContextCompat.startForegroundService(context, intent);
|
||||
}
|
||||
|
||||
/** Kill the service if it is still running */
|
||||
public static void killService(){
|
||||
Service service = sProgressService.get();
|
||||
int refcnt = sReferenceCount.decrementAndGet();
|
||||
if(service != null && refcnt <= 0) {
|
||||
service.stopSelf();
|
||||
}
|
||||
}
|
||||
|
||||
private NotificationCompat.Builder mNotificationBuilder;
|
||||
public ProgressService(){
|
||||
super();
|
||||
sProgressService = new WeakReference<>(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
Tools.buildNotificationChannel(getApplicationContext());
|
||||
Intent killIntent = new Intent(getApplicationContext(), ProgressService.class);
|
||||
killIntent.putExtra("kill", true);
|
||||
PendingIntent pendingKillIntent = PendingIntent.getService(this, 0, killIntent, Build.VERSION.SDK_INT >=23 ? PendingIntent.FLAG_IMMUTABLE : 0);
|
||||
mNotificationBuilder = new NotificationCompat.Builder(this, "channel_id")
|
||||
.setContentTitle(getString(R.string.lazy_service_default_title))
|
||||
.addAction(android.R.drawable.ic_menu_close_clear_cancel, getString(R.string.notification_terminate), pendingKillIntent)
|
||||
.setSmallIcon(R.mipmap.ic_launcher_round);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
if(intent != null && intent.getBooleanExtra("kill", false)) {
|
||||
stopSelf(); // otherwise Android tries to restart the service since it "crashed"
|
||||
Process.killProcess(Process.myPid());
|
||||
return super.onStartCommand(intent, flags, startId);
|
||||
}
|
||||
mNotificationBuilder.setContentText(getString(R.string.progresslayout_tasks_in_progress, sReferenceCount.get()));
|
||||
startForeground(1,mNotificationBuilder.build());
|
||||
return super.onStartCommand(intent, flags, startId);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return null;
|
||||
}
|
||||
}
|
@ -1,12 +1,9 @@
|
||||
package net.kdt.pojavlaunch.tasks;
|
||||
|
||||
import static net.kdt.pojavlaunch.PojavApplication.sExecutorService;
|
||||
import static net.kdt.pojavlaunch.Tools.ENABLE_DEV_FEATURES;
|
||||
import static net.kdt.pojavlaunch.utils.DownloadUtils.downloadFileMonitored;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
@ -21,16 +18,12 @@ import net.kdt.pojavlaunch.R;
|
||||
import net.kdt.pojavlaunch.Tools;
|
||||
import net.kdt.pojavlaunch.extra.ExtraConstants;
|
||||
import net.kdt.pojavlaunch.extra.ExtraCore;
|
||||
import net.kdt.pojavlaunch.multirt.MultiRTUtils;
|
||||
import net.kdt.pojavlaunch.multirt.Runtime;
|
||||
import net.kdt.pojavlaunch.prefs.LauncherPreferences;
|
||||
import net.kdt.pojavlaunch.services.LazyService;
|
||||
import net.kdt.pojavlaunch.services.ProgressService;
|
||||
import net.kdt.pojavlaunch.utils.DownloadUtils;
|
||||
import net.kdt.pojavlaunch.value.DependentLibrary;
|
||||
import net.kdt.pojavlaunch.value.MinecraftClientInfo;
|
||||
import net.kdt.pojavlaunch.value.MinecraftLibraryArtifact;
|
||||
import net.kdt.pojavlaunch.value.launcherprofiles.LauncherProfiles;
|
||||
import net.kdt.pojavlaunch.value.launcherprofiles.MinecraftProfile;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
@ -54,13 +47,13 @@ public class AsyncMinecraftDownloader {
|
||||
|
||||
public AsyncMinecraftDownloader(@NonNull Activity activity, JMinecraftVersionList.Version version,
|
||||
@NonNull DoneListener listener){
|
||||
LazyService.startService(activity);
|
||||
ProgressService.startService(activity);
|
||||
sExecutorService.execute(() -> {
|
||||
|
||||
if(downloadGame(activity, version, version.id))
|
||||
listener.onDownloadDone();
|
||||
|
||||
LazyService.killService();
|
||||
ProgressService.killService();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -311,4 +311,5 @@
|
||||
<string name="default_control">Default control</string>
|
||||
<string name="progresslayout_tasks_in_progress">%d tasks in progress</string>
|
||||
<string name="notification_terminate">Terminate</string>
|
||||
<string name="notification_game_runs">The game is running!</string>
|
||||
</resources>
|
||||
|
Loading…
x
Reference in New Issue
Block a user