1
0
mirror of https://gitlab.com/neothefox/LayTray synced 2026-03-23 21:54:54 +03:00
2018-07-28 16:19:10 +03:00

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);
}
}