/*
Copyright (C) 2013, TecVis LP, support@tecvis.co.uk
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation as version 2.1 of the License.
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 Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this library; if not, write to the Free Software Foundation, Inc.,
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package com.airs.handlers;
import com.airs.R;
import android.accessibilityservice.AccessibilityService;
import android.accessibilityservice.AccessibilityServiceInfo;
import android.app.Notification;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.util.Log;
import android.view.accessibility.AccessibilityEvent;
/**
* Class to implement the AIRS accessibility service
*/
public class NotificationHandlerService extends AccessibilityService
{
boolean started = true;
/**
* Called when an accessibility event occurs - here, we check the particular component packages that fired the event, filtering out the ones we support
* @param event Reference to the fired {android.view.accessibility.AccessibilityEvent}
* @see android.accessibilityservice.AccessibilityService#onAccessibilityEvent(android.view.accessibility.AccessibilityEvent)
*/
@Override
public void onAccessibilityEvent(AccessibilityEvent event)
{
if (event.getEventType() == AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED)
{
// get notification shown
Notification notification = (Notification)event.getParcelableData();
if (notification != null)
{
// now parse the specific packages we support
// start with GTalk
if (event.getPackageName().toString().compareTo("com.google.android.talk") == 0)
{
// now broadcast the capturing of the accessibility service to the handler
Intent intent = new Intent("com.airs.accessibility");
intent.putExtra("NotifyText", "gtalk::" + notification.tickerText);
sendBroadcast(intent);
}
// anything from Skype?
if (event.getPackageName().toString().compareTo("com.skype.raider") == 0)
{
// now broadcast the capturing of the accessibility service to the handler
Intent intent = new Intent("com.airs.accessibility");
intent.putExtra("NotifyText", "skype::Message from " + notification.tickerText);
sendBroadcast(intent);
}
// anything from Spotify?
if (event.getPackageName().toString().compareTo("com.spotify.music") == 0)
{
// now broadcast the capturing of the accessibility service to the handler
// anything delivered?
if (notification.tickerText != null)
{
// split information in tokens
String tokens[] = notification.tickerText.toString().split(getString(R.string.accessibility_spotify));
// try other '-', if previous one did not work
if (tokens.length != 2)
tokens = notification.tickerText.toString().split("-");
if (tokens.length == 2)
{
// signal as play state changed event
Intent intent = new Intent("com.android.music.playstatechanged");
intent.putExtra("track", tokens[0].trim());
intent.putExtra("artist", tokens[1].trim());
intent.putExtra("album", "");
sendBroadcast(intent);
}
else
Log.e("AIRS", "Can't find token in '" + notification.tickerText +"'");
}
}
}
}
}
/**
* Called when the service is started (usually after boot). We register the events we are interested in (change of notification) and also register to the start broadcast event, sent by AIRS
* Originally, we set the package filters to something that does not exist, so that we minimise the firing of the callback
* After the start broadcast event will be received, the proper package names will be set for recording
* @see android.accessibilityservice.AccessibilityService#onServiceConnected()
*/
@Override
protected void onServiceConnected()
{
// register for any input from the accessbility service
IntentFilter intentFilter = new IntentFilter("com.airs.accessibility.start");
registerReceiver(SystemReceiver, intentFilter);
// now switch off initially
AccessibilityServiceInfo info = new AccessibilityServiceInfo();
info.eventTypes = AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED;
info.notificationTimeout = 100;
info.feedbackType = AccessibilityServiceInfo.FEEDBACK_VISUAL;
info.packageNames = new String[] {"com.airs.helpers" };
// info.packageNames = new String[] {"com.skype.raider", "com.google.android.gsf" };
setServiceInfo(info);
}
/*
* Called when interrupting the service
* @see android.accessibilityservice.AccessibilityService#onInterrupt()
*/
@Override
public void onInterrupt()
{
}
/*
* Called when destroying the service
* @see android.app.Service#onDestroy()
*/
@Override
public void onDestroy()
{
super.onDestroy();
}
private final BroadcastReceiver SystemReceiver = new BroadcastReceiver()
{
@Override
public void onReceive(Context context, Intent intent)
{
String action = intent.getAction();
// if anything sent from the accessbility service
if (action.equals("com.airs.accessibility.start"))
{
// start the gathering?
if (intent.getBooleanExtra("start", true) == true)
{
AccessibilityServiceInfo info = new AccessibilityServiceInfo();
info.eventTypes = AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED;
info.notificationTimeout = 100;
info.feedbackType = AccessibilityServiceInfo.FEEDBACK_VISUAL;
info.packageNames = new String[] {"com.skype.raider", "com.google.android.talk", "com.spotify.music"};
setServiceInfo(info);
started = true;
}
else // or stop it?
{
AccessibilityServiceInfo info = new AccessibilityServiceInfo();
info.eventTypes = AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED;
info.notificationTimeout = 100;
info.feedbackType = AccessibilityServiceInfo.FEEDBACK_VISUAL;
info.packageNames = new String[] {"com.airs.helpers" };
setServiceInfo(info);
started = false;
}
}
}
};
}