【问题标题】:Read Notification Bar title, message using Accessibility Service Programmatically以编程方式使用辅助功能服务读取通知栏标题、消息
【发布时间】:2017-08-30 15:27:25
【问题描述】:

使用辅助功能服务我能够阅读通知栏标题和消息,我面临的问题是当第一个通知出现时我正在完美地阅读所有这些但在第一次通知之后我只得到标题和文本“你有2 条消息”等等,而不是整个消息。 等待您的专家建议。

代码:

@Override
    protected void onServiceConnected() 
    {
        Log.d("AccessibilityServiceNotification", "ServiceConnected");
    try
    {
        AccessibilityServiceInfo info = new AccessibilityServiceInfo();

        info.eventTypes = AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED;

        info.feedbackType = AccessibilityServiceInfo.FEEDBACK_ALL_MASK;

        info.notificationTimeout = 100;

        setServiceInfo(info);
    }
    catch(Exception e)
    {
        Log.d("ERROR onServiceConnected", e.toString());
    }
    }

    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) 
    {
        try 
        {
            LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);

            Parcelable data = event.getParcelableData();

            if(data !=null)
            {
                Notification notification = (Notification) data;

                RemoteViews remoteView = notification.bigContentView;

                ViewGroup localView = (ViewGroup) inflater.inflate(remoteView.getLayoutId(), null);

                remoteView.reapply(getApplicationContext(), localView);

                Resources resources = null;

                PackageManager pkm = getPackageManager();

                try 
                {
                    resources = pkm.getResourcesForApplication("com.user.package");
                }
                catch (NameNotFoundException e) 
                {
                    e.printStackTrace();
                }

                if (resources == null)
                    return; 

                int TITLE = resources.getIdentifier("android:id/title", null, null);

                int INBOX = resources.getIdentifier("android:id/big_text", null, null);

                int TEXT = resources.getIdentifier("android:id/text", null, null);

                String packagename = String.valueOf(event.getPackageName());

                title = (TextView) localView.findViewById(TITLE);

                inbox = (TextView) localView.findViewById(INBOX);

                text = (TextView) localView.findViewById(TEXT);

                Log.d("NOTIFICATION Package : ", packagename);

                Log.d("NOTIFICATION Title : ", title.getText().toString());

                Log.d("NOTIFICATION You have got x messages : ", text.getText().toString());

                Log.d("NOTIFICATION inbox : ", inbox.getText().toString());
        }
        }
        catch(Exception e)
        {
            Log.e("onAccessibilityEvent ERROR", e.toString());
        } 
    }

示例通知 1:

包:com.whatsapp, 标题:你好, 留言:你好吗

示例通知 2:

包:com.whatsapp, 标题:你好, 消息:你有 2 条消息(而不是:你在做什么)

【问题讨论】:

    标签: java android notifications accessibilityservice


    【解决方案1】:

    在通知中使用extras 字段相当简单。保存扩展文本行的键是EXTRA_TEXT_LINES。

    这对我有用:

    Notification notification = (Notification) event.getParcelableData();
    CharSequence[] lines = notification.extras.getCharSequenceArray(Notification.EXTRA_TEXT_LINES);
    int i = 0;
    for(CharSequence msg : lines)
    {
        Log.d("Line " + i, (String) msg);
        i += 1;
    }
    

    【讨论】:

      【解决方案2】:

      这段代码非常适合我:

      List<String> msgs = new ArrayList<String>();
      msgs.add("Info: " + notif.extras.getString(Notification.EXTRA_INFO_TEXT));
      msgs.add("Title: " + notif.extras.getString(Notification.EXTRA_TITLE));
      msgs.add("Text: " + notif.extras.getString(Notification.EXTRA_TEXT));
      

      我研究了几天来获得这个方法,我已经在 Android 4.4、5.5 和 6.0 上对其进行了测试。也可以使用方法

      if(event.getEventType() == AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED){  
        if(event.getPackageName().toString().equalsIgnoreCase("com.whatsapp")){
      Log.d("msg", event.getText().toString().replace("[", "]").replaceAll("]", ""), Logger.EXTRA_LOG);
       }
      }
      

      然后你可以得到所有的书面信息。 希望对您有所帮助。

      【讨论】:

        【解决方案3】:

        试试这个,下面的代码对我有用 -

        Notification notification = (Notification) event.getParcelableData();
        RemoteViews views = notification.contentView;
        Class secretClass = views.getClass();
        
        try {
            Map<Integer, String> text = new HashMap<Integer, String>();
        
            Field outerFields[] = secretClass.getDeclaredFields();
            for (int i = 0; i < outerFields.length; i++) {
                if (!outerFields[i].getName().equals("mActions")) continue;
        
                outerFields[i].setAccessible(true);
        
                ArrayList<Object> actions = (ArrayList<Object>) outerFields[i]
                        .get(views);
                for (Object action : actions) {
                    Field innerFields[] = action.getClass().getDeclaredFields();
        
                    Object value = null;
                    Integer type = null;
                    Integer viewId = null;
                    for (Field field : innerFields) {
                        field.setAccessible(true);
                        if (field.getName().equals("value")) {
                            value = field.get(action);
                        } else if (field.getName().equals("type")) {
                            type = field.getInt(action);
                        } else if (field.getName().equals("viewId")) {
                            viewId = field.getInt(action);
                        }
                    }
        
                    if (type == 9 || type == 10) {
                        text.put(viewId, value.toString());
                    }
                }
        
                System.out.println("title is: " + text.get(16908310));
                System.out.println("info is: " + text.get(16909082));
                System.out.println("text is: " + text.get(16908358));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        

        希望对你有所帮助。

        已编辑

        在您的 res 文件夹中创建一个名为 xml 的文件夹 - 在其中创建一个名为 -"accessibilityservice" 的 xml 并粘贴以下代码 -

        <?xml version="1.0" encoding="utf-8"?>
          <accessibility-service  xmlns:android="http://schemas.android.com/apk/res/android"
         android:accessibilityEventTypes="typeNotificationStateChanged"
         android:accessibilityFeedbackType="feedbackSpoken"
         android:notificationTimeout="100" />
        

        并在清单内部将您的服务标签更新为以下代码 -

        <service
                android:name=".YourServiceClassName"
                android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE" >
                <intent-filter>
                    <action android:name="android.accessibilityservice.AccessibilityService" />
                </intent-filter>
        
                <meta-data
                    android:name="android.accessibilityservice"
                    android:resource="@xml/accessibilityservice" />
           </service> 
        

        【讨论】:

        • 谢谢,我试试看,它会给你每条通知消息?
        • 在上面的代码中再添加一行-RemoteViews views = notification.contentView; if(views ==null){ views = notification.bigContentView; }
        • 您正在测试哪个 android api 级别?
        • 添加后 if(views ==null){ views = notification.bigContentView; } 现在我得到了标题,但其他 2 仍然为空
        • 我已经测试过了,信息对我来说是空的,但我能够成功获取标题和文本。通过发送普通文本而不是特殊聊天或表情来测试它。
        【解决方案4】:
                    <?xml version="1.0" encoding="utf-8"?>
            <manifest xmlns:android="http://schemas.android.com/apk/res/android"
                package="deepak.com.androidnotification">
                <uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission>
                <uses-permission android:name="android.permission.READ_SMS" />
                <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
        
                <application
                    android:allowBackup="true"
                    android:icon="@mipmap/ic_launcher"
                    android:label="@string/app_name"
                    android:roundIcon="@mipmap/ic_launcher_round"
                    android:supportsRtl="true"
                    android:theme="@style/AppTheme">
                    <activity android:name="deepak.com.androidnotification.MainActivity">
                        <intent-filter>
                            <action android:name="android.intent.action.MAIN" />
        
                            <category android:name="android.intent.category.LAUNCHER" />
                        </intent-filter>
                    </activity>
                    <service
                        android:name="deepak.com.androidnotification.NotificationService"
                        android:label="@string/app_name"
                        android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
        
                        <intent-filter>
        
                            <action android:name="android.service.notification.NotificationListenerService" />
        
                        </intent-filter>
        
                    </service>
                </application>
        
            </manifest>
        
        
        
        
            import android.app.Notification;
            import android.content.Context;
            import android.content.Intent;
            import android.graphics.Bitmap;
            import android.os.Bundle;
            import android.service.notification.NotificationListenerService;
            import android.service.notification.StatusBarNotification;
            import android.util.Log;
            import android.support.v4.content.LocalBroadcastManager;
        
            import java.io.ByteArrayOutputStream;
        
        
            public class NotificationService extends NotificationListenerService {
        
                Context context;
        
                @Override
        
                public void onCreate() {
        
                    super.onCreate();
                    context = getApplicationContext();
        
                }
                @Override
        
                public void onNotificationPosted(StatusBarNotification sbn) {
                    String pack = sbn.getPackageName();
                    String ticker ="";
                    if(sbn.getNotification().tickerText !=null) {
                        ticker = sbn.getNotification().tickerText.toString();
                    }
                    Bundle extras = sbn.getNotification().extras;
                    String title = extras.getString("android.title");
                   String text = extras.getCharSequence("android.text").toString();
                    int id1 = extras.getInt(Notification.EXTRA_SMALL_ICON);
        
        
                    Log.i("Package",pack);
                    Log.i("Ticker",ticker);
                    Log.i("Title",title);
                   Log.i("Text",text);
        
                    Intent msgrcv = new Intent("Msg");
                    msgrcv.putExtra("package", pack);
                    msgrcv.putExtra("ticker", ticker);
                    msgrcv.putExtra("title", title);
                   msgrcv.putExtra("text", text);
        
                    LocalBroadcastManager.getInstance(context).sendBroadcast(msgrcv);
        
        
                }
        
                @Override
        
                public void onNotificationRemoved(StatusBarNotification sbn) {
                    Log.i("Msg","Notification Removed");
        
                }
            }
        
        
        
        
            import android.content.Context;
            import android.view.LayoutInflater;
            import android.view.View;
            import android.view.ViewGroup;
            import android.widget.BaseAdapter;
            import android.widget.TextView;
        
            import java.util.ArrayList;
        
            /**
             * Created by Deepak on 8/30/2017.
             */
        
            public class CustomListAdapter extends BaseAdapter {
                int mResource;
                ArrayList<Data> arrayList;
                Context context;
        
                public CustomListAdapter(Context context,int resource, ArrayList<Data> arrayList) {
                    this.context = context;
                    this.arrayList = arrayList;
                    this.mResource=resource;
                }
                @Override
                public int getCount() {
                    return arrayList.size();
                }
        
                @Override
                public Object getItem(int position) {
                    return arrayList.get(position);
                }
        
                @Override
                public long getItemId(int position) {
                    return position;
                }
        
                @Override
                public View getView(int position, View convertView, ViewGroup parent) {
                    Data data = (Data) getItem(position);
                    LayoutInflater inflater =LayoutInflater.from(context);
                    convertView=inflater.inflate(mResource,parent,false);
                    TextView textView=(TextView)convertView.findViewById(R.id.textView);
                    TextView textView1=(TextView)convertView.findViewById(R.id.textView2);
                    TextView textView2=(TextView)convertView.findViewById(R.id.textView3);
                    textView.setText(data.getName());
                    textView1.setText(data.getPack());
                    textView2.setText(data.getText());
                    return convertView;
                }
            }
        
        
        
        
            import android.app.Activity;
            import android.content.BroadcastReceiver;
            import android.content.Context;
            import android.content.Intent;
            import android.content.IntentFilter;
            import android.os.Bundle;
            import android.support.v4.content.LocalBroadcastManager;
            import android.util.Log;
            import android.widget.ListView;
            import java.util.ArrayList;
        
            public class MainActivity extends Activity {
               ListView listView;
                ArrayList<Data> list;
                @Override
                protected void onCreate(Bundle savedInstanceState) {
                    super.onCreate(savedInstanceState);
                    setContentView(R.layout.activity_main);
                    listView=(ListView)findViewById(R.id.list) ;
                    LocalBroadcastManager.getInstance(this).registerReceiver(onNotice, new IntentFilter("Msg"));
                }
        
                private BroadcastReceiver onNotice= new BroadcastReceiver() {
        
                    @Override
                    public void onReceive(Context context, Intent intent) {
                        String title = intent.getStringExtra("title");
                        String pack= intent.getStringExtra("package");
                        String text = intent.getStringExtra("text");
                        Log.d("Title",title);
                        Data data=new Data();
                        data.setName(title);
                        data.setPack(pack);
                        data.setText(text);
                        list=new ArrayList<Data>();
                        list.add(data);
                        listView.setAdapter(new CustomListAdapter(MainActivity.this,R.layout.list_view,list));
                    }
                };
            }
        
        
        
        
        public class Data {
            private String name;
            private String pack;
            private String text;
        
            public Data() {
            }
        
            public Data(String name, String pack, String text) {
                this.name = name;
                this.pack = pack;
                this.text = text;
            }
        
            public String getName() {
                return name;
            }
        
            public void setName(String name) {
                this.name = name;
            }
        
            public String getPack() {
                return pack;
            }
        
            public void setPack(String pack) {
                this.pack = pack;
            }
        
            public String getText() {
                return text;
            }
        
            public void setText(String text) {
                this.text = text;
            }
        }
        
        
        
        
        <?xml version="1.0" encoding="utf-8"?>
        <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
        
            <TextView
                android:id="@+id/textView"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_alignParentTop="true"
                android:layout_centerHorizontal="true"
                android:layout_marginTop="26dp"
                android:gravity="center"
                android:text="TextView" />
        
            <TextView
                android:id="@+id/textView2"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_below="@+id/textView"
                android:layout_centerHorizontal="true"
                android:layout_marginTop="26dp"
                android:gravity="center"
                android:text="TextView" />
            <TextView
                android:id="@+id/textView3"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_alignLeft="@+id/textView2"
                android:layout_alignStart="@+id/textView2"
                android:layout_below="@+id/textView2"
                android:layout_marginTop="24dp"
                android:gravity="center"
                android:text="TextView"/>
        
        </RelativeLayout>
        
        
        
        
        <?xml version="1.0" encoding="utf-8"?>
        <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:app="http://schemas.android.com/apk/res-auto"
            xmlns:tools="http://schemas.android.com/tools"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
        
           <ListView
               android:layout_width="match_parent"
               android:id="@+id/list"
               android:layout_height="wrap_content"/>
        
        
        
        </RelativeLayout>
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-04-21
          • 1970-01-01
          • 1970-01-01
          • 2022-11-30
          • 1970-01-01
          • 2015-03-07
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多