mirror of
https://gitlab.com/neothefox/LayTray
synced 2026-03-23 21:54:54 +03:00
220 lines
8.6 KiB
Java
220 lines
8.6 KiB
Java
package space.neothefox.laytray;
|
|
|
|
import android.accessibilityservice.AccessibilityService;
|
|
import android.accessibilityservice.AccessibilityServiceInfo;
|
|
import android.app.Notification;
|
|
import android.app.NotificationChannel;
|
|
import android.app.NotificationManager;
|
|
import android.content.Context;
|
|
import android.content.SharedPreferences;
|
|
import android.graphics.Bitmap;
|
|
import android.graphics.Canvas;
|
|
import android.graphics.Color;
|
|
import android.graphics.Paint;
|
|
import android.graphics.PorterDuff;
|
|
import android.graphics.PorterDuffXfermode;
|
|
import android.graphics.RectF;
|
|
import android.graphics.drawable.Icon;
|
|
import android.os.Build;
|
|
import android.preference.PreferenceManager;
|
|
import android.util.Log;
|
|
import android.view.accessibility.AccessibilityEvent;
|
|
|
|
import static android.graphics.Paint.ANTI_ALIAS_FLAG;
|
|
|
|
|
|
@SuppressWarnings("SuspiciousNameCombination")
|
|
public class IconService extends AccessibilityService
|
|
implements SharedPreferences.OnSharedPreferenceChangeListener
|
|
{
|
|
|
|
public static final String TAG = "layicon";
|
|
public static final String channelId = "space.neothefox.laytray.IC";
|
|
private final AccessibilityServiceInfo serviceInfo = new AccessibilityServiceInfo();
|
|
|
|
private SharedPreferences layouts;
|
|
private SharedPreferences options;
|
|
private String lastToast;
|
|
|
|
private NotificationManager iconManager;
|
|
private NotificationChannel iconChannel;
|
|
|
|
@Override
|
|
protected void onServiceConnected()
|
|
{
|
|
super.onServiceConnected();
|
|
Log.d(TAG, "Icon service started");
|
|
serviceInfo.eventTypes = AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED;
|
|
serviceInfo.packageNames = new String[] {"com.blackberry.keyboard"};
|
|
serviceInfo.feedbackType = AccessibilityServiceInfo.FEEDBACK_VISUAL;
|
|
serviceInfo.notificationTimeout = 100;
|
|
this.setServiceInfo(serviceInfo);
|
|
layouts = getSharedPreferences("layouts", 0);
|
|
options = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
|
|
lastToast = "EMPT";
|
|
options.registerOnSharedPreferenceChangeListener(this);
|
|
|
|
iconManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
|
|
{
|
|
try
|
|
{
|
|
iconChannel = iconManager.getNotificationChannel(channelId);
|
|
}
|
|
catch (NullPointerException e)
|
|
{
|
|
Log.d(TAG, "No NotificationChannel found");
|
|
}
|
|
if(iconChannel == null) {
|
|
iconChannel = new NotificationChannel(
|
|
channelId,
|
|
getString(R.string.title_icon_channel),
|
|
NotificationManager.IMPORTANCE_LOW);
|
|
iconChannel.setShowBadge(false);
|
|
iconChannel.enableLights(false);
|
|
iconChannel.enableVibration(false);
|
|
iconChannel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
|
|
iconManager.createNotificationChannel(iconChannel);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void updateNotification(String toast)
|
|
{
|
|
Notification indicator;
|
|
String textIcon = layouts.getString(toast,"EMPT");
|
|
if(textIcon.equals("EMPT"))
|
|
{
|
|
SharedPreferences.Editor layoutsEditor = layouts.edit();
|
|
layoutsEditor.putString(toast, "??");
|
|
layoutsEditor.apply();
|
|
textIcon = "??";
|
|
}
|
|
Icon smallIcon = Icon.createWithBitmap(textAsBitmap(textIcon,
|
|
Integer.parseInt(options.getString("textSize", "48")),
|
|
options.getBoolean("textFakeBold", true),
|
|
Integer.parseInt(options.getString("textMode", "0")),
|
|
Color.WHITE));
|
|
|
|
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
|
|
{
|
|
indicator = new Notification.Builder(this, channelId)
|
|
.setSmallIcon(smallIcon)
|
|
.setContentTitle(toast)
|
|
.setOngoing(true)
|
|
.setVisibility(Notification.VISIBILITY_SECRET)
|
|
.build();
|
|
}
|
|
else
|
|
{
|
|
indicator = new Notification.Builder(this)
|
|
.setSmallIcon(smallIcon)
|
|
.setContentTitle(toast)
|
|
.setOngoing(true)
|
|
.setPriority(Integer.parseInt(options.getString("notificationImportance", "0")))
|
|
.setVisibility(Notification.VISIBILITY_SECRET)
|
|
.build();
|
|
}
|
|
iconManager.notify(0, indicator);
|
|
return;
|
|
}
|
|
|
|
//Borrowed from Ted Hopp from StackOverflow
|
|
public static Bitmap textAsBitmap(String text, float textSize, boolean fakeBold, int mode, int textColor)
|
|
{
|
|
Paint paint = new Paint(ANTI_ALIAS_FLAG);
|
|
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT));
|
|
paint.setTextSize(textSize);
|
|
paint.setFakeBoldText(fakeBold);
|
|
paint.setColor(textColor);
|
|
switch (mode)
|
|
{
|
|
case 1: {
|
|
int width = 48;
|
|
int height = 48;
|
|
Bitmap image = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
|
Canvas canvas = new Canvas(image);
|
|
canvas.drawCircle(width / 2f, height / 2f, width / 2f, paint);
|
|
paint.setAlpha(255);
|
|
paint.setColor(Color.TRANSPARENT);
|
|
paint.setTextSize(textSize);
|
|
paint.setTextAlign(Paint.Align.CENTER);
|
|
canvas.drawText(text, width/2f, ((height/2f) - (paint.descent()+paint.ascent())/2f), paint);
|
|
return image;
|
|
}
|
|
|
|
case 2: {
|
|
int width = 48;
|
|
int height = 48;
|
|
Bitmap image = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
|
Canvas canvas = new Canvas(image);
|
|
canvas.drawRoundRect(new RectF(0, 0, height, width), 5, 5, paint);
|
|
paint.setAlpha(255);
|
|
paint.setColor(Color.TRANSPARENT);
|
|
paint.setTextSize(textSize);
|
|
paint.setTextAlign(Paint.Align.CENTER);
|
|
canvas.drawText(text, width / 2f, ((height/2f) - (paint.descent()+paint.ascent())/2f), paint);
|
|
return image;
|
|
}
|
|
|
|
case 3: {
|
|
int width = 48;
|
|
int height = 48;
|
|
Bitmap image = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
|
Canvas canvas = new Canvas(image);
|
|
canvas.drawRoundRect(new RectF(0, 0, height, width), 5, 5, paint);
|
|
paint.setAlpha(255);
|
|
paint.setColor(Color.TRANSPARENT);
|
|
canvas.drawRoundRect(new RectF(2,2,height-2,width-2), 5, 5, paint);
|
|
paint.setColor(textColor);
|
|
paint.setTextSize(textSize);
|
|
paint.setTextAlign(Paint.Align.CENTER);
|
|
canvas.drawText(text, width / 2f, ((height/2f) - (paint.descent()+paint.ascent())/2f), paint);
|
|
return image;
|
|
}
|
|
|
|
case 0:
|
|
default:
|
|
paint.setTextAlign(Paint.Align.LEFT);
|
|
float baseline = -paint.ascent(); // ascent() is negative
|
|
int width = (int) (paint.measureText(text) + 0.5f); // round
|
|
int height = (int) (baseline + paint.descent() + 0.5f);
|
|
Bitmap image = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
|
Canvas canvas = new Canvas(image);
|
|
canvas.drawText(text, 0, baseline, paint);
|
|
return image;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onAccessibilityEvent(AccessibilityEvent event)
|
|
{
|
|
|
|
Log.d(TAG, event.toString());
|
|
if(event.getEventType() == AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED)
|
|
{
|
|
Log.d(TAG, "Caught a Toast: ");
|
|
Log.d(TAG, (String)event.getPackageName());
|
|
lastToast = (String)event.getText().get(0);
|
|
Log.d(TAG, lastToast);
|
|
|
|
updateNotification(lastToast);
|
|
}
|
|
else
|
|
Log.d(TAG, "Caution! This service had been tampered with!");
|
|
|
|
}
|
|
|
|
@Override
|
|
public void onInterrupt()
|
|
{
|
|
}
|
|
|
|
@Override
|
|
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key)
|
|
{
|
|
options = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
|
|
updateNotification(lastToast);
|
|
}
|
|
}
|