package space.neothefox.laytray; import android.accessibilityservice.AccessibilityService; import android.accessibilityservice.AccessibilityServiceInfo; import android.app.Notification; 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.preference.PreferenceManager; import android.util.Log; import android.view.accessibility.AccessibilityEvent; import static android.graphics.Paint.ANTI_ALIAS_FLAG; public class IconService extends AccessibilityService implements SharedPreferences.OnSharedPreferenceChangeListener{ public String TAG = "layicon"; private final AccessibilityServiceInfo serviceInfo = new AccessibilityServiceInfo(); SharedPreferences layouts; SharedPreferences options; String lastToast; NotificationManager iconManager; @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); } protected void updateNotification(String toast) { Notification indicator; String textIcon = layouts.getString(toast,"EMPT"); if(textIcon == "EMPT") { SharedPreferences.Editor layoutsEditor = layouts.edit(); layoutsEditor.putString(toast, "??"); layoutsEditor.commit(); 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)); indicator = new Notification.Builder(this) .setSmallIcon(smallIcon) .setContentTitle(toast) .setOngoing(true) .setPriority(Integer.parseInt(options.getString("notificationImportance", "0"))) .build(); iconManager.notify(0, indicator); return; } //Borrowed from Ted Hopp from StackOverflow public 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: { float baseline = -paint.ascent(); // ascent() is negative 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 + textSize / 2f, paint); return image; } case 2: { float baseline = -paint.ascent(); // ascent() is negative 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 + textSize / 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); } }