Android Broadcast Receiver не срабатывает

Я пытаюсь прочитать все входящие SMS в своем приложении для Android. Я написал широковещательный приемник для чтения сообщений и добавил разрешения для него в AndroidManifest. Я получаю следующую ошибку:

android.content.ActivityNotFoundException: не удалось найти явный класс активности {com.example.asus.otpclippr/com.example.asus.otpclippr.readerService}; вы объявили это действие в своем AndroidManifest.xml?

Это AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.asus.otpclippr">
<uses-permission-sdk-23 android:name="android.permission.BROADCAST_SMS"/>
<uses-permission-sdk-23 android:name="android.permission.RECEIVE_SMS" />
<uses-permission-sdk-23 android:name="android.permission.SEND_SMS" />
<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    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>
    <receiver android:name="com.example.asus.otpclippr.readerService" >
        <intent-filter>
            <action android:name="android.provider.Telephony.SMS_RECEIVED"      />
        </intent-filter>
    </receiver>
</application>

This is the MainActivity.java package com.example.asus.otpclippr;

import android.app.ActivityManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;

public class MainActivity extends AppCompatActivity {
    CheckBox copyClip, createNotif ;
    Button btn ;
    private BroadcastReceiver br ;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    copyClip = (CheckBox)findViewById(R.id.checkBox) ;
    createNotif = (CheckBox)findViewById(R.id.checkBox2) ;
    btn = (Button)findViewById(R.id.button) ;
    btn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            boolean res = false ;
            res = isMyServiceRunning(readerService.class) ;
            Intent intent = new     Intent(MainActivity.this,readerService.class) ;
            //intent.setAction("android.provider.Telephony.SMS_RECEIVED") ;
            intent.putExtra("flag1",copyClip.isChecked());
            intent.putExtra("flag2",createNotif.isChecked()) ;
            Log.d("Checkpoint1","calling broadcast") ;
            startActivity(intent);
        }
    });

}

/*public boolean isMyServiceRunning(Class<?> serviceClass){
    ActivityManager activityManager = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE) ;
    for(ActivityManager.RunningServiceInfo service : activityManager.getRunningServices(Integer.MAX_VALUE)){
        if(serviceClass.getName().equals(service.service.getClassName())){
            return true ;
        }
    }
    return false ;
    }*/
}

А это пакет BroadcastReceiver com.example.asus.otpclippr;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.provider.Telephony;
import android.telephony.SmsManager;
import android.telephony.SmsMessage;
import android.util.Log;
import android.widget.Toast;

/**
 * Created by ASUS on 27-12-2016.
 */

public class readerService extends BroadcastReceiver {
    SmsManager smsManager = SmsManager.getDefault() ;
    String[] msg ;
    @Override
    public void onReceive(Context context, Intent intent) {



    final Bundle bundle = intent.getExtras() ;
    try{
        if(bundle!=null) {
            SmsMessage smsMessage;

            if (Build.VERSION.SDK_INT >= 19) { //KITKAT
                SmsMessage[] msgs = Telephony.Sms.Intents.getMessagesFromIntent(intent);
                smsMessage = msgs[0];
            } else {
                Object pdus[] = (Object[]) bundle.get("pdus");
                smsMessage = SmsMessage.createFromPdu((byte[]) pdus[0]);
            }
            String message = smsMessage.getMessageBody() ;
            String[] checks = new String[]{"OTP","Transaction","Password","key","card","txn"} ;
            msg = message.split(" ") ;
            Log.d("Message",message) ;
            for(int i=0;i<checks.length;i++){
                if(message.contains(checks[i])){
                    checkforOTP(context,message) ;
                    Log.d("Check2","Checking for OTP") ;
                    break;
                }
            }

            /*final Object[] pdusObj = (Object[]) bundle.get("pdus");
            for (int i = 0; i < pdusObj.length; i++) {

                SmsMessage currentMessage = SmsMessage.createFromPdu((byte[]) pdusObj[i]);
                String phoneNumber = currentMessage.getDisplayOriginatingAddress();

                String senderNum = phoneNumber;
                String message = currentMessage.getDisplayMessageBody();

                Log.d("SmsReceiver", "senderNum: " + senderNum + "; message: " + message);
                String[] msg = message.split(" ") ;
                Toast.makeText(context,message,Toast.LENGTH_SHORT).show();
                String[] checks = new String[]   {"OTP","Transaction","Password","key","card"} ;
                for(int j=0; j< checks.length; j++){
                    if(message.contains(checks[j])){
                        checkforOTP(message) ;
                        break;
                    }
                }
            }*/
        }
    }catch (Exception e){
        e.printStackTrace();
    }
}

public void checkforOTP(Context context ,String message){
    int pos = message.indexOf("is") ;
    String msg1 = message.substring(pos,message.length()) ;
    String otp1 = msg1.split(" ")[0];
    String msg2 = message.substring(0,pos) ;
    String[] tempA = msg2.split(" ") ;
    String otp2 = tempA[tempA.length -1] ;
    if(isValid(otp1)){
        Toast.makeText(context,"OTP is"+otp1,Toast.LENGTH_SHORT).show();
    }
    else if(isValid(otp2)){
        Toast.makeText(context,"OTP is "+otp2,Toast.LENGTH_SHORT).show();
    }
    else{
        Log.d("check3","Wrong call") ;
    }

}

public boolean isValid(String x){
    if(!(x.length()==4 || x.length() ==6)){
        return false ;
    }
    if(x.matches("\\d+")){
        return  true ;
    }
    return  false ;
}
}

Как правильно вызвать Broadcast Receiver из MainActivity? Заранее спасибо


person user6739649    schedule 04.01.2017    source источник


Ответы (1)


Вы делаете это в OnClickListener:

       Intent intent = new     Intent(MainActivity.this,readerService.class) ;
        //intent.setAction("android.provider.Telephony.SMS_RECEIVED") ;
        intent.putExtra("flag1",copyClip.isChecked());
        intent.putExtra("flag2",createNotif.isChecked()) ;
        Log.d("Checkpoint1","calling broadcast") ;
        startActivity(intent);

Вы звоните startActivity() с Intent, который нацелен на BroadcastReceiver. readerService это BroadcastReceiver, а не Activity. Это не может работать.

person David Wasser    schedule 05.01.2017
comment
Спасибо. Можете ли вы предложить некоторые изменения, которые можно внести, чтобы onClickListener запускал Broadcast Receiver? Заранее спасибо. - person user6739649; 05.01.2017
comment
Извините, я не понимаю. Ваш BroadcastReceiver сработает при поступлении входящего SMS. Разве это не то, чего ты хочешь? - person David Wasser; 05.01.2017
comment
Да. Я пытаюсь прочитать входящее SMS и создать с ним тост-сообщение. Ничего менять не надо? Думал должен быть какой-то звонок на приемник вещания. - person user6739649; 05.01.2017
comment
Нет, ваш BroadcastReceiver настроен в вашем манифесте. Он будет вызываться при поступлении SMS, даже если ваше приложение не запущено. Вам просто нужно убедиться, что вы запускаете свое приложение хотя бы один раз после установки. Приложению (Activity) на самом деле ничего не нужно делать. - person David Wasser; 05.01.2017
comment
О.. Я этого не знал. Но все равно не работает как надо. Я также добавил разрешения. Должен ли я что-то изменить в коде? Заранее спасибо. - person user6739649; 05.01.2017
comment
Вызывается ли ваш метод onReceive()? Что случается? - person David Wasser; 05.01.2017
comment
onReceive() не вызывается во время входящего SMS. - person user6739649; 06.01.2017
comment
На каком устройстве вы тестируете? Какая версия андроида работает? - person David Wasser; 06.01.2017
comment
Android-устройство. Мото Х играть. Android версии 6.0.1 - person user6739649; 06.01.2017
comment
Начиная с Android 6, пользователи могут предоставлять и отзывать разрешения. Проверьте, предоставили ли вы разрешение RECEIVE_SMS в настройках безопасности на телефоне. - person David Wasser; 06.01.2017
comment
Кроме того, вы должны убедиться, что разрешение было предоставлено во время выполнения. Посмотрите developer.android.com/training/permissions/requesting.html и добавьте этот код проверки разрешения в свой Activity, чтобы убедиться, что ваше приложение имеет разрешение RECEIVE_SMS. - person David Wasser; 06.01.2017
comment
Я дал разрешение сейчас, и он работает нормально. Большое спасибо. - person user6739649; 06.01.2017
comment
Великолепно! Рад, что смог быть полезен. - person David Wasser; 06.01.2017