mirror of
https://github.com/AngelAuraMC/Amethyst-Android.git
synced 2025-09-16 08:05:34 -04:00
Feat[notifs]: features for remote error reporting, unified notification constants
TODO: also use it for Minecraft downloads
This commit is contained in:
parent
2980afdd05
commit
f1e88e2068
@ -78,6 +78,9 @@
|
|||||||
android:name=".FatalErrorActivity"
|
android:name=".FatalErrorActivity"
|
||||||
android:configChanges="keyboardHidden|orientation|screenSize|keyboard|navigation"
|
android:configChanges="keyboardHidden|orientation|screenSize|keyboard|navigation"
|
||||||
android:theme="@style/Theme.AppCompat.DayNight.Dialog" />
|
android:theme="@style/Theme.AppCompat.DayNight.Dialog" />
|
||||||
|
<activity android:name=".ShowErrorActivity"
|
||||||
|
android:configChanges="keyboardHidden|orientation|screenSize|keyboard|navigation"
|
||||||
|
android:theme="@style/Theme.AppCompat.DayNight.Dialog" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".ExitActivity"
|
android:name=".ExitActivity"
|
||||||
android:configChanges="keyboardHidden|orientation|screenSize|keyboard|navigation"
|
android:configChanges="keyboardHidden|orientation|screenSize|keyboard|navigation"
|
||||||
|
@ -24,6 +24,7 @@ import androidx.fragment.app.FragmentManager;
|
|||||||
import com.kdt.mcgui.ProgressLayout;
|
import com.kdt.mcgui.ProgressLayout;
|
||||||
import com.kdt.mcgui.mcAccountSpinner;
|
import com.kdt.mcgui.mcAccountSpinner;
|
||||||
|
|
||||||
|
import net.kdt.pojavlaunch.contextexecutor.ContextExecutor;
|
||||||
import net.kdt.pojavlaunch.fragments.MainMenuFragment;
|
import net.kdt.pojavlaunch.fragments.MainMenuFragment;
|
||||||
import net.kdt.pojavlaunch.fragments.MicrosoftLoginFragment;
|
import net.kdt.pojavlaunch.fragments.MicrosoftLoginFragment;
|
||||||
import net.kdt.pojavlaunch.extra.ExtraConstants;
|
import net.kdt.pojavlaunch.extra.ExtraConstants;
|
||||||
@ -183,12 +184,14 @@ public class LauncherActivity extends BaseActivity {
|
|||||||
@Override
|
@Override
|
||||||
protected void onResume() {
|
protected void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
|
ContextExecutor.setActivity(this);
|
||||||
mInstallTracker.attach();
|
mInstallTracker.attach();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPause() {
|
protected void onPause() {
|
||||||
super.onPause();
|
super.onPause();
|
||||||
|
ContextExecutor.clearActivity();
|
||||||
mInstallTracker.detach();
|
mInstallTracker.detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@ import java.util.concurrent.LinkedBlockingQueue;
|
|||||||
import java.util.concurrent.ThreadPoolExecutor;
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import net.kdt.pojavlaunch.contextexecutor.ContextExecutor;
|
||||||
import net.kdt.pojavlaunch.tasks.AsyncAssetManager;
|
import net.kdt.pojavlaunch.tasks.AsyncAssetManager;
|
||||||
import net.kdt.pojavlaunch.utils.*;
|
import net.kdt.pojavlaunch.utils.*;
|
||||||
|
|
||||||
@ -27,6 +28,7 @@ public class PojavApplication extends Application {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
|
ContextExecutor.setApplication(this);
|
||||||
Thread.setDefaultUncaughtExceptionHandler((thread, th) -> {
|
Thread.setDefaultUncaughtExceptionHandler((thread, th) -> {
|
||||||
boolean storagePermAllowed = (Build.VERSION.SDK_INT < 23 || Build.VERSION.SDK_INT >= 29 ||
|
boolean storagePermAllowed = (Build.VERSION.SDK_INT < 23 || Build.VERSION.SDK_INT >= 29 ||
|
||||||
ActivityCompat.checkSelfPermission(PojavApplication.this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) && Tools.checkStorageRoot(PojavApplication.this);
|
ActivityCompat.checkSelfPermission(PojavApplication.this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) && Tools.checkStorageRoot(PojavApplication.this);
|
||||||
@ -78,8 +80,14 @@ public class PojavApplication extends Application {
|
|||||||
startActivity(ferrorIntent);
|
startActivity(ferrorIntent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
public void onTerminate() {
|
||||||
|
super.onTerminate();
|
||||||
|
ContextExecutor.clearApplication();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
protected void attachBaseContext(Context base) {
|
protected void attachBaseContext(Context base) {
|
||||||
super.attachBaseContext(LocaleUtils.setLocale(base));
|
super.attachBaseContext(LocaleUtils.setLocale(base));
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,75 @@
|
|||||||
|
package net.kdt.pojavlaunch;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.app.NotificationManager;
|
||||||
|
import android.app.PendingIntent;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.core.app.NotificationCompat;
|
||||||
|
|
||||||
|
import net.kdt.pojavlaunch.contextexecutor.ContextExecutorTask;
|
||||||
|
import net.kdt.pojavlaunch.value.NotificationConstants;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
public class ShowErrorActivity extends Activity {
|
||||||
|
|
||||||
|
private static final String ERROR_ACTIVITY_REMOTE_TASK = "remoteTask";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
Intent intent = getIntent();
|
||||||
|
if(intent == null) {
|
||||||
|
finish();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
RemoteErrorTask remoteErrorTask = (RemoteErrorTask) intent.getSerializableExtra(ERROR_ACTIVITY_REMOTE_TASK);
|
||||||
|
if(remoteErrorTask == null) {
|
||||||
|
finish();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
remoteErrorTask.executeWithActivity(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class RemoteErrorTask implements ContextExecutorTask, Serializable {
|
||||||
|
private final Throwable mThrowable;
|
||||||
|
private final String mRolledMsg;
|
||||||
|
|
||||||
|
public RemoteErrorTask(Throwable mThrowable, String mRolledMsg) {
|
||||||
|
this.mThrowable = mThrowable;
|
||||||
|
this.mRolledMsg = mRolledMsg;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void executeWithActivity(Activity activity) {
|
||||||
|
Tools.showError(activity, mRolledMsg, mThrowable);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void executeWithApplication(Context context) {
|
||||||
|
sendNotification(context, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static void sendNotification(Context context, RemoteErrorTask remoteErrorTask) {
|
||||||
|
|
||||||
|
Intent showErrorIntent = new Intent(context, ShowErrorActivity.class);
|
||||||
|
showErrorIntent.putExtra(ERROR_ACTIVITY_REMOTE_TASK, remoteErrorTask);
|
||||||
|
|
||||||
|
PendingIntent pendingIntent = PendingIntent.getActivity(context, NotificationConstants.PENDINGINTENT_CODE_SHOW_ERROR, showErrorIntent,
|
||||||
|
Build.VERSION.SDK_INT >=23 ? PendingIntent.FLAG_IMMUTABLE : 0);
|
||||||
|
|
||||||
|
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
|
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context, context.getString(R.string.notif_channel_id))
|
||||||
|
.setContentTitle(context.getString(R.string.notif_error_occured))
|
||||||
|
.setContentText(context.getString(R.string.notif_error_occured_desc))
|
||||||
|
.setSmallIcon(R.drawable.notif_icon)
|
||||||
|
.setContentIntent(pendingIntent);
|
||||||
|
notificationManager.notify(NotificationConstants.NOTIFICATION_ID_SHOW_ERROR, notificationBuilder.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -46,6 +46,7 @@ import androidx.fragment.app.FragmentTransaction;
|
|||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
||||||
|
|
||||||
|
import net.kdt.pojavlaunch.contextexecutor.ContextExecutor;
|
||||||
import net.kdt.pojavlaunch.multirt.MultiRTUtils;
|
import net.kdt.pojavlaunch.multirt.MultiRTUtils;
|
||||||
import net.kdt.pojavlaunch.multirt.Runtime;
|
import net.kdt.pojavlaunch.multirt.Runtime;
|
||||||
import net.kdt.pojavlaunch.plugins.FFmpegPlugin;
|
import net.kdt.pojavlaunch.plugins.FFmpegPlugin;
|
||||||
@ -595,6 +596,26 @@ public final class Tools {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void showErrorRemote(Throwable e) {
|
||||||
|
showErrorRemote(null, e);
|
||||||
|
}
|
||||||
|
public static void showErrorRemote(Context context, int rolledMessage, Throwable e) {
|
||||||
|
showErrorRemote(context.getString(rolledMessage), e);
|
||||||
|
}
|
||||||
|
public static void showErrorRemote(String rolledMessage, Throwable e) {
|
||||||
|
// I WILL embrace layer violations because Android's concept of layers is STUPID
|
||||||
|
// We live in the same process anyway, why make it any more harder with this needless
|
||||||
|
// abstraction?
|
||||||
|
// Also, to @TorchDragon in r/AndroidDev discord: if Android is not for general computing,
|
||||||
|
// and all apps need so much babysitting, why did they put an SoC equivalent to
|
||||||
|
// my main PC in power?
|
||||||
|
|
||||||
|
// Add your Context-related rage here
|
||||||
|
ContextExecutor.execute(new ShowErrorActivity.RemoteErrorTask(e, rolledMessage));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static void dialogOnUiThread(final Activity activity, final CharSequence title, final CharSequence message) {
|
public static void dialogOnUiThread(final Activity activity, final CharSequence title, final CharSequence message) {
|
||||||
activity.runOnUiThread(()->dialog(activity, title, message));
|
activity.runOnUiThread(()->dialog(activity, title, message));
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,75 @@
|
|||||||
|
package net.kdt.pojavlaunch.contextexecutor;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.app.Application;
|
||||||
|
|
||||||
|
import net.kdt.pojavlaunch.Tools;
|
||||||
|
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
|
||||||
|
public class ContextExecutor {
|
||||||
|
private static WeakReference<Application> sApplication;
|
||||||
|
private static WeakReference<Activity> sActivity;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schedules a ContextExecutorTask to be executed. For more info on tasks, please read
|
||||||
|
* ContextExecutorTask.java
|
||||||
|
* @param contextExecutorTask the task to be executed
|
||||||
|
*/
|
||||||
|
public static void execute(ContextExecutorTask contextExecutorTask) {
|
||||||
|
Tools.runOnUiThread(()->executeOnUiThread(contextExecutorTask));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void executeOnUiThread(ContextExecutorTask contextExecutorTask) {
|
||||||
|
Activity activity = getWeakReference(sActivity);
|
||||||
|
if(activity != null) {
|
||||||
|
contextExecutorTask.executeWithActivity(activity);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Application application = getWeakReference(sApplication);
|
||||||
|
if(application != null) {
|
||||||
|
contextExecutorTask.executeWithApplication(application);
|
||||||
|
}else {
|
||||||
|
throw new RuntimeException("ContextExecutor.execute() called before Application.onCreate!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the Activity that this ContextExecutor will use for executing tasks
|
||||||
|
* @param activity the activity to be used
|
||||||
|
*/
|
||||||
|
public static void setActivity(Activity activity) {
|
||||||
|
sActivity = new WeakReference<>(activity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear the Activity previously set, so thet ContextExecutor won't use it to execute tasks.
|
||||||
|
*/
|
||||||
|
public static void clearActivity() {
|
||||||
|
if(sActivity != null)
|
||||||
|
sActivity.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the Application that will be used to execute tasks if the Activity won't be available.
|
||||||
|
* @param application the application to use as the fallback
|
||||||
|
*/
|
||||||
|
public static void setApplication(Application application) {
|
||||||
|
sApplication = new WeakReference<>(application);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear the Application previously set, so that ContextExecutor will notify the user of a critical error
|
||||||
|
* that is executing code after the application is ended by the system.
|
||||||
|
*/
|
||||||
|
public static void clearApplication() {
|
||||||
|
if(sApplication != null)
|
||||||
|
sApplication.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T> T getWeakReference(WeakReference<T> weakReference) {
|
||||||
|
if(weakReference == null) return null;
|
||||||
|
return weakReference.get();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package net.kdt.pojavlaunch.contextexecutor;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A ContextExecutorTask is a task that can dynamically change its behaviour, based on the context
|
||||||
|
* used for its execution. This can be used to implement for ex. error/finish notifications from
|
||||||
|
* background threads that may live with the Service after the activity that started them died.
|
||||||
|
*/
|
||||||
|
public interface ContextExecutorTask {
|
||||||
|
/**
|
||||||
|
* ContextExecutor will execute this function first if a foreground Activity that was attached to the
|
||||||
|
* ContextExecutor is available.
|
||||||
|
* @param activity the activity
|
||||||
|
*/
|
||||||
|
void executeWithActivity(Activity activity);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ContextExecutor will execute this function if a foreground Activity is not available, but the app
|
||||||
|
* is still running.
|
||||||
|
* @param context the application context
|
||||||
|
*/
|
||||||
|
void executeWithApplication(Context context);
|
||||||
|
}
|
@ -57,7 +57,7 @@ public interface ModpackApi {
|
|||||||
if (loaderInfo == null) return;
|
if (loaderInfo == null) return;
|
||||||
loaderInfo.getDownloadTask(new NotificationDownloadListener(context, loaderInfo)).run();
|
loaderInfo.getDownloadTask(new NotificationDownloadListener(context, loaderInfo)).run();
|
||||||
}catch (IOException e) {
|
}catch (IOException e) {
|
||||||
// TODO: pass on the IOException to a relevant handler
|
Tools.showErrorRemote(context, R.string.modpack_install_download_failed, e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ import net.kdt.pojavlaunch.R;
|
|||||||
import net.kdt.pojavlaunch.Tools;
|
import net.kdt.pojavlaunch.Tools;
|
||||||
import net.kdt.pojavlaunch.modloaders.ModloaderDownloadListener;
|
import net.kdt.pojavlaunch.modloaders.ModloaderDownloadListener;
|
||||||
import net.kdt.pojavlaunch.modloaders.modpacks.ModloaderInstallTracker;
|
import net.kdt.pojavlaunch.modloaders.modpacks.ModloaderInstallTracker;
|
||||||
|
import net.kdt.pojavlaunch.value.NotificationConstants;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
@ -46,21 +47,21 @@ public class NotificationDownloadListener implements ModloaderDownloadListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDownloadError(Exception e) {
|
public void onDownloadError(Exception e) {
|
||||||
Tools.runOnUiThread(()->sendEmptyNotification(R.string.modpack_install_notification_download_failed));
|
Tools.showErrorRemote(mContext, R.string.modpack_install_modloader_download_failed, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendIntentNotification(Intent intent, int contentText) {
|
private void sendIntentNotification(Intent intent, int contentText) {
|
||||||
PendingIntent pendingInstallIntent =
|
PendingIntent pendingInstallIntent =
|
||||||
PendingIntent.getActivity(mContext, 0,
|
PendingIntent.getActivity(mContext, NotificationConstants.PENDINGINTENT_CODE_DOWNLOAD_SERVICE,
|
||||||
intent, Build.VERSION.SDK_INT >=23 ? PendingIntent.FLAG_IMMUTABLE : 0);
|
intent, Build.VERSION.SDK_INT >=23 ? PendingIntent.FLAG_IMMUTABLE : 0);
|
||||||
|
|
||||||
mNotificationBuilder.setContentText(mContext.getText(contentText));
|
mNotificationBuilder.setContentText(mContext.getText(contentText));
|
||||||
mNotificationBuilder.setContentIntent(pendingInstallIntent);
|
mNotificationBuilder.setContentIntent(pendingInstallIntent);
|
||||||
mNotificationManager.notify(3, mNotificationBuilder.build());
|
mNotificationManager.notify(NotificationConstants.NOTIFICATION_ID_DOWNLOAD_LISTENER, mNotificationBuilder.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendEmptyNotification(int contentText) {
|
private void sendEmptyNotification(int contentText) {
|
||||||
mNotificationBuilder.setContentText(mContext.getText(contentText));
|
mNotificationBuilder.setContentText(mContext.getText(contentText));
|
||||||
mNotificationManager.notify(3, mNotificationBuilder.build());
|
mNotificationManager.notify(NotificationConstants.NOTIFICATION_ID_DOWNLOAD_LISTENER, mNotificationBuilder.build());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ import androidx.core.content.ContextCompat;
|
|||||||
|
|
||||||
import net.kdt.pojavlaunch.R;
|
import net.kdt.pojavlaunch.R;
|
||||||
import net.kdt.pojavlaunch.Tools;
|
import net.kdt.pojavlaunch.Tools;
|
||||||
|
import net.kdt.pojavlaunch.value.NotificationConstants;
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
|
|
||||||
@ -38,14 +39,15 @@ public class GameService extends Service {
|
|||||||
}
|
}
|
||||||
Intent killIntent = new Intent(getApplicationContext(), GameService.class);
|
Intent killIntent = new Intent(getApplicationContext(), GameService.class);
|
||||||
killIntent.putExtra("kill", true);
|
killIntent.putExtra("kill", true);
|
||||||
PendingIntent pendingKillIntent = PendingIntent.getService(this, 0, killIntent, Build.VERSION.SDK_INT >=23 ? PendingIntent.FLAG_IMMUTABLE : 0);
|
PendingIntent pendingKillIntent = PendingIntent.getService(this, NotificationConstants.PENDINGINTENT_CODE_KILL_GAME_SERVICE
|
||||||
|
, killIntent, Build.VERSION.SDK_INT >=23 ? PendingIntent.FLAG_IMMUTABLE : 0);
|
||||||
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, "channel_id")
|
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, "channel_id")
|
||||||
.setContentTitle(getString(R.string.lazy_service_default_title))
|
.setContentTitle(getString(R.string.lazy_service_default_title))
|
||||||
.setContentText(getString(R.string.notification_game_runs))
|
.setContentText(getString(R.string.notification_game_runs))
|
||||||
.addAction(android.R.drawable.ic_menu_close_clear_cancel, getString(R.string.notification_terminate), pendingKillIntent)
|
.addAction(android.R.drawable.ic_menu_close_clear_cancel, getString(R.string.notification_terminate), pendingKillIntent)
|
||||||
.setSmallIcon(R.drawable.notif_icon)
|
.setSmallIcon(R.drawable.notif_icon)
|
||||||
.setNotificationSilent();
|
.setNotificationSilent();
|
||||||
startForeground(2, notificationBuilder.build());
|
startForeground(NotificationConstants.NOTIFICATION_ID_GAME_SERVICE, notificationBuilder.build());
|
||||||
return START_NOT_STICKY; // non-sticky so android wont try restarting the game after the user uses the "Quit" button
|
return START_NOT_STICKY; // non-sticky so android wont try restarting the game after the user uses the "Quit" button
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ import net.kdt.pojavlaunch.R;
|
|||||||
import net.kdt.pojavlaunch.Tools;
|
import net.kdt.pojavlaunch.Tools;
|
||||||
import net.kdt.pojavlaunch.progresskeeper.ProgressKeeper;
|
import net.kdt.pojavlaunch.progresskeeper.ProgressKeeper;
|
||||||
import net.kdt.pojavlaunch.progresskeeper.TaskCountListener;
|
import net.kdt.pojavlaunch.progresskeeper.TaskCountListener;
|
||||||
|
import net.kdt.pojavlaunch.value.NotificationConstants;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lazy service which allows the process not to get killed.
|
* Lazy service which allows the process not to get killed.
|
||||||
@ -42,7 +43,8 @@ public class ProgressService extends Service implements TaskCountListener {
|
|||||||
notificationManagerCompat = NotificationManagerCompat.from(getApplicationContext());
|
notificationManagerCompat = NotificationManagerCompat.from(getApplicationContext());
|
||||||
Intent killIntent = new Intent(getApplicationContext(), ProgressService.class);
|
Intent killIntent = new Intent(getApplicationContext(), ProgressService.class);
|
||||||
killIntent.putExtra("kill", true);
|
killIntent.putExtra("kill", true);
|
||||||
PendingIntent pendingKillIntent = PendingIntent.getService(this, 0, killIntent, Build.VERSION.SDK_INT >=23 ? PendingIntent.FLAG_IMMUTABLE : 0);
|
PendingIntent pendingKillIntent = PendingIntent.getService(this, NotificationConstants.PENDINGINTENT_CODE_KILL_PROGRESS_SERVICE
|
||||||
|
, killIntent, Build.VERSION.SDK_INT >=23 ? PendingIntent.FLAG_IMMUTABLE : 0);
|
||||||
mNotificationBuilder = new NotificationCompat.Builder(this, "channel_id")
|
mNotificationBuilder = new NotificationCompat.Builder(this, "channel_id")
|
||||||
.setContentTitle(getString(R.string.lazy_service_default_title))
|
.setContentTitle(getString(R.string.lazy_service_default_title))
|
||||||
.addAction(android.R.drawable.ic_menu_close_clear_cancel, getString(R.string.notification_terminate), pendingKillIntent)
|
.addAction(android.R.drawable.ic_menu_close_clear_cancel, getString(R.string.notification_terminate), pendingKillIntent)
|
||||||
@ -62,7 +64,7 @@ public class ProgressService extends Service implements TaskCountListener {
|
|||||||
}
|
}
|
||||||
Log.d("ProgressService", "Started!");
|
Log.d("ProgressService", "Started!");
|
||||||
mNotificationBuilder.setContentText(getString(R.string.progresslayout_tasks_in_progress, ProgressKeeper.getTaskCount()));
|
mNotificationBuilder.setContentText(getString(R.string.progresslayout_tasks_in_progress, ProgressKeeper.getTaskCount()));
|
||||||
startForeground(1, mNotificationBuilder.build());
|
startForeground(NotificationConstants.NOTIFICATION_ID_PROGRESS_SERVICE, mNotificationBuilder.build());
|
||||||
if(ProgressKeeper.getTaskCount() < 1) stopSelf();
|
if(ProgressKeeper.getTaskCount() < 1) stopSelf();
|
||||||
else ProgressKeeper.addTaskCountListener(this, false);
|
else ProgressKeeper.addTaskCountListener(this, false);
|
||||||
|
|
||||||
|
@ -0,0 +1,12 @@
|
|||||||
|
package net.kdt.pojavlaunch.value;
|
||||||
|
|
||||||
|
public class NotificationConstants {
|
||||||
|
public static final int NOTIFICATION_ID_PROGRESS_SERVICE = 1;
|
||||||
|
public static final int NOTIFICATION_ID_GAME_SERVICE = 2;
|
||||||
|
public static final int NOTIFICATION_ID_DOWNLOAD_LISTENER = 3;
|
||||||
|
public static final int NOTIFICATION_ID_SHOW_ERROR = 4;
|
||||||
|
public static final int PENDINGINTENT_CODE_KILL_PROGRESS_SERVICE = 1;
|
||||||
|
public static final int PENDINGINTENT_CODE_KILL_GAME_SERVICE = 2;
|
||||||
|
public static final int PENDINGINTENT_CODE_DOWNLOAD_SERVICE = 3;
|
||||||
|
public static final int PENDINGINTENT_CODE_SHOW_ERROR = 4;
|
||||||
|
}
|
@ -423,5 +423,9 @@
|
|||||||
<string name="modpack_install_notification_title">Pojav Modpack Installer</string>
|
<string name="modpack_install_notification_title">Pojav Modpack Installer</string>
|
||||||
<string name="modpack_install_notification_success">Click here to finish modpack installation</string>
|
<string name="modpack_install_notification_success">Click here to finish modpack installation</string>
|
||||||
<string name="modpack_install_notification_data_not_available">Failed to download mod loader information</string>
|
<string name="modpack_install_notification_data_not_available">Failed to download mod loader information</string>
|
||||||
<string name="modpack_install_notification_download_failed">Failed to download the mod loader files</string>
|
<string name="modpack_install_modloader_download_failed">Failed to download the mod loader files</string>
|
||||||
|
<string name="modpack_install_download_failed">Failed to download modpack files</string>
|
||||||
|
|
||||||
|
<string name="notif_error_occured">An error has occurred</string>
|
||||||
|
<string name="notif_error_occured_desc">Click to see more details</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user