Search code examples
androidnotificationsnotificationservices

Not able to read notifications from other apps


I want to read notifications from other apps in android , but I am not able to do so. These are my implementations to achieve same. This is my MainActivity.java

package com.example.demoapp;

import androidx.appcompat.app.AppCompatActivity;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Color;
import android.os.Bundle;
import android.text.Html;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {
    TableLayout tab;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tab = (TableLayout)findViewById(R.id.tab);
         LocalBroadcastManager.getInstance(this).registerReceiver(onNotice, new IntentFilter("Msg"));
    }
    private BroadcastReceiver onNotice= new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            String pack = intent.getStringExtra("package");
            String title = intent.getStringExtra("title");
            String text = intent.getStringExtra("text");
            TableRow tr = new TableRow(getApplicationContext());
            tr.setLayoutParams(new TableRow.LayoutParams( TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.WRAP_CONTENT));
            TextView textview = new TextView(getApplicationContext());
            textview.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.WRAP_CONTENT,1.0f));
            textview.setTextSize(20);
            textview.setTextColor(Color.parseColor("#0B0719"));
            textview.setText(Html.fromHtml(pack +"<br><b>" + title + " : </b>" + text));
            tr.addView(textview);
            tab.addView(tr);




        }
    };
}

This is my NotificationService class

package com.example.demoapp;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
import android.util.Log;

import androidx.localbroadcastmanager.content.LocalBroadcastManager;

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 = sbn.getNotification().tickerText.toString();
        Bundle extras = sbn.getNotification().extras;
        String title = extras.getString("android.title");
        String text = extras.getCharSequence("android.text").toString();

        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");

    }

}

This is my AndroidManifest.xml

    <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:dist="http://schemas.android.com/apk/distribution"
    package="com.example.demoapp">

    <dist:module dist:instant="true" />

    <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=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service android:name="com.example.demoapp.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>

This is my activity.xml

    <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
    tools:context=".MainActivity">
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <TableLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/tab" />
    </ScrollView>
    </LinearLayout>


</androidx.constraintlayout.widget.ConstraintLayout>

I have tested app in Android 5 and above, it is not getting any notification details. I gave permission to the app for reading permissions in android while testing on Android 6 and above versions. Suggest me where I am getting wrong.


Solution

  • I have created a small demo for you its working fine in Android API-18 and above devices.

    Even you can

    1. Read all incoming SMS

    2. Read all incoming calls

    3. Battery Low and other notifications too

    This is screenshot for display notification of other application Picture1 Picture2

    NotificationService.java

    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);
            Bitmap id = sbn.getNotification().largeIcon;
            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);
            if(id != null) {
                ByteArrayOutputStream stream = new ByteArrayOutputStream();
                id.compress(Bitmap.CompressFormat.PNG, 100, stream);
                byte[] byteArray = stream.toByteArray();
                msgrcv.putExtra("icon",byteArray);
            }
            LocalBroadcastManager.getInstance(context).sendBroadcast(msgrcv);
        }
        @Override
        public void onNotificationRemoved(StatusBarNotification sbn) {
            Log.i("Msg","Notification Removed");
    
        }
    }
    

    MainActivity.java

    import android.app.Activity;
    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;
    import android.content.IntentFilter;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.os.Bundle;
    import android.support.v4.content.LocalBroadcastManager;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.widget.ListView;
    
    import java.util.ArrayList;
    
    
    public class MainActivity extends Activity {
    
        ListView list;
        CustomListAdapter adapter;
        ArrayList<Model> modelList;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            modelList = new ArrayList<Model>();
            adapter = new CustomListAdapter(getApplicationContext(), modelList);
            list=(ListView)findViewById(R.id.list);
            list.setAdapter(adapter);
            LocalBroadcastManager.getInstance(this).registerReceiver(onNotice, new IntentFilter("Msg"));
        }
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            getMenuInflater().inflate(R.menu.menu_main, menu);//Menu Resource, Menu
            return true;
        }
    
        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            switch (item.getItemId()) {
                case R.id.action_settings:
                    Intent intent = new Intent(
                            "android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS");
                    startActivity(intent);
                    return true;
                default:
                    return super.onOptionsItemSelected(item);
            }
        }
        private BroadcastReceiver onNotice= new BroadcastReceiver() {
    
            @Override
            public void onReceive(Context context, Intent intent) {
               // String pack = intent.getStringExtra("package");
                String title = intent.getStringExtra("title");
                String text = intent.getStringExtra("text");
                //int id = intent.getIntExtra("icon",0);
    
                Context remotePackageContext = null;
                try {
                    byte[] byteArray =intent.getByteArrayExtra("icon");
                    Bitmap bmp = null;
                    if(byteArray !=null) {
                        bmp = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length);
                    }
                    Model model = new Model();
                    model.setName(title +" " +text);
                    model.setImage(bmp);
    
                    if(modelList !=null) {
                        modelList.add(model);
                        adapter.notifyDataSetChanged();
                    }else {
                        modelList = new ArrayList<Model>();
                        modelList.add(model);
                        adapter = new CustomListAdapter(getApplicationContext(), modelList);
                        list=(ListView)findViewById(R.id.list);
                        list.setAdapter(adapter);
                    }
    
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        };
    }
    

    activity_main.xml

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="{relativePackage}.${activityClass}" >
    
        <ListView
            android:id="@+id/list"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_alignParentTop="true" >
        </ListView>
    </RelativeLayout>
    

    Androidmanifest.xml

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.demoapp">
    
        <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="@drawable/ic_launcher"
            android:label="@string/app_name"
            android:theme="@style/AppTheme">
            <activity
                android:name="com.example.demoapp.MainActivity"
                android:configChanges="keyboardHidden|orientation|screenSize"
                android:label="@string/app_name">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
            <service
                android:name="com.example.demoapp.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>