通知イベントを傍受するために AccessibiltyService を拡張しようとしています。私の問題は、私のクラスがサービスに接続しないことによって作成されることです。
これが私のアプリの仕組みです:
- いくつかの統計の収集を管理し、通知イベントも監視する必要があるサービス (StatisticsService) があります。
- そのために、対象の統計ごとに StatCollector (Java オブジェクト) を作成します。
- すべての StatCollector は同じインターフェースを実装し、作成されると StatisticService コンテキストを保存します。
- この StatCollector の 1 つが、AccessibilityService を拡張する NotificationService を開始します。
関連するクラスは次のとおりです。
StatCollector:
public class NotificationCollector implements
StatCollectorInterface {
private Context context = null;
private Intent notificationServiceIntent = null;
private boolean collectorStarted = false;
/**Constructor**/
public NotificationCollector(Context context) {
this.context = context;
collectorStarted = false;
}
@Override
public void startCollector() {
if (collectorStarted == true)
{
return;
}
collectorStarted = true;
notificationServiceIntent = new Intent(context,NotificationService.class);
context.startService(notificationServiceIntent);
}
@Override
public void stopCollector() {
if (collectorStarted == false)
{
return;
}
collectorStarted = false;
context.stopService(notificationServiceIntent);
}
通知サービス:
public class NotificationService extends AccessibilityService {
private static final Logger logger = LoggerFactory.getLogger ("Notification");
@Override
public void onCreate()
{
logger.trace("onCreate");
super.onCreate();
}
@Override
public void onDestroy()
{
logger.trace("onDestroy");
super.onDestroy();
}
/**Methods from Accessibility Service**/
@Override
protected void onServiceConnected() {
logger.trace("onServiceConnected");
AccessibilityServiceInfo info = new AccessibilityServiceInfo();
info.eventTypes = AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED;
info.feedbackType = AccessibilityServiceInfo.FEEDBACK_ALL_MASK;
info.notificationTimeout = 100;
setServiceInfo(info);
}
@Override
public void onInterrupt() {
// TODO Auto-generated method stub
}
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
logger.trace("onAccessibilityEvent");
if (event.getEventType() == AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED) {
logger.trace("notification: " + event.getText());
}
}
}
Manifest.xml: (関連コンポーネント)
<service android:name=".StatisticsService"/>
<service android:name=".service.NotificationService">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
<meta-data
android:name="android.accessibilityservice"
android:resource="@xml/accessibilityservice" />
</service>
...
<uses-permission android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"/>
android.permission.BIND_ACCESSIBILITY_SERVICE を NotificationService に追加すると、アプリが次のエラーでクラッシュすることに注意してください
java.lang.RuntimeException: Unable to start service my.app.StatisticsService@406657d0
with Intent { cmp=my.app/.StatisticsService (has extras) }: java.lang.SecurityException:
Not allowed to start service Intent { cmp=my.app/.NotificationService } without permission android.permission.BIND_ACCESSIBILITY_SERVICE
問題は、BIND_ACCESSIBILITY_SERVICE 権限があることを明示的に言及していないため、システムが NotificationService クラスを無視していることだと思います。しかし、マニフェスト ファイルのサービスに追加すると、アプリがクラッシュします。
私は何が欠けていますか/間違っていますか?
ありがとう
アップデート
Dr.Cyanideのコメントのおかげで、特定のアプリのアクセシビリティは、ユーザーが [設定] の [アクセシビリティ] メニューで有効にする必要があることがわかりました。
さらにタグは
<uses-permission android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"/>
ジェリービーン以前のバージョンには必要ないので、ICSを使用しているので削除しました。
アプリは期待どおりに動作するようになりました