android广播接收器(呼叫和短信收到)不在Android牛轧糖工作

时间:2017-09-01 06:34:18

标签: android broadcastreceiver android-service android-broadcastreceiver

android调用和短信广播接收器完美地工作直到marshmallow 6.0,但在android nougat中,当应用程序关闭时它不起作用,并且当app在后台时,那么它在android nougat(N)中正常工作。请帮助我解决这个问题。

public class CallReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
    if(intent.getAction().equals("android.intent.action.NEW_OUTGOING_CALL")) {
        savedNumber = intent.getExtras().getString("android.intent.extra.PHONE_NUMBER");
        Log.d("t savedNumber", savedNumber);
        return;
    }else{
        String stateStr = intent.getExtras().getString(TelephonyManager.EXTRA_STATE);
        String number = intent.getExtras().getString(TelephonyManager.EXTRA_INCOMING_NUMBER);

        int state = 0;
        if(stateStr.equals(TelephonyManager.EXTRA_STATE_IDLE)){
            state = TelephonyManager.CALL_STATE_IDLE;
        }
        else if(stateStr.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)){
            state = TelephonyManager.CALL_STATE_OFFHOOK;
        }
        else if(stateStr.equals(TelephonyManager.EXTRA_STATE_RINGING)){
            state = TelephonyManager.CALL_STATE_RINGING;
        }

        Log.d("t incoming Number", number+" state: "+state+ " stateStr: "+stateStr);

        onCallStateChanged(context, state, number);
    }
 }
}
在mainfest文件中添加了

permisssion

<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />

注册接收方

     <receiver android:name=".Receiver.CallReceiver ">
        <intent-filter android:priority="100">
            <action android:name="android.intent.action.PHONE_STATE" />
        </intent-filter>
        <intent-filter>
            <action    android:name="android.intent.action.NEW_OUTGOING_CALL" />
        </intent-filter>
    </receiver>

2 个答案:

答案 0 :(得分:3)

试试这项服务..!

SMS观察员

 package com.demo.service;

import android.content.Context;
import android.content.Intent;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Handler;
import android.util.Log;
import android.widget.Toast;


import org.json.JSONArray;
import org.json.JSONObject;

import java.util.HashMap;
import java.util.Map;


public class SmsObserver extends ContentObserver {

    String TAG =SmsObserver.class.getSimpleName();

    static final Uri SMS_STATUS_URI = Uri.parse("content://sms");
    private Context mContext;
    private String contactId = "", contactName = "";
    private String smsBodyStr = "", phoneNoStr = "";
    private long smsDatTime = System.currentTimeMillis();

    public SmsObserver(Handler handler, Context ctx) {
        super(handler);
        mContext = ctx;
    }

    public boolean deliverSelfNotifications() {
        return true;
    }

    public void onChange(boolean selfChange) {
        try {
            Log.e("Info", "Notification on SMS observer");
            Cursor sms_sent_cursor = mContext.getContentResolver().query(SMS_STATUS_URI, null, null, null, null);
            if (sms_sent_cursor != null) {
                if (sms_sent_cursor.moveToFirst()) {
                    String protocol = sms_sent_cursor.getString(sms_sent_cursor.getColumnIndex("protocol"));
                    Log.e("Info", "protocol : " + protocol);
                    //for send  protocol is null
                    if (protocol == null) {
                        /*
                        String[] colNames = sms_sent_cursor.getColumnNames();
                        if(colNames != null){
                            for(int k=0; k<colNames.length; k++){
                                Log.e("Info","colNames["+k+"] : " + colNames[k]);
                            }
                        }
                        */
                        int type = sms_sent_cursor.getInt(sms_sent_cursor.getColumnIndex("type"));
                        Log.e("Info", "SMS Type : " + type);
                        // for actual state type=2
                        if (type == 2) {
                            Log.e("Info", "Id : " + sms_sent_cursor.getString(sms_sent_cursor.getColumnIndex("_id")));
                            Log.e("Info", "Thread Id : " + sms_sent_cursor.getString(sms_sent_cursor.getColumnIndex("thread_id")));
                            Log.e("Info", "Address : " + sms_sent_cursor.getString(sms_sent_cursor.getColumnIndex("address")));
                            Log.e("Info", "Person : " + sms_sent_cursor.getString(sms_sent_cursor.getColumnIndex("person")));
                            Log.e("Info", "Date : " + sms_sent_cursor.getLong(sms_sent_cursor.getColumnIndex("date")));
                            Log.e("Info", "Read : " + sms_sent_cursor.getString(sms_sent_cursor.getColumnIndex("read")));
                            Log.e("Info", "Status : " + sms_sent_cursor.getString(sms_sent_cursor.getColumnIndex("status")));
                            Log.e("Info", "Type : " + sms_sent_cursor.getString(sms_sent_cursor.getColumnIndex("type")));
                            Log.e("Info", "Rep Path Present : " + sms_sent_cursor.getString(sms_sent_cursor.getColumnIndex("reply_path_present")));
                            Log.e("Info", "Subject : " + sms_sent_cursor.getString(sms_sent_cursor.getColumnIndex("subject")));
                            Log.e("Info", "Body : " + sms_sent_cursor.getString(sms_sent_cursor.getColumnIndex("body")));
                            Log.e("Info", "Err Code : " + sms_sent_cursor.getString(sms_sent_cursor.getColumnIndex("error_code")));

                            smsBodyStr = sms_sent_cursor.getString(sms_sent_cursor.getColumnIndex("body")).trim();
                            phoneNoStr = sms_sent_cursor.getString(sms_sent_cursor.getColumnIndex("address")).trim();
                            smsDatTime = sms_sent_cursor.getLong(sms_sent_cursor.getColumnIndex("date"));

                            Log.e("Info", "SMS Content : " + smsBodyStr);
                            Log.e("Info", "SMS Phone No : " + phoneNoStr);
                            Log.e("Info", "SMS Time : " + smsDatTime);

                        }
                    }
                }
            } else
                Log.e("Info", "Send Cursor is Empty");
        } catch (Exception sggh) {
            Log.e("Error", "Error on onChange : " + sggh.toString());
        }
        super.onChange(selfChange);
    }//fn onChange


}//End of class SmsObserver

电话状态服务

package com.demo.service;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.widget.Toast;


import org.json.JSONArray;
import org.json.JSONObject;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;


public class PhoneStateService extends Service {

    String TAG = PhoneStateService.class.getSimpleName();

    boolean isMissedCall = false;
    boolean isRingingCall = false;
    boolean isRingingCallOne = false;

    String onOff;
    String callerID;
    String callerIDOne;
    String[] cIds;
    String[] cIdsOne;

    private CallStateListener mCallStateListener = new CallStateListener();
    private TelephonyManager mTelephonyManager;
    private int mCallState;

    @Override
    public void onCreate() {
        super.onCreate();
        mTelephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
        mCallState = mTelephonyManager.getCallState();
        mTelephonyManager.listen(mCallStateListener, PhoneStateListener.LISTEN_CALL_STATE);
    }

    @Override
    public void onDestroy() {
        Log.d("onDestroy", "onDestroy");
        mTelephonyManager.listen(mCallStateListener, PhoneStateListener.LISTEN_NONE);
        super.onDestroy();
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null; //-- not a bound service--
    }

    private final class CallStateListener extends PhoneStateListener {
        @Override
        public void onCallStateChanged(int state, String incomingNumber) {

            String getSimSerialNumber = mTelephonyManager.getSimSerialNumber();
            String mPhoneNumber = mTelephonyManager.getLine1Number();


            Log.d("number", "getSimSerialNumber : " + getSimSerialNumber);
            Log.d("number", "mPhoneNumber : " + mPhoneNumber);

            Log.d("number", "number : " + incomingNumber+" callstatelistner : "+state + "  "+Consts.number);

            onOff = SharedPreferenceUtil.getString("onOff","");

            callerID = SharedPreferenceUtil.getString("callerID","");

            callerIDOne = SharedPreferenceUtil.getString("callerIDOne","");

            cIds = new String[0];

            cIdsOne = new String[0];
            Log.d(TAG,"callerID : "+ callerID);
            Log.d(TAG,"callerIDOne : "+ callerIDOne);
            if (!callerID.equals("")) {
                try {
                    callerID = callerID.substring(0, callerID.length() - 1);
                    cIds = callerID.split(",");
                    Log.d(TAG,"callerID  :: "+ cIds.toString());
                    Log.d(TAG,"callerID  :: "+ cIds.length);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (!callerIDOne.equals("")) {
                try {
                    callerIDOne = callerIDOne.substring(0, callerIDOne.length() - 1);
                    cIdsOne = callerIDOne.split(",");

                    Log.d(TAG,"callerIDOne  :: "+ cIdsOne.toString());
                    Log.d(TAG,"callerIDOne  :: "+ cIdsOne.length);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            int OFFHOOK = TelephonyManager.CALL_STATE_OFFHOOK;
            int IDLE = TelephonyManager.CALL_STATE_IDLE;
            int RINGING = TelephonyManager.CALL_STATE_RINGING;

// my change
            mCallState = state;
//            Log.v("state","-- "+state+  "  --- "+TelephonyManager.CALL_STATE_IDLE+" - "+TelephonyManager.CALL_STATE_OFFHOOK+"  - "+TelephonyManager.CALL_STATE_RINGING);
            Log.v("state","-- "+state+  "  --- "+IDLE+" - "+OFFHOOK+"  - "+RINGING);
            if (state == 0){
                Log.d(TAG, "state ....0");
                if (state == OFFHOOK) {
                    Log.d("state", "idle --> off hook = new outgoing call"+ Consts.number);
                    // idle --> off hook = new outgoing call
                    //triggerSenses(Sense.CallEvent.OUTGOING);

                    callStateOffhoof(incomingNumber);
                } else if (state == RINGING) {
                    Log.d("state", "idle --> ringing = new incoming call"+Consts.number);
                    // idle --> ringing = new incoming call
                    //triggerSenses(Sense.CallEvent.INCOMING);
                    callStateRinging(incomingNumber);
                }else if (state == IDLE) {
                    Log.d(TAG, "state ....IDLE");
                    Log.d("state", "ringing --> idle = missed call"+Consts.number);
                    // ringing --> idle = missed call
                    //triggerSenses(Sense.CallEvent.MISSED);
                    callStateIdeal(incomingNumber);
                }
            }else if (state == 1){
                Log.d(TAG, "state ....1");
                if (state == OFFHOOK) {
                    Log.d("state", "ringing --> off hook = received"+Consts.number);
                    // ringing --> off hook = received
                    //triggerSenses(Sense.CallEvent.RECEIVED);
                    callStateOffhoof(incomingNumber);
                } else if (state == IDLE) {
                    Log.d("state", "ringing --> idle = missed call"+Consts.number);
                    // ringing --> idle = missed call
                    //triggerSenses(Sense.CallEvent.MISSED);
                    callStateIdeal(incomingNumber);
                }else if (state == RINGING)  {
                    Log.d("state", "idle --> ringing = new incoming call"+Consts.number);
                    // idle --> ringing = new incoming call
                    //triggerSenses(Sense.CallEvent.INCOMING);
                    callStateRinging(incomingNumber);
                }
            }else if (state == 2){
                Log.d(TAG, "state ....2");
                if (state == IDLE) {
                    Log.d("state", "off hook --> idle  = disconnected"+Consts.number);
                    // off hook --> idle  = disconnected
                    //triggerSenses(Sense.CallEvent.ENDED);
                    callStateIdeal(incomingNumber);
                } else if (state == RINGING) {
                    Log.d("state", "off hook --> ringing = another call waiting"+Consts.number);
                    // off hook --> ringing = another call waiting
                    //triggerSenses(Sense.CallEvent.WAITING);
                    callStateRinging(incomingNumber);
                }else if(state==OFFHOOK)
                {
                    String nm = Consts.number;
                    if (!nm.isEmpty()){
                        callStateOffhoof(nm);
                    }else {
                        callStateOffhoof(incomingNumber);
                    }

                }
                Log.d("CALL_STATE_OFFHOOK", String.valueOf(state));
            }
            /*switch (state) {
                case 0:
                    if (state == OFFHOOK) {
                        Log.d("state", "idle --> off hook = new outgoing call"+ Consts.number);
                        // idle --> off hook = new outgoing call
                        //triggerSenses(Sense.CallEvent.OUTGOING);

                        callStateOffhoof(incomingNumber);
                    } else if (state == RINGING) {
                        Log.d("state", "idle --> ringing = new incoming call"+Consts.number);
                        // idle --> ringing = new incoming call
                        //triggerSenses(Sense.CallEvent.INCOMING);
                        callStateRinging(incomingNumber);
                    }

                    break;

                case 2:
                    if (state == IDLE) {
                        Log.d("state", "off hook --> idle  = disconnected"+Consts.number);
                        // off hook --> idle  = disconnected
                        //triggerSenses(Sense.CallEvent.ENDED);
                        callStateIdeal(incomingNumber);
                    } else if (state == RINGING) {
                        Log.d("state", "off hook --> ringing = another call waiting"+Consts.number);
                        // off hook --> ringing = another call waiting
                        //triggerSenses(Sense.CallEvent.WAITING);
                        callStateRinging(incomingNumber);
                    }
                    else if(state==OFFHOOK)
                    {
                        String nm = Consts.number;
                        if (!nm.isEmpty()){
                            callStateOffhoof(nm);
                        }else {
                            callStateOffhoof(incomingNumber);
                        }

                    }
                    Log.d("CALL_STATE_OFFHOOK", String.valueOf(state));
                    break;

                case 1:
                    if (state == OFFHOOK) {
                        Log.d("state", "ringing --> off hook = received"+Consts.number);
                        // ringing --> off hook = received
                        //triggerSenses(Sense.CallEvent.RECEIVED);
                        callStateOffhoof(incomingNumber);
                    } else if (state == IDLE) {
                        Log.d("state", "ringing --> idle = missed call"+Consts.number);
                        // ringing --> idle = missed call
                        //triggerSenses(Sense.CallEvent.MISSED);
                        callStateIdeal(incomingNumber);
                    }
                    break;
            }*/
            Log.d(TAG, "Outer state.....");
//            mCallState = state; change
        }
    }

    public static void init(Context c) {
        c.startService(new Intent(c, PhoneStateService.class));
        Log.d("Service enabled","Service enabled: " + true);
    }
    boolean b;
    public void callStateRinging(String incomingNumber){
        /*Toast.makeText(getApplicationContext(), "Phone Is Riging",
                Toast.LENGTH_LONG).show();*/
        isMissedCall = true;
        isRingingCall = true;
        isRingingCallOne = true;

        Log.d(TAG,"Rebound : "+ onOff);
        if (onOff.equals("on")){

            b = false;
            for (int i=0; i<cIds.length; i++) {
                if (cIds[i].equals(incomingNumber)){
                    b = true;
                }else if (incomingNumber.contains(cIds[i])){
                    b = true;
                }
            }
            if (!b){
                for (int i=0; i<cIdsOne.length; i++) {
                    if (cIdsOne[i].equals(incomingNumber)){
                        b = true;
                    }else if (incomingNumber.contains(cIdsOne[i])){
                        b = true;
                    }
                }
            }
            Log.d(TAG,"b : "+b);
            if (!b) {
                Log.d(TAG,"Rebound : disconnectCall");
                disconnectCall();
            }else {
                Log.d(TAG,"Rebound : not disconnectCall because it allow contact...");
            }
        }else if (onOff.equals("off")){
            Log.d(TAG,"Rebound Off");
        }
        Log.d(TAG,"callStateRinging Rebound outer : "+ onOff);
        Log.d(TAG,"callStateRinging Rebound cIds  : "+ cIds.length);
        Log.d(TAG,"callStateRinging Rebound callerID: "+ callerID);
        Log.d("number", "callStateRinging number : " + incomingNumber);
    }

    public void callStateIdeal(String incomingNumber){
        /*Toast.makeText(getApplicationContext(), "phone is neither ringing nor in a call",
                Toast.LENGTH_LONG).show();*/

        if (!isRingingCall){
                        if (isRingingCallOne) {
                            Intent service;
//                            service = new Intent(this, WaitingMessageService.class);
//                            startService(service);
                            Log.d(TAG, "Servic called");
//                            new Handler().postDelayed(stopWaitnigPopUp, 10000);
                        }
            Log.d(TAG,"Rebound in A call : "+ onOff);
            if (Consts.isInternet()) {
//                            if (onOff.equals("on")) {

                String nm = Consts.number;
                String onlyDigitNum = Consts.getOnlyDigits(nm);
                String onlyDigitNumOne = Consts.getOnlyDigits(incomingNumber);
                Log.d(TAG,"nm : "+ nm);
                Log.d(TAG,"incomingNumber : "+ incomingNumber);
                Log.d(TAG,"onlyDigitNum : "+ onlyDigitNum);
                Log.d(TAG,"onlyDigitNumOne : "+ onlyDigitNumOne);

//                            }
            }else {
                Log.d(TAG,"No Internet so not send any rebounds");
            }
        }

        if (isMissedCall){
            Log.d(TAG,"Rebound : "+ onOff);

            if (Consts.isInternet()) {
                if (onOff.equals("on")) {
                    isMissedCall = false;

                }
            }else {
                Log.d(TAG,"No Internet so not send any rebounds");
            }

                        /*int count = dbHelper.numberOfRows();
                        Log.d(TAG,"count :" + count);
                        if (count != 0){
                            Cursor cursor = dbHelper.getAllData();
                            if (cursor.moveToFirst()) {
                                for (int j = 0; j < count; j++) {
                                    String alive = cursor.getString(1);
                                    String cantactno = cursor.getString(2);
                                    String multimidiyatype = cursor.getString(3);
                                    String path = cursor.getString(4);
                                    String credate = cursor.getString(5);
                                    String message = cursor.getString(6);

                                    if (cantactno.equals(incomingNumber)){
                                        Toast.makeText(getApplicationContext(),"Message "+ message + " path :"+ path +" Contact NO;"+ cantactno,Toast.LENGTH_SHORT).show();
                                    }

                                    Log.d(TAG,"--"+incomingNumber + cantactno + path + message);

                                    cursor.moveToNext();
                                }
                            }
                        }*/
        }
        Log.d(TAG,"callStateIdeal Rebound outer : "+ onOff);
        Log.d(TAG,"callStateIdeal Rebound cIds  : "+ cIds.length);
        Log.d(TAG,"callStateIdeal Rebound callerID: "+ callerID);
        Log.d("number", "callStateIdeal number : " + incomingNumber);
    }

    public void callStateOffhoof(String incomingNumber){
        /*Toast.makeText(getApplicationContext(), "Phone is Currently in A call",
                Toast.LENGTH_LONG).show();*/
        isMissedCall = false;
        isRingingCall = false;
        isRingingCallOne = true;

        if (!isRingingCall){
                        Intent service;
//                        service = new Intent(this,WaitingMessageService.class);
//                        startService(service);
                        Log.d(TAG,"Servic called");
//                        new Handler().postDelayed(stopWaitnigPopUp, 10000);

            Log.d(TAG,"Rebound in A call : "+ onOff);
            if (Consts.isInternet()) {
//                            if (onOff.equals("on")) {

                String nm = Consts.number;
                String onlyDigitNum = Consts.getOnlyDigits(nm);
                String onlyDigitNumOne = Consts.getOnlyDigits(incomingNumber);
                Log.d(TAG,"nm : "+ nm);
                Log.d(TAG,"incomingNumber : "+ incomingNumber);
                Log.d(TAG,"onlyDigitNum : "+ onlyDigitNum);
                Log.d(TAG,"onlyDigitNumOne : "+ onlyDigitNumOne);

//                            }
            }else {
                Log.d(TAG,"No Internet so not send any rebounds");
            }
        }
        Log.d(TAG,"callStateOffhoof Rebound outer : "+ onOff);
        Log.d(TAG,"callStateOffhoof Rebound cIds  : "+ cIds.length);
        Log.d(TAG,"callStateOffhoof Rebound callerID: "+ callerID);
        Log.d("number", "callStateOffhoof number : " + incomingNumber);
    }

    public void disconnectCall(){
        try {
            String serviceManagerName = "android.os.ServiceManager";
            String serviceManagerNativeName = "android.os.ServiceManagerNative";
            String telephonyName = "com.android.internal.telephony.ITelephony";
            Class<?> telephonyClass;
            Class<?> telephonyStubClass;
            Class<?> serviceManagerClass;
            Class<?> serviceManagerNativeClass;
            Method telephonyEndCall;
            Object telephonyObject;
            Object serviceManagerObject;
            telephonyClass = Class.forName(telephonyName);
            telephonyStubClass = telephonyClass.getClasses()[0];
            serviceManagerClass = Class.forName(serviceManagerName);
            serviceManagerNativeClass = Class.forName(serviceManagerNativeName);
            Method getService = // getDefaults[29];
                    serviceManagerClass.getMethod("getService", String.class);
            Method tempInterfaceMethod = serviceManagerNativeClass.getMethod("asInterface", IBinder.class);
            Binder tmpBinder = new Binder();
            tmpBinder.attachInterface(null, "fake");
            serviceManagerObject = tempInterfaceMethod.invoke(null, tmpBinder);
            IBinder retbinder = (IBinder) getService.invoke(serviceManagerObject, "phone");
            Method serviceMethod = telephonyStubClass.getMethod("asInterface", IBinder.class);
            telephonyObject = serviceMethod.invoke(null, retbinder);
            telephonyEndCall = telephonyClass.getMethod("endCall");
            telephonyEndCall.invoke(telephonyObject);

        } catch (Exception e) {
            e.printStackTrace();
            /*Log.error(DialerActivity.this,
                    "FATAL ERROR: could not connect to telephony subsystem");
            Log.error(DialerActivity.this, "Exception object: " + e);*/
        }
    }


}

我希望它为你工作..!

答案 1 :(得分:0)

我认为你忘了要求获得运行时间许可

从Android 6.0(API级别23)开始,用户在应用运行时向应用授予权限,而非在安装应用时授予

使用以下代码为READ_SMS添加运行时权限:

String permission = Manifest.permission.READ_SMS;
int grant = ContextCompat.checkSelfPermission(this, permission);
if (grant != PackageManager.PERMISSION_GRANTED) {
    String[] permission_list = new String[1];
    permission_list[0] = permission;
    ActivityCompat.requestPermissions(this, permission_list, 1);
}

而不是处理这样的结果:

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                       @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == 1) {
        if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            Toast.makeText(AccountClass.this,"permission granted", Toast.LENGTH_SHORT).show();  
             // perform your action here

        } else {
            Toast.makeText(AccountClass.this,"permission not granted", Toast.LENGTH_SHORT).show();
        }
    }

}

在清单文件中添加此权限:

<uses-permission android:name="android.permission.READ_SMS"/>