{"id":268885,"date":"2015-11-24T14:01:02","date_gmt":"2015-11-24T11:01:02","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=268885"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=268885","title":{"rendered":"\u041e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u0435 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0439 \u043d\u0430 Android 4.0-4.2"},"content":{"rendered":"<p>       <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/01f\/ff3\/997\/01fff3997752478b98e640942a845b82.jpg\" align=\"left\"\/> \u041d\u0430\u0447\u0438\u043d\u0430\u044f \u0441 \u0432\u0435\u0440\u0441\u0438\u0438 4.3 \u0432 Android OS \u0431\u044b\u043b\u0430 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f <a href=\"http:\/\/developer.android.com\/reference\/android\/service\/notification\/NotificationListenerService.html\">NotificationListenerService<\/a>. \u041a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u043e\u0431\u0440\u0430\u0442\u043d\u0430\u044f \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e\u0441\u0442\u044c \u0441 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u043c\u0438 \u0432\u0435\u0440\u0441\u0438\u044f\u043c\u0438 OS \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442. \u0427\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c, \u0435\u0441\u043b\u0438 \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c \u043d\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430\u0445 \u0441 \u0431\u043e\u043b\u0435\u0435 \u0441\u0442\u0430\u0440\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0435\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b?<\/p>\n<p>  \u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u043d\u0430\u0431\u043e\u0440 \u043a\u043e\u0441\u0442\u044b\u043b\u0435\u0439 \u0438 \u0445\u0430\u043a\u043e\u0432 \u0434\u043b\u044f \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0439 \u043d\u0430 Android OS \u0432\u0435\u0440\u0441\u0438\u0438 4.0-4.2. \u041d\u0435 \u043d\u0430 \u0432\u0441\u0435\u0445 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430\u0445 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 100% \u0440\u0430\u0431\u043e\u0442\u043e\u0441\u043f\u043e\u0441\u043e\u0431\u0435\u043d, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043a\u043e\u0441\u0442\u044b\u043b\u0438, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0439 \u0432 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445.<br \/>  <a name=\"habracut\"><\/a><br \/>  \u041f\u043e\u0438\u0441\u043a \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u0432 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0435 \u043f\u043e \u044d\u0442\u043e\u043c\u0443 \u0432\u043e\u043f\u0440\u043e\u0441\u0443 \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u0432\u044b\u0432\u043e\u0434\u0443, \u0447\u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <a href=\"http:\/\/developer.android.com\/reference\/android\/accessibilityservice\/AccessibilityService.html\">AccessibilityService<\/a> \u0438 \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u0435 <a href=\"http:\/\/developer.android.com\/reference\/android\/view\/accessibility\/AccessibilityEvent.html#TYPE_NOTIFICATION_STATE_CHANGED\">TYPE_NOTIFICATION_STATE_CHANGED<\/a>. \u0422\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u043a\u0430\u0437\u0430\u043b\u043e, \u0447\u0442\u043e \u0434\u0430\u043d\u043d\u043e\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043b\u0438\u0448\u044c \u0432 \u0442\u043e\u0442 \u043c\u043e\u043c\u0435\u043d\u0442, \u043a\u043e\u0433\u0434\u0430 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432 \u0441\u0442\u0430\u0442\u0443\u0441\u043d\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443, \u043d\u043e \u043d\u0435 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442, \u043a\u043e\u0433\u0434\u0430 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435 \u0443\u0434\u0430\u043b\u044f\u0435\u0442\u0441\u044f. \u0427\u0442\u0435\u043d\u0438\u0435 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u043e \u043f\u0440\u0438\u0448\u0435\u0434\u0448\u0435\u043c \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0438 \u0438 \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u0435 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0430\u0438\u0431\u043e\u043b\u044c\u0448\u0438\u043c\u0438 \u043a\u043e\u0441\u0442\u044b\u043b\u044f\u043c\u0438 \u0432 \u0440\u0435\u0448\u0435\u043d\u0438\u0438 \u044d\u0442\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438.<\/p>\n<h1>\u041e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u0435 \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0439 \u0441 \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u0435 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438<\/h1>\n<p>  \u0418\u0442\u0430\u043a, \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435 \u043f\u0440\u0438\u0448\u043b\u043e, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u0435 <a href=\"http:\/\/developer.android.com\/reference\/android\/view\/accessibility\/AccessibilityEvent.html#TYPE_NOTIFICATION_STATE_CHANGED\">TYPE_NOTIFICATION_STATE_CHANGED<\/a>. \u041c\u044b \u043c\u043e\u0436\u0435\u043c \u0443\u0437\u043d\u0430\u0442\u044c package name \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043f\u043e\u0441\u043b\u0430\u043b\u043e \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043c\u0435\u0442\u043e\u0434 <a href=\"http:\/\/developer.android.com\/reference\/android\/view\/accessibility\/AccessibilityEvent.html#getPackageName()\">AccessibilityEvent.getPackageName()<\/a>. \u0421\u0430\u043c\u043e \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435 \u043c\u043e\u0436\u043d\u043e \u0438\u0437\u0432\u043b\u0435\u0447\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043c\u0435\u0442\u043e\u0434 <a href=\"http:\/\/developer.android.com\/reference\/android\/view\/accessibility\/AccessibilityRecord.html#getParcelableData()\">AccessibilityRecord.getParcelableData()<\/a>, \u043d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u043e\u0431\u044a\u0435\u043a\u0442 \u0442\u0438\u043f\u0430 <a href=\"http:\/\/developer.android.com\/reference\/android\/app\/Notification.html\">Notification<\/a>. \u041d\u043e, \u043a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u043d\u0430\u0431\u043e\u0440 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u043d\u043e\u043c \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0438 \u0432\u0435\u0441\u044c\u043c\u0430 \u0441\u043a\u0443\u0434\u0435\u043d. \u0414\u043b\u044f \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0433\u043e \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f \u043d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0434\u043e\u0441\u0442\u0430\u0442\u044c \u0445\u043e\u0442\u044f \u0431\u044b \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c reflection \u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u043a\u043e\u0441\u0442\u044b\u043b\u0438.<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041a\u043e\u0434<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">public CharSequence getNotificationTitle(Notification notification, String packageName) {     CharSequence title = null;     title = getExpandedTitle(notification);     if (title == null) {         Bundle extras = NotificationCompat.getExtras(notification);         if (extras != null) {             Timber.d(&quot;getNotificationTitle: has extras: %1$s&quot;, extras.toString());             title = extras.getCharSequence(&quot;android.title&quot;);             Timber.d(&quot;getNotificationTitle: notification has no title, trying to get from bundle. found: %1$s&quot;, title);         }     }     if (title == null) {         \/\/ if title was not found, use package name as title         title = packageName;     }     Timber.d(&quot;getNotificationTitle: discovered title %1$s&quot;, title);     return title; }  private CharSequence getExpandedTitle(Notification n) {     CharSequence title = null;      RemoteViews view = n.contentView;      \/\/ first get information from the original content view     title = extractTitleFromView(view);      \/\/ then try get information from the expanded view     if (Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.JELLY_BEAN) {         view = getBigContentView(n);         title = extractTitleFromView(view);     }     Timber.d(&quot;getExpandedTitle: discovered title %1$s&quot;, title);     return title; }  private CharSequence extractTitleFromView(RemoteViews view) {     CharSequence title = null;      HashMap&lt;Integer, CharSequence&gt; notificationStrings = getNotificationStringFromRemoteViews(view);      if (notificationStrings.size() &gt; 0) {          \/\/ get title string if available         if (notificationStrings.containsKey(mNotificationTitleId)) {             title = notificationStrings.get(mNotificationTitleId);         } else if (notificationStrings.containsKey(mBigNotificationTitleId)) {             title = notificationStrings.get(mBigNotificationTitleId);         } else if (notificationStrings.containsKey(mInboxNotificationTitleId)) {             title = notificationStrings.get(mInboxNotificationTitleId);         }     }      return title; }  \/\/ use reflection to extract string from remoteviews object private HashMap&lt;Integer, CharSequence&gt; getNotificationStringFromRemoteViews(RemoteViews view) {     HashMap&lt;Integer, CharSequence&gt; notificationText = new HashMap&lt;&gt;();      try {         ArrayList&lt;Parcelable&gt; actions = null;         Field fs = RemoteViews.class.getDeclaredField(&quot;mActions&quot;);         if (fs != null) {             fs.setAccessible(true);             \/\/noinspection unchecked             actions = (ArrayList&lt;Parcelable&gt;) fs.get(view);         }         if (actions != null) {             \/\/ Find the setText() and setTime() reflection actions             for (Parcelable p : actions) {                 Parcel parcel = Parcel.obtain();                 p.writeToParcel(parcel, 0);                 parcel.setDataPosition(0);                  \/\/ The tag tells which type of action it is (2 is ReflectionAction, from the source)                 int tag = parcel.readInt();                 if (tag != 2) continue;                  \/\/ View ID                 int viewId = parcel.readInt();                  String methodName = parcel.readString();                 \/\/noinspection ConstantConditions                 if (methodName == null) continue;                      \/\/ Save strings                 else if (methodName.equals(&quot;setText&quot;)) {                     \/\/ Parameter type (10 = Character Sequence)                     int i = parcel.readInt();                      \/\/ Store the actual string                     try {                         CharSequence t = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);                         notificationText.put(viewId, t);                     } catch (Exception exp) {                         Timber.d(&quot;getNotificationStringFromRemoteViews: Can't get the text for setText with viewid:&quot; + viewId + &quot; parameter type:&quot; + i + &quot; reason:&quot; + exp.getMessage());                     }                 }                  parcel.recycle();             }         }     } catch (Exception exp) {         Timber.e(exp, null);     }      return notificationText; } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0412 \u0432\u044b\u0448\u0435\u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u043e\u043c \u043a\u043e\u0434\u0435 \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u044e\u0442\u0441\u044f \u0432\u0441\u0435 \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0438 View Ids, \u043e\u0442\u043d\u043e\u0441\u044f\u0449\u0438\u0435\u0441\u044f \u043a \u043e\u0431\u044a\u0435\u043a\u0442\u0443 \u0442\u0438\u043f\u0430 <a href=\"http:\/\/developer.android.com\/reference\/android\/app\/Notification.html\">Notification<\/a>. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f Reflection \u0438 \u0447\u0442\u0435\u043d\u0438\u0435 \u0438\u0437 <a href=\"http:\/\/developer.android.com\/reference\/android\/os\/Parcelable.html\">Parcelable<\/a> \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432. \u041d\u043e \u043c\u044b \u043d\u0435 \u0437\u043d\u0430\u0435\u043c, \u043a\u0430\u043a\u043e\u0435 View Id \u0438\u043c\u0435\u0435\u0442 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f. \u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u044d\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434:<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041a\u043e\u0434<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">\/*  * Data constants used to parse notification view ids  *\/ public static final String NOTIFICATION_TITLE_DATA = &quot;1&quot;; public static final String BIG_NOTIFICATION_TITLE_DATA = &quot;8&quot;; public static final String INBOX_NOTIFICATION_TITLE_DATA = &quot;9&quot;; \/**  * The id of the notification title view. Initialized in the {@link #detectNotificationIds()} method  *\/ public int mNotificationTitleId = 0; \/**  * The id of the big notification title view. Initialized in the {@link #detectNotificationIds()} method  *\/ public int mBigNotificationTitleId = 0; \/**  * The id of the inbox notification title view. Initialized in the {@link #detectNotificationIds()} method  *\/ public int mInboxNotificationTitleId = 0; \/**  * Detect required view ids which are used to parse notification information  *\/ private void detectNotificationIds() {     Timber.d(&quot;detectNotificationIds&quot;);     NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(mContext)             .setContentTitle(NOTIFICATION_TITLE_DATA);      Notification n = mBuilder.build();      LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);     ViewGroup localView;      \/\/ detect id's from normal view     localView = (ViewGroup) inflater.inflate(n.contentView.getLayoutId(), null);     n.contentView.reapply(mContext, localView);     recursiveDetectNotificationsIds(localView);      \/\/ detect id's from expanded views     if (Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.JELLY_BEAN) {         NotificationCompat.BigTextStyle bigtextstyle = new NotificationCompat.BigTextStyle();         mBuilder.setContentTitle(BIG_NOTIFICATION_TITLE_DATA);         mBuilder.setStyle(bigtextstyle);         n = mBuilder.build();         detectExpandedNotificationsIds(n);          NotificationCompat.InboxStyle inboxStyle =                 new NotificationCompat.InboxStyle();         mBuilder.setContentTitle(INBOX_NOTIFICATION_TITLE_DATA);          mBuilder.setStyle(inboxStyle);         n = mBuilder.build();         detectExpandedNotificationsIds(n);     } }  @TargetApi(Build.VERSION_CODES.JELLY_BEAN) private void detectExpandedNotificationsIds(Notification n) {     LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);     ViewGroup localView = (ViewGroup) inflater.inflate(n.bigContentView.getLayoutId(), null);     n.bigContentView.reapply(mContext, localView);     recursiveDetectNotificationsIds(localView); }  private void recursiveDetectNotificationsIds(ViewGroup v) {     for (int i = 0; i &lt; v.getChildCount(); i++) {         View child = v.getChildAt(i);         if (child instanceof ViewGroup)             recursiveDetectNotificationsIds((ViewGroup) child);         else if (child instanceof TextView) {             String text = ((TextView) child).getText().toString();             int id = child.getId();             switch (text) {                 case NOTIFICATION_TITLE_DATA:                     mNotificationTitleId = id;                     break;                 case BIG_NOTIFICATION_TITLE_DATA:                     mBigNotificationTitleId = id;                     break;                 case INBOX_NOTIFICATION_TITLE_DATA:                     mInboxNotificationTitleId = id;                     break;             }         }     } } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u041b\u043e\u0433\u0438\u043a\u0430 \u0432\u044b\u0448\u0435\u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0435 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435 \u0441 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u043c \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c \u0434\u043b\u044f \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430. \u0421\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f View \u0434\u043b\u044f \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 <a href=\"http:\/\/developer.android.com\/reference\/android\/view\/LayoutInflater.html\">LayoutInflater<\/a> \u0438 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u044b\u043c \u043f\u043e\u0438\u0441\u043a\u043e\u043c \u0438\u0449\u0435\u0442\u0441\u044f \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0439 TextView \u0441 \u0440\u0430\u043d\u0435\u0435 \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u043c \u0442\u0435\u043a\u0441\u0442\u043e\u043c. Id \u043d\u0430\u0439\u0434\u0435\u043d\u043d\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0438 \u0431\u0443\u0434\u0435\u0442 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u043c \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u043c \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430 \u0432\u0441\u0435\u0445 \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0439.<\/p>\n<p>  \u041f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u0431\u044b\u043b \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d, \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u043f\u0430\u0440\u0443 package, title \u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043f\u0438\u0441\u043a\u0435 \u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0439 \u0434\u043b\u044f \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0438\u0445 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a.<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041a\u043e\u0434<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">\/**  * List to store currently active notifications data  *\/ ConcurrentLinkedQueue&lt;NotificationData&gt; mAvailableNotifications = new ConcurrentLinkedQueue&lt;&gt;();  @Override public void onAccessibilityEvent(AccessibilityEvent accessibilityEvent) {     switch (accessibilityEvent.getEventType()) {         case AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED:             Timber.d(&quot;onAccessibilityEvent: notification state changed&quot;);             if (accessibilityEvent.getParcelableData() != null &&                     accessibilityEvent.getParcelableData() instanceof Notification) {                 Notification n = (Notification) accessibilityEvent.getParcelableData();                 String packageName = accessibilityEvent.getPackageName().toString();                 Timber.d(&quot;onAccessibilityEvent: notification posted package: %1$s; notification: %2$s&quot;, packageName, n);                 mAvailableNotifications.add(new NotificationData(mNotificationParser.getNotificationTitle(n, packageName), packageName));                 \/\/ fire event                 onNotificationPosted();             }             break; ...     } }  \/**  * Simple notification information holder  *\/ class NotificationData {     CharSequence title;     CharSequence packageName;      public NotificationData(CharSequence title, CharSequence packageName) {         this.title = title;         this.packageName = packageName;     } } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0421 \u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u044c\u044e, \u0432\u0440\u043e\u0434\u0435 \u043a\u0430\u043a, \u0441\u043f\u0440\u0430\u0432\u0438\u043b\u0438\u0441\u044c. \u0422\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0431\u043e\u043b\u0435\u0435 \u043c\u0435\u043d\u0435\u0435 \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u043e \u043d\u0430 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0432\u0435\u0440\u0441\u0438\u044f Android. \u041f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043a\u043e \u0432\u0442\u043e\u0440\u043e\u0439 \u0447\u0430\u0441\u0442\u0438, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043f\u044b\u0442\u0430\u0442\u044c\u0441\u044f \u043e\u0442\u0441\u043b\u0435\u0434\u0438\u0442\u044c \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0439.<\/p>\n<h1>\u041e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u0435 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0439<\/h1>\n<p>  \u041f\u043e \u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u043c \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c \u0443\u0437\u043d\u0430\u0442\u044c, \u043a\u043e\u0433\u0434\u0430 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435 \u0431\u044b\u043b\u043e \u0443\u0434\u0430\u043b\u0435\u043d\u043e \u043d\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u043c, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u0442\u0432\u0435\u0442\u0438\u0442\u044c \u043d\u0430 \u0432\u043e\u043f\u0440\u043e\u0441: \u0432 \u043a\u0430\u043a\u0438\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445 \u043e\u043d\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0443\u0434\u0430\u043b\u0435\u043d\u043e? \u041d\u0430 \u0443\u043c \u043f\u0440\u0438\u0445\u043e\u0434\u044f\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b:<\/p>\n<ol>\n<li>\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441\u043c\u0430\u0445\u043d\u0443\u043b \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435<\/li>\n<li>\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043e\u0442\u043a\u0440\u044b\u043b \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043f\u043e \u043a\u043b\u0438\u043a\u0443 \u043d\u0430 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0438 \u0438 \u043e\u043d\u043e \u0438\u0441\u0447\u0435\u0437\u043b\u043e.<\/li>\n<li>\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0430\u0436\u0430\u043b \u043a\u043d\u043e\u043f\u043a\u0443 \u043e\u0447\u0438\u0441\u0442\u0438\u0442\u044c \u0432\u0441\u0435 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f. <\/li>\n<li>\u041f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0441\u0430\u043c\u043e \u0443\u0434\u0430\u043b\u0438\u043b\u043e \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435. <\/li>\n<\/ol>\n<p>  \u0421\u0440\u0430\u0437\u0443 \u0432\u044b\u043d\u0443\u0436\u0434\u0435\u043d \u043f\u0440\u0438\u0437\u043d\u0430\u0442\u044c, \u0447\u0442\u043e \u0441 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u043c \u043f\u0443\u043d\u043a\u0442\u043e\u043c \u043d\u0438\u0447\u0435\u0433\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u043e\u043a\u0430 \u043d\u0435 \u0441\u043c\u043e\u0433, \u043d\u043e \u0435\u0441\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u0434\u0430, \u0447\u0442\u043e \u0442\u0430\u043a\u043e\u0435 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u043d\u0435 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0447\u0430\u0441\u0442\u043e\u0435, \u0438 \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0435 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0432\u043e\u0441\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u043d\u043e\u0435.<\/p>\n<p>  \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043a\u0430\u0436\u0434\u044b\u0439 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0439 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438.<\/p>\n<h2>\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441\u043c\u0430\u0445\u043d\u0443\u043b \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435<\/h2>\n<p>  \u041e\u0442\u0441\u043b\u0435\u0434\u0438\u0432, \u043a\u0430\u043a\u0438\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u044f\u0442, \u043a\u043e\u0433\u0434\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441\u043c\u0430\u0445\u0438\u0432\u0430\u0435\u0442 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f, \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u043b, \u0447\u0442\u043e \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u0442\u0438\u043f\u0430 <a href=\"http:\/\/developer.android.com\/reference\/android\/view\/accessibility\/AccessibilityEvent.html#TYPE_WINDOW_CONTENT_CHANGED\">TYPE_WINDOW_CONTENT_CHANGED<\/a> \u0434\u043b\u044f package name <b>\u00abandroid.system.ui\u00bb<\/b> \u0441 <b>windowId<\/b> \u043f\u0440\u0438\u043d\u0430\u0434\u043b\u0435\u0436\u0430\u0449\u0435\u043c\u0443 \u0441\u0442\u0430\u0442\u0443\u0441\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0435. \u041a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u043e\u043a\u043d\u043e \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043c\u0435\u0436\u0434\u0443 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u043c\u0438 \u0442\u043e\u0436\u0435 \u0438\u043c\u0435\u0435\u0442 package name <b>\u00abandroid.system.ui\u00bb<\/b> \u043d\u043e \u0434\u0440\u0443\u0433\u043e\u0439 <b>windowId<\/b>. WindowId \u044d\u0442\u043e \u043d\u0435 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0430, \u0438 \u043c\u043e\u0436\u0435\u0442 \u043c\u0435\u043d\u044f\u0442\u044c\u0441\u044f \u043f\u043e\u0441\u043b\u0435 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u0438\u043b\u0438 \u043d\u0430 \u0440\u0430\u0437\u043d\u044b\u0445 \u0432\u0435\u0440\u0441\u0438\u044f\u0445 Android. <\/p>\n<p>  \u041a\u0430\u043a \u0436\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u044c, \u0447\u0442\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u043f\u0440\u0438\u0448\u043b\u043e \u0438\u043c\u0435\u043d\u043d\u043e \u0438\u0437 \u0441\u0442\u0430\u0442\u0443\u0441\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438? \u041c\u043d\u0435 \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0438\u0437\u0440\u044f\u0434\u043d\u043e \u043f\u043e\u043b\u043e\u043c\u0430\u0442\u044c \u0433\u043e\u043b\u043e\u0432\u0443 \u043d\u0430\u0434 \u044d\u0442\u0438\u043c \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u043c. \u0412 \u043a\u043e\u043d\u0446\u0435 \u043a\u043e\u043d\u0446\u043e\u0432, \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0439 \u043a\u043e\u0441\u0442\u044b\u043b\u044c \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e. \u041f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043b, \u0447\u0442\u043e \u0441\u0442\u0430\u0442\u0443\u0441\u043d\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442\u0430 \u0432 \u043c\u043e\u043c\u0435\u043d\u0442 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c. \u041d\u0430 \u043d\u0435\u0439 \u0434\u043e\u043b\u0436\u043d\u0430 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u043a\u043d\u043e\u043f\u043a\u0430 \u043e\u0447\u0438\u0441\u0442\u0438\u0442\u044c \u0432\u0441\u0435 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f \u0441 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u043c accessibility description. \u041a \u0441\u0447\u0430\u0441\u0442\u044c\u044e, \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0430 \u0438\u043c\u0435\u0435\u0442 \u043e\u0434\u043d\u043e \u0438 \u0442\u043e \u0436\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043d\u0430 \u0440\u0430\u0437\u043d\u044b\u0445 \u0432\u0435\u0440\u0441\u0438\u044f\u0445 Android. \u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u0440\u043e\u0430\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u044e \u0432\u0438\u0434\u0430 \u043d\u0430 \u043f\u0440\u0435\u0434\u043c\u0435\u0442 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u044f \u0434\u0430\u043d\u043d\u043e\u0439 \u043a\u043d\u043e\u043f\u043a\u0438, \u0438 \u0442\u043e\u0433\u0434\u0430 \u043c\u044b \u0441\u043c\u043e\u0436\u0435\u043c \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u0442\u044c windowId \u043f\u0440\u0438\u043d\u0430\u0434\u043b\u0435\u0436\u0430\u0449\u0438\u0439 \u0441\u0442\u0430\u0442\u0443\u0441\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0435. \u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u043a\u0442\u043e-\u043d\u0438\u0431\u0443\u0434\u044c \u0438\u0437 \u0445\u0430\u0431\u0440\u0430\u0436\u0438\u0442\u0435\u043b\u0435\u0439 \u0437\u043d\u0430\u0435\u0442 \u0431\u043e\u043b\u0435\u0435 \u0434\u043e\u0441\u0442\u043e\u0432\u0435\u0440\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e, \u0431\u0443\u0434\u0443 \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u0435\u043d, \u0435\u0441\u043b\u0438 \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u0435\u0441\u044c \u0437\u043d\u0430\u043d\u0438\u044f\u043c\u0438.<\/p>\n<p>  \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c, \u043f\u0440\u0438\u043d\u0430\u0434\u043b\u0435\u0436\u0438\u0442 \u043b\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u0441\u0442\u0430\u0442\u0443\u0441\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0435:<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041a\u043e\u0434<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">\/**  * Find &quot;clear all notifications&quot; button accessibility text used by the systemui application  *\/ private void findClearAllButton() {     Timber.d(&quot;findClearAllButton: called&quot;);     Resources res;     try {         res = mPackageManager.getResourcesForApplication(SYSTEMUI_PACKAGE_NAME);         int i = res.getIdentifier(&quot;accessibility_clear_all&quot;, &quot;string&quot;, &quot;com.android.systemui&quot;);         if (i != 0) {             mClearButtonName = res.getString(i);         }     } catch (Exception exp) {         Timber.e(exp, null);     } }  \/**  * Check whether accessibility event belongs to the status bar window by checking event package  * name and window id  *  * @param accessibilityEvent  * @return  *\/ public boolean isStatusBarWindowEvent(AccessibilityEvent accessibilityEvent) {     boolean result = false;     if (!SYSTEMUI_PACKAGE_NAME.equals(accessibilityEvent.getPackageName())) {         Timber.v(&quot;isStatusBarWindowEvent: not system ui package&quot;);     } else if (mStatusBarWindowId != -1) {         \/\/ if status bar window id is already initialized         result = accessibilityEvent.getWindowId() == mStatusBarWindowId;         Timber.v(&quot;isStatusBarWindowEvent: comparing window ids %1$d %2$d, result %3$b&quot;, mStatusBarWindowId, accessibilityEvent.getWindowId(), result);     } else {         Timber.v(&quot;isStatusBarWindowEvent: status bar window id not initialized, starting detection&quot;);         AccessibilityNodeInfo node = accessibilityEvent.getSource();         node = getRootNode(node);          if (hasClearButton(node)) {             Timber.v(&quot;isStatusBarWindowEvent: the root node has clear text button in the view hierarchy. Remember window id for future use&quot;);             mStatusBarWindowId = accessibilityEvent.getWindowId();             result = isStatusBarWindowEvent(accessibilityEvent);         }         if (!result) {             Timber.v(&quot;isStatusBarWindowEvent: can't initizlie status bar window id&quot;);         }     }     return result; }  \/**  * Get the root node for the specified node if it is not null  *  * @param node  * @return the root node for the specified node in the view hierarchy  *\/ public AccessibilityNodeInfo getRootNode(AccessibilityNodeInfo node) {     if (node != null) {         \/\/ workaround for Android 4.0.3 to avoid NPE. Should to remember first call of the node.getParent() such         \/\/ as second call may return null         AccessibilityNodeInfo parent;         while ((parent = node.getParent()) != null) {             node = parent;         }     }     return node; }  \/**  * Check whether the node has clear notifications button in the view hierarchy  *  * @param node  * @return  *\/ private boolean hasClearButton(AccessibilityNodeInfo node) {     boolean result = false;     if (node == null) {         return result;     }     Timber.d(&quot;hasClearButton: %1$s %2$d %3$s&quot;, node.getClassName(), node.getWindowId(), node.getContentDescription());     if (TextUtils.equals(mClearButtonName, node.getContentDescription())) {         result = true;     } else {         for (int i = 0; i &lt; node.getChildCount(); i++) {             if (hasClearButton(node.getChild(i))) {                 result = true;                 break;             }         }     }     return result; } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c, \u0431\u044b\u043b\u043e \u043b\u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u043e \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435 \u0438\u043b\u0438 \u0432\u0441\u0435 \u0435\u0449\u0435 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0441\u043f\u043e\u0441\u043e\u0431, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0435 \u043e\u0431\u043b\u0430\u0434\u0430\u0435\u0442 100% \u043d\u0430\u0434\u0435\u0436\u043d\u043e\u0441\u0442\u044c\u044e: \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u043c \u0432\u0441\u0435 \u0441\u0442\u0440\u043e\u043a\u0438 \u0438\u0437 \u0441\u0442\u0430\u0442\u0443\u0441\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438 \u0438 \u0438\u0449\u0435\u043c \u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u044f \u0441 \u0440\u0430\u043d\u0435\u0435 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u043d\u044b\u043c\u0438 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430\u043c\u0438 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0439. \u0415\u0441\u043b\u0438 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442, \u0441\u0447\u0438\u0442\u0430\u0435\u043c, \u0447\u0442\u043e \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435 \u0431\u044b\u043b\u043e \u0443\u0434\u0430\u043b\u0435\u043d\u043e. \u0411\u044b\u0432\u0430\u0435\u0442, \u0447\u0442\u043e \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u0441 \u043d\u0443\u0436\u043d\u044b\u043c <b>windowId<\/b> \u043d\u043e \u0441 \u043f\u0443\u0441\u0442\u044b\u043c <a href=\"http:\/\/developer.android.com\/reference\/android\/view\/accessibility\/AccessibilityNodeInfo.html\">AccessibilityNodeInfo<\/a> (\u0441\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f, \u043a\u043e\u0433\u0434\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441\u043c\u0430\u0445\u0438\u0432\u0430\u0435\u0442 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0435 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435). \u0412 \u0442\u0430\u043a\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0441\u0447\u0438\u0442\u0430\u0435\u043c, \u0447\u0442\u043e \u0432\u0441\u0435 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f \u0431\u044b\u043b\u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u044b.<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041a\u043e\u0434<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">\/**  * Update the available notification information from the node information of the accessibility event  * &lt;br&gt;  * The algorithm is not exact. All the strings are recursively retrieved in the view hierarchy and then  * titles are compared with the available notifications  *  * @param accessibilityEvent  *\/ private void updateNotifications(AccessibilityEvent accessibilityEvent) {     AccessibilityNodeInfo node = accessibilityEvent.getSource();     node = mStatusBarWindowUtils.getRootNode(node);     boolean removed = false;     Set&lt;String&gt; titles = node == null ? Collections.emptySet() : recursiveGetStrings(node);     for (Iterator&lt;NotificationData&gt; iter = mAvailableNotifications.iterator(); iter.hasNext(); ) {         NotificationData data = iter.next();         if (!titles.contains(data.title.toString())) {             \/\/ if the title is absent in the view hierarchy remove notification from available notifications             iter.remove();             removed = true;         }     }     if (removed) {         Timber.d(&quot;updateNotifications: removed&quot;);         \/\/ fire event if at least one notification was removed         onNotificationRemoved();     } }  \/**  * Get all the text information from the node view hierarchy  *  * @param node  * @return  *\/ private Set&lt;String&gt; recursiveGetStrings(AccessibilityNodeInfo node) {     Set&lt;String&gt; strings = new HashSet&lt;&gt;();     if (node != null) {         if (node.getText() != null) {             strings.add(node.getText().toString());             Timber.d(&quot;recursiveGetStrings: %1$s&quot;, node.getText().toString());         }         for (int i = 0; i &lt; node.getChildCount(); i++) {             strings.addAll(recursiveGetStrings(node.getChild(i)));         }     }     return strings; } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041a\u043e\u0434 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u044f<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">case AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED:     \/\/ auto clear notifications when cleared from notifications bar (old api, Android &lt; 4.3)     if (mStatusBarWindowUtils.isStatusBarWindowEvent(accessibilityEvent)) {         Timber.d(&quot;onAccessibilityEvent: status bar content changed&quot;);         updateNotifications(accessibilityEvent);     }     break; <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<h2>\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043e\u0442\u043a\u0440\u044b\u043b \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043f\u043e \u043a\u043b\u0438\u043a\u0443 \u043d\u0430 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0438 \u0438 \u043e\u043d\u043e \u0438\u0441\u0447\u0435\u0437\u043b\u043e<\/h2>\n<p>  \u0411\u044b\u043b\u043e \u0431\u044b \u0438\u0434\u0435\u0430\u043b\u044c\u043d\u043e, \u0435\u0441\u043b\u0438 \u0431\u044b \u0434\u0430\u043d\u043d\u043e\u0435 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043b\u043e, \u043a\u0430\u043a \u0438 \u0432 \u043f\u0435\u0440\u0432\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u0441\u043e\u0431\u044b\u0442\u0438\u0435 <a href=\"http:\/\/developer.android.com\/reference\/android\/view\/accessibility\/AccessibilityEvent.html#TYPE_WINDOW_CONTENT_CHANGED\">TYPE_WINDOW_CONTENT_CHANGED<\/a> \u0434\u043b\u044f package name <b>\u00abandroid.system.ui\u00bb<\/b>, \u043d\u0435 \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0431\u044b \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u044d\u0442\u043e\u0442 \u0441\u043b\u0443\u0447\u0430\u0439 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e. \u041d\u043e \u0442\u0435\u0441\u0442\u044b \u043f\u043e\u043a\u0430\u0437\u0430\u043b\u0438, \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f, \u043d\u043e \u043d\u0435 \u0432\u0441\u0435\u0433\u0434\u0430: \u044d\u0442\u043e \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u0432\u0435\u0440\u0441\u0438\u0438 Android, \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0437\u0430\u043a\u0440\u044b\u0442\u0438\u044f \u0441\u0442\u0430\u0442\u0443\u0441\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438 \u0438 \u0435\u0449\u0435 \u043d\u0435\u043f\u043e\u043d\u044f\u0442\u043d\u043e \u043e\u0442 \u0447\u0435\u0433\u043e. \u0412 \u0441\u0432\u043e\u0435\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u043c\u043d\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0431\u044b\u043b\u043e \u043f\u0435\u0440\u0435\u0441\u0442\u0430\u0442\u044c \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u044f\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043e \u043f\u0440\u043e\u043f\u0443\u0449\u0435\u043d\u043d\u043e\u043c \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0438. \u0411\u044b\u043b\u043e \u0440\u0435\u0448\u0435\u043d\u043e \u043f\u043e\u0434\u0441\u0442\u0440\u0430\u0445\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0438 \u0441\u0447\u0438\u0442\u0430\u0442\u044c, \u0447\u0442\u043e \u0440\u0430\u0437 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043e\u0442\u043a\u0440\u044b\u043b \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u0443 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0438\u043c\u0435\u044e\u0442\u0441\u044f \u043f\u0440\u043e\u043f\u0443\u0449\u0435\u043d\u043d\u044b\u0435 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f, \u043c\u043e\u0436\u043d\u043e \u0441\u0447\u0438\u0442\u0430\u0442\u044c, \u0447\u0442\u043e \u0440\u0430\u043d\u0435\u0435 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u043d\u044b\u0435 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u043d\u0435\u0433\u043e \u043d\u0435 \u0432\u0430\u0436\u043d\u044b \u0438 \u043c\u043e\u0433\u0443\u0442 \u043e \u0441\u0435\u0431\u0435 \u043d\u0435 \u043d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u0442\u044c. <\/p>\n<p>  \u041a\u043e\u0433\u0434\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f, \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u0435 <a href=\"http:\/\/developer.android.com\/reference\/android\/view\/accessibility\/AccessibilityEvent.html#TYPE_WINDOW_STATE_CHANGED\">TYPE_WINDOW_STATE_CHANGED<\/a>, \u043e\u0442\u043a\u0443\u0434\u0430 \u043c\u043e\u0436\u043d\u043e \u0443\u0437\u043d\u0430\u0442\u044c packageName \u0438 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0432\u0441\u0435 \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0435\u043c\u044b\u0435 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u043d\u0435\u0433\u043e.<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041a\u043e\u0434<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">\/**  * Remove all notifications from the available notifications with the specified package name  *  * @param packageName  *\/ private void removeNotificationsFor(String packageName) {     boolean removed = false;     Timber.d(&quot;removeNotificationsFor: %1$s&quot;, packageName);     for (Iterator&lt;NotificationData&gt; iter = mAvailableNotifications.iterator(); iter.hasNext(); ) {         NotificationData data = iter.next();         if (TextUtils.equals(packageName, data.packageName)) {             iter.remove();             removed = true;         }     }     if (removed) {         Timber.d(&quot;removeNotificationsFor: removed for %1$s&quot;, packageName);         onNotificationRemoved();     } } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041a\u043e\u0434 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u044f<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:     \/\/ auto clear notifications for launched application (TYPE_WINDOW_CONTENT_CHANGED not always generated     \/\/ when app is clicked or cleared)     Timber.d(&quot;onAccessibilityEvent: window state changed&quot;);     if (accessibilityEvent.getPackageName() != null) {         String packageName = accessibilityEvent.getPackageName().toString();         Timber.d(&quot;onAccessibilityEvent: window state has been changed for package %1$s&quot;, packageName);         removeNotificationsFor(packageName);     }     break; <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<h2>\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0430\u0436\u0430\u043b \u043a\u043d\u043e\u043f\u043a\u0443 \u043e\u0447\u0438\u0441\u0442\u0438\u0442\u044c \u0432\u0441\u0435 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f<\/h2>\n<p>  \u0422\u0443\u0442, \u043a\u0430\u043a \u0438 \u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u0441\u043e\u0431\u044b\u0442\u0438\u0435 <a href=\"http:\/\/developer.android.com\/reference\/android\/view\/accessibility\/AccessibilityEvent.html#TYPE_WINDOW_CONTENT_CHANGED\">TYPE_WINDOW_CONTENT_CHANGED<\/a> \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043d\u0435 \u0432\u0441\u0435\u0433\u0434\u0430. \u041f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c, \u0447\u0442\u043e \u0440\u0430\u0437 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0430\u0436\u0430\u043b \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443, \u0442\u043e \u0440\u0430\u043d\u0435\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0435 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u0432\u0430\u0436\u043d\u044b \u0438 \u043f\u0435\u0440\u0435\u0441\u0442\u0430\u0442\u044c \u043e \u043d\u0438\u0445 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u044f\u0442\u044c. <\/p>\n<p>  \u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u0442\u0441\u043b\u0435\u0434\u0438\u0442\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u0435 <a href=\"http:\/\/developer.android.com\/reference\/android\/view\/accessibility\/AccessibilityEvent.html#TYPE_VIEW_CLICKED\">TYPE_VIEW_CLICKED <\/a> \u0432 \u0441\u0442\u0430\u0442\u0443\u0441\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0435 \u0438 \u0435\u0441\u043b\u0438 \u043e\u043d\u043e \u043f\u0440\u0438\u043d\u0430\u0434\u043b\u0435\u0436\u0438\u0442 \u043a\u043d\u043e\u043f\u043a\u0435 \u00ab\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u044c \u0432\u0441\u0435\u00bb, \u043f\u0435\u0440\u0435\u0441\u0442\u0430\u0442\u044c \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f.<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041a\u043e\u0434<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">\/**  * Check whether the accessibility event is generated by the clear all notifications button  *  * @param accessibilityEvent  * @return  *\/ public boolean isClearNotificationsButtonEvent(AccessibilityEvent accessibilityEvent) {     return TextUtils.equals(accessibilityEvent.getClassName(), android.widget.ImageView.class.getName())             && TextUtils.equals(accessibilityEvent.getContentDescription(), mClearButtonName); } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041a\u043e\u0434 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u044f<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">case AccessibilityEvent.TYPE_VIEW_CLICKED:     \/\/ auto clear notifications when clear all notifications button clicked (TYPE_WINDOW_CONTENT_CHANGED not always generated     \/\/ when this event occurs so need to handle this manually     \/\/     \/\/ also handle notification clicked event     Timber.d(&quot;onAccessibilityEvent: view clicked&quot;);     if (mStatusBarWindowUtils.isStatusBarWindowEvent(accessibilityEvent)) {         Timber.d(&quot;onAccessibilityEvent: status bar content clicked&quot;);         if (mStatusBarWindowUtils.isClearNotificationsButtonEvent(accessibilityEvent)) {             \/\/ if clicked image view element with the clear button name content description             Timber.d(&quot;onAccessibilityEvent: clear notifications button clicked&quot;);             mAvailableNotifications.clear();             \/\/ fire event             onNotificationRemoved();         } else {             \/\/ update notifications if another view is clicked             updateNotifications(accessibilityEvent);         }     }     break; <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<h2>\u0427\u0442\u043e \u0441 Android \u0434\u043e \u0432\u0435\u0440\u0441\u0438\u0438 4.0?<\/h2>\n<p>  \u041a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u043c\u043d\u0435 \u043f\u043e\u043a\u0430 \u043d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043d\u0430\u0439\u0442\u0438 \u0440\u0430\u0431\u043e\u0447\u0438\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u043e\u0442\u0441\u043b\u0435\u0434\u0438\u0442\u044c \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0439. \u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 ViewHierarchy \u0432 <a href=\"http:\/\/developer.android.com\/reference\/android\/accessibilityservice\/AccessibilityService.html\">AccessibilityService<\/a> \u0431\u044b\u043b\u0430 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430\u0447\u0438\u043d\u0430\u044f \u0441 API \u0432\u0435\u0440\u0441\u0438\u0438 14. \u0415\u0441\u043b\u0438 \u043a\u0442\u043e-\u043d\u0438\u0431\u0443\u0434\u044c \u0437\u043d\u0430\u0435\u0442 \u0441\u043f\u043e\u0441\u043e\u0431, \u043a\u0430\u043a \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a ViewHierarchy \u0441\u0442\u0430\u0442\u0443\u0441\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438 \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u044d\u0442\u0443 \u0437\u0430\u0434\u0430\u0447\u0443 \u0443\u0434\u0430\u0441\u0442\u0441\u044f \u0440\u0435\u0448\u0438\u0442\u044c<\/p>\n<h1>P.S.<\/h1>\n<p>  \u041d\u0430\u0434\u0435\u044e\u0441\u044c, \u043a\u043e\u043c\u0443-\u043d\u0438\u0431\u0443\u0434\u044c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u0430 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u043d\u0430\u044f \u0432 \u0441\u0442\u0430\u0442\u044c\u0435 \u0442\u0435\u043c\u0430. \u0411\u0443\u0434\u0443 \u0440\u0430\u0434 \u0443\u0441\u043b\u044b\u0448\u0430\u0442\u044c \u0432\u0430\u0448\u0438 \u0438\u0434\u0435\u0438 \u043f\u043e \u043f\u043e\u0432\u043e\u0434\u0443 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u0443\u043b\u0443\u0447\u0448\u0438\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0439. <\/p>\n<p>  \u0411\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u0447\u0435\u0440\u043f\u0430\u043b \u043e\u0442\u0441\u044e\u0434\u0430 <a href=\"https:\/\/github.com\/minhdangoz\/notifications-widget\">https:\/\/github.com\/minhdangoz\/notifications-widget<\/a> (\u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0434\u043e\u043f\u0438\u043b\u0438\u0442\u044c \u0432 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043c\u0435\u0441\u0442\u0430\u0445) <\/p>\n<p>  \u0413\u043e\u0442\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 <a href=\"https:\/\/github.com\/httpdispatch\/MissedNotificationsReminder\">https:\/\/github.com\/httpdispatch\/MissedNotificationsReminder<\/a> \u2014 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u044e\u0449\u0435\u0435 \u043e \u043f\u0440\u043e\u043f\u0443\u0449\u0435\u043d\u043d\u044b\u0445 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f\u0445. \u041d\u0435 \u0437\u0430\u0431\u0443\u0434\u044c\u0442\u0435 \u0432\u044b\u0431\u0440\u0430\u0442\u044c v14 build variant, \u0442.\u043a. v18 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0447\u0435\u0440\u0435\u0437 NotificationListenerService               <\/p>\n<div class=\"clear\"><\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"http:\/\/habrahabr.ru\/post\/271541\/\"> http:\/\/habrahabr.ru\/post\/271541\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>       <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/01f\/ff3\/997\/01fff3997752478b98e640942a845b82.jpg\" align=\"left\"\/> \u041d\u0430\u0447\u0438\u043d\u0430\u044f \u0441 \u0432\u0435\u0440\u0441\u0438\u0438 4.3 \u0432 Android OS \u0431\u044b\u043b\u0430 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f <a href=\"http:\/\/developer.android.com\/reference\/android\/service\/notification\/NotificationListenerService.html\">NotificationListenerService<\/a>. \u041a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u043e\u0431\u0440\u0430\u0442\u043d\u0430\u044f \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e\u0441\u0442\u044c \u0441 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u043c\u0438 \u0432\u0435\u0440\u0441\u0438\u044f\u043c\u0438 OS \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442. \u0427\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c, \u0435\u0441\u043b\u0438 \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c \u043d\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430\u0445 \u0441 \u0431\u043e\u043b\u0435\u0435 \u0441\u0442\u0430\u0440\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0435\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b?<\/p>\n<p>  \u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u043d\u0430\u0431\u043e\u0440 \u043a\u043e\u0441\u0442\u044b\u043b\u0435\u0439 \u0438 \u0445\u0430\u043a\u043e\u0432 \u0434\u043b\u044f \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0439 \u043d\u0430 Android OS \u0432\u0435\u0440\u0441\u0438\u0438 4.0-4.2. \u041d\u0435 \u043d\u0430 \u0432\u0441\u0435\u0445 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430\u0445 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 100% \u0440\u0430\u0431\u043e\u0442\u043e\u0441\u043f\u043e\u0441\u043e\u0431\u0435\u043d, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043a\u043e\u0441\u0442\u044b\u043b\u0438, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0439 \u0432 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445.  <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-268885","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/268885","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=268885"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/268885\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=268885"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=268885"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=268885"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}