com.yangtsaosoftware.pebblemessenger.services.NotificationService.java Source code

Java tutorial

Introduction

Here is the source code for com.yangtsaosoftware.pebblemessenger.services.NotificationService.java

Source

/*
 * Pebble Messenger is used to display non-english message on Pebble.
 * Copyright (C) 2014  Yang Tsao
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

package com.yangtsaosoftware.pebblemessenger.services;

import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.PowerManager;
import android.os.RemoteException;
import android.provider.Telephony;
import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
import android.support.v4.content.LocalBroadcastManager;

import com.yangtsaosoftware.pebblemessenger.Constants;
import com.yangtsaosoftware.pebblemessenger.db.MessageDbHandler;

import android.app.Notification;

import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.util.Log;

public class NotificationService extends NotificationListenerService {
    private static final String LOG_TAG = "NotificationService";

    private boolean notifScreenOn = true;
    private String[] packages = null;

    private Messenger rMessageProcessHandler = null;

    private final ServiceConnection connToMessageProcess = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            rMessageProcessHandler = new Messenger(iBinder);
            Constants.log(LOG_TAG, "Connect to MessageProcessHandler!");
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            rMessageProcessHandler = null;
        }
    };

    public NotificationService() {
    }

    @Override
    public void onNotificationPosted(StatusBarNotification sbn) {
        if (sbn == null)
            return;
        Constants.log(LOG_TAG, "New Access Event:" + sbn.getPackageName() + " tag:" + sbn.getTag());
        /*if(event.getEventType()!= AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED){
            
        return;
        }
        */
        PowerManager powMan = (PowerManager) this.getSystemService(POWER_SERVICE);
        if (!notifScreenOn && powMan.isScreenOn()) {
            Constants.log(LOG_TAG, "because screen out!");
            return;
        }
        //Parcelable parcelable=event.getParcelableData();
        //if(!(parcelable instanceof Notification)) return;
        Notification notif = sbn.getNotification();
        if (sbn.isOngoing()) {
            Constants.log(LOG_TAG, "because is Ongoing!");
            return;
        }

        String eventPackageName;

        if (sbn.getPackageName() != null) {
            eventPackageName = sbn.getPackageName();
        } else {
            Constants.log(LOG_TAG, "Can't get event package name. Returning.");
            return;
        }

        boolean found = false;
        for (String packageName : packages) {
            if (packageName.equalsIgnoreCase(eventPackageName)) {
                found = true;
                break;
            }
        }
        if (!found) {
            Constants.log(LOG_TAG, eventPackageName + " was not found in the include list. Returning.");
            return;
        }
        String title = eventPackageName.substring(eventPackageName.lastIndexOf('.') + 1);
        // get the notification text
        Bundle notiBundle = notif.extras;
        StringBuilder notifySb = new StringBuilder();
        CharSequence notifyChars = notiBundle.getCharSequence(Notification.EXTRA_TITLE);
        if (notifyChars != null) {
            notifySb.append(notifyChars);
        } else {
            Constants.log(LOG_TAG, "empty message title,return!");
            return;
        }

        CharSequence bodyCS = notiBundle.getCharSequence(Notification.EXTRA_TEXT);
        if (bodyCS != null) {
            notifySb.append(":");
            notifySb.append(bodyCS);
        } else {
            Constants.log(LOG_TAG, "empty message body,return!" + notifySb.toString());
            return;
        }
        bodyCS = notiBundle.getCharSequence(Notification.EXTRA_SUB_TEXT);
        if (bodyCS != null) {
            notifySb.append(bodyCS);
        }

        Message msg = Message.obtain();
        msg.what = MessageProcessingService.MSG_NEW_MESSAGE;
        Bundle b = new Bundle();
        b.putString(MessageDbHandler.COL_MESSAGE_APP, title);
        b.putString(MessageDbHandler.COL_MESSAGE_CONTENT, notifySb.toString());
        Constants.log(LOG_TAG, "Send new message title:" + title + " body:" + notifySb.toString());
        msg.setData(b);
        try {
            rMessageProcessHandler.send(msg);
        } catch (RemoteException e) {
            e.printStackTrace();
            Constants.log(LOG_TAG, "Error when sending message to MessageProcessingService.");
        }
    }

    @Override
    public void onNotificationRemoved(StatusBarNotification statusBarNotification) {

    }

    /*@Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
    if(event==null) return;
    Constants.log(LOG_TAG,"New Access Event:"+ String.valueOf(event.getEventType()));
    if(event.getEventType()!= AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED){
        
        return;
    }
    PowerManager powMan = (PowerManager) this.getSystemService(POWER_SERVICE);
    if (!notifScreenOn && powMan.isScreenOn()) {
        return;
    }
    Parcelable parcelable=event.getParcelableData();
    if(!(parcelable instanceof Notification)) return;
    Notification notif=(Notification) parcelable;
       if((notif.flags & Notification.FLAG_ONGOING_EVENT)==Notification.FLAG_ONGOING_EVENT){
       return;
       }
        
    String eventPackageName;
        
    if (event.getPackageName() != null) {
        eventPackageName = event.getPackageName().toString();
    } else {
        Constants.log(LOG_TAG, "Can't get event package name. Returning.");
        return;
    }
        
    boolean found = false;
    for (String packageName : packages) {
        if (packageName.equalsIgnoreCase(eventPackageName)) {
            found = true;
            break;
        }
    }
    if (!found) {
        Constants.log(LOG_TAG, eventPackageName + " was not found in the include list. Returning.");
        return;
    }
    String title = eventPackageName.substring(eventPackageName.lastIndexOf('.')+1);
    // get the notification text
    String notificationText = event.getText().toString();
    // strip the first and last characters which are [ and ]
    notificationText = notificationText.substring(1, notificationText.length() - 1);
    if (!eventPackageName.contentEquals("com.android.mms")) {
        Constants.log(LOG_TAG, "Fetching extras from notification");
        String str = getExtraBigData((Notification) parcelable, notificationText);
        notificationText += "\n" + str;
    }
    if (notificationText.length() == 0) {
        return;
    }
    Message msg=Message.obtain();
    msg.what=MessageProcessingService.MSG_NEW_MESSAGE;
    Bundle b=new Bundle();
    b.putString(MessageDbHandler.COL_MESSAGE_APP,title);
    b.putString(MessageDbHandler.COL_MESSAGE_CONTENT,notificationText);
    Constants.log(LOG_TAG,"Send new message title:"+ title + " boty:" + notificationText);
    msg.setData(b);
    try {
        rMessageProcessHandler.send(msg);
    } catch (RemoteException e) {
        e.printStackTrace();
        Constants.log(LOG_TAG,"Error when sending message to MessageProcessingService.");
    }
        
    }*/

    /*   private String getExtraBigData(Notification notification, String existing_text) {
    RemoteViews views;
    try {
        views = notification.bigContentView;
    } catch (NoSuchFieldError e) {
        return getExtraData(notification, existing_text);
    }
    if (views == null) {
        Constants.log(LOG_TAG, "bigContentView was empty, running normal");
        
        return getExtraData(notification, existing_text);
    }
    LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    try {
        ViewGroup localView = (ViewGroup) inflater.inflate(views.getLayoutId(), null);
        views.reapply(getApplicationContext(), localView);
        return dumpViewGroup(0, localView, existing_text);
    } catch (android.content.res.Resources.NotFoundException e) {
        return "";
    }
       }
        
       private String getExtraData(Notification notification, String existing_text) {
    Constants.log(LOG_TAG, "I am running extra data");
        
    RemoteViews views = notification.contentView;
    if (views == null) {
        Constants.log(LOG_TAG, "ContentView was empty, returning a blank string");
        
        return "";
    }
        
    LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    try {
        ViewGroup localView = (ViewGroup) inflater.inflate(views.getLayoutId(), null);
        views.reapply(getApplicationContext(), localView);
        return dumpViewGroup(0, localView, existing_text);
    } catch (android.content.res.Resources.NotFoundException e) {
        return "";
    } catch (RemoteViews.ActionException e) {
        return "";
    }
       }
        
       private String dumpViewGroup(int depth, ViewGroup vg, String existing_text) {
    String text = "";
    Constants.log(LOG_TAG, "root view, depth:" + depth + "; view: " + vg);
    for (int i = 0; i < vg.getChildCount(); ++i) {
        
        View v = vg.getChildAt(i);
        Constants.log(LOG_TAG, "depth: " + depth + "; " + v.getClass().toString() + "; view: " + v);
        
        if (v.getId() == android.R.id.title || v instanceof android.widget.Button
                || v.getClass().toString().contains("android.widget.DateTimeView")) {
            Constants.log(LOG_TAG, "I am going to skip this, but if I didn't, the text would be: "
                        + ((TextView) v).getText().toString());
            if (existing_text.isEmpty() && v.getId() == android.R.id.title) {
                Constants.log(LOG_TAG,
                            "I was going to skip this, but the existing text was empty, and I need something.");
            } else {
                continue;
            }
        }
        
        if (v instanceof TextView) {
            TextView tv = (TextView) v;
            if (tv.getText().toString().equalsIgnoreCase("...") || tv.getText().toString().equalsIgnoreCase("")
                    || isInteger(tv.getText().toString()) || existing_text.contains(tv.getText().toString().trim())) {
                Constants.log(LOG_TAG, "Text is: " + tv.getText().toString()
                            + " but I am going to skip this");
                continue;
            }
            text += tv.getText().toString() + "\n";
            Constants.log(LOG_TAG, tv.getText().toString());
        }
        if (v instanceof ViewGroup) {
            text += dumpViewGroup(depth + 1, (ViewGroup) v, existing_text);
        }
    }
    return text;
       }
        
       public boolean isInteger(String input) {
    try {
        Integer.parseInt(input);
        return true;
    } catch (Exception e) {
        return false;
    }
       }
    */
    private void loadPrefs() {
        SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
        packages = sharedPref.getString(Constants.PREFERENCE_PACKAGE_LIST, "").split(",");
        if (sharedPref.getBoolean(Constants.PREFERENCE_SMS_ENABLE, true)) {
            String smspackage = Telephony.Sms.getDefaultSmsPackage(getBaseContext());
            for (int i = 0; i < packages.length; i++) {
                if (packages[i].equalsIgnoreCase(smspackage)) {
                    packages[i] = "";
                    break;
                }
            }
        }
        notifScreenOn = sharedPref.getBoolean(Constants.PREFERENCE_NOTIF_SCREEN_ON, true);
    }

    @Override
    public void onDestroy() {
        unbindService(connToMessageProcess);

    }

    @Override
    public void onCreate() {
        super.onCreate();
        loadPrefs();
        bindService(new Intent(this, MessageProcessingService.class), connToMessageProcess,
                Context.BIND_AUTO_CREATE);
        BroadcastReceiver br = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {

                loadPrefs();
            }
        };
        IntentFilter intentFilter = new IntentFilter(NotificationService.class.getName());
        LocalBroadcastManager.getInstance(getApplicationContext()).registerReceiver(br, intentFilter);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return START_STICKY;
    }

}