在Android中自动检测短信

时间:2016-03-30 13:53:05

标签: android broadcastreceiver sms android-service otp

我正在尝试从SMS自动检测OTP并在EditText中填充OTP。我试图通过接收器服务存档它,但它将日志作为'它是空'而不是自动填充EditText(etLastOtp)。

这是我的服务类:

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.telephony.SmsMessage;
import android.util.Log;

public class SmsListener extends BroadcastReceiver {

    public OnSmsReceivedListener listener = null;
    public Context context;

    public SmsListener()
    {

    }

    public void setOnSmsReceivedListener(Context context) {
        Log.d("Listener","SET");
        this.listener = (OnSmsReceivedListener) context;
        Log.d("Listener","SET SUCCESS");
    }

    public interface OnSmsReceivedListener {
        public void onSmsReceived(String otp);
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO Auto-generated method stub

        if(intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")){
            Bundle bundle = intent.getExtras();           //---get the SMS message passed in---
            SmsMessage[] msgs = null;
            String msg_from;
            if (bundle != null){
                //---retrieve the SMS message received---
                try{
                    Object[] pdus = (Object[]) bundle.get("pdus");
                    msgs = new SmsMessage[pdus.length];
                    for(int i=0; i<msgs.length; i++){
                        msgs[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
                        msg_from = msgs[i].getOriginatingAddress();
                        String msgBody = msgs[i].getMessageBody();

                        Log.d("MsgBody", msgBody);

                            String otpSMS=msgBody.substring(36,36+4);


                        if (listener != null) {
                            listener.onSmsReceived(otpSMS);
                        }
                        else
                        {
                            Log.d("Listener", "Its null");
                        }

                    }
                }catch(Exception e){
                    Log.d("Exception caught", e.getMessage());
                }
            }
        }
    }
}

这是我的Activity类:

import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AppCompatActivity;
import android.telephony.PhoneStateListener;
import android.telephony.SmsMessage;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.analytics.GoogleAnalytics;
import com.google.android.gms.analytics.HitBuilders;
import com.google.android.gms.analytics.Tracker;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.HashMap;

public class MobileVerifySMS extends AppCompatActivity implements SmsListener.OnSmsReceivedListener {

    ImageButton btnBack;
    private boolean mIsInForegroundMode;

    Button btnVerify;
    String userName,email,password,currency,role,isind,timeZone;
    TextView tvTryAgain;
    public EditText etLastOTP;
    String lastOTP;
    Button btnSkip;
    TLConstants tlConstants;
    DatabaseHandler databaseHandler;
    TLAPI tlapi;

    private SmsListener receiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_mobile_verifysms);

        receiver = new SmsListener();
        receiver.setOnSmsReceivedListener(this);


        btnBack=(ImageButton)findViewById(R.id.btnBack);

        etLastOTP=(EditText)findViewById(R.id.etOtpEnd);
        btnVerify=(Button)findViewById(R.id.btnVerify);
        btnSkip=(Button)findViewById(R.id.btnSkip);
        tvTryAgain=(TextView)findViewById(R.id.tryAgain);

        btnVerify.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                if(etLastOTP.getText().toString().length()==4) {

//verify otp
                }
                else
                {
                    Toast.makeText(getApplicationContext(),"Enter 4 digit OTP",Toast.LENGTH_SHORT).show();
                }
            }
        });

        mIsInForegroundMode=true;
    }

    @Override
    public void onSmsReceived(String otp) {
        try
        {
            etLastOTP.setText(otp);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }


    @Override
    protected void onPause() {
        super.onPause();

        mIsInForegroundMode = false;
    }
    @Override
    protected void onResume() {
        super.onResume();
        mIsInForegroundMode = true;

    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();
        this.finish();
        overridePendingTransition(R.anim.hj_enter_left_anim_2, R.anim.hj_exit_left_anim);

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_mobile_verify, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

2 个答案:

答案 0 :(得分:3)

您没有显示任何注册BroadcastReceiver的代码,因此我会想出您已经在清单条目中添加了<intent-filter>对于BroadcastReceiver,在收到短信时触发。这可以解释你的问题。

如果您的<intent-filter>BroadcastReceiver,则在收到短信后,Android会自动为您创建BroadcastReceiver的新实例并在该新实例上调用onReceive()实例。此实例由于它是由Android创建的,因此没有设置侦听器。

要解决此问题,您需要从清单中删除<intent-filter>,并且需要在创建BroadcastReceiver后动态注册。{1}}。在Activity创建BroadcastReceiver后,请致电registerReceiver()。您需要创建一个IntentFilter来描述您想要接收的广播Intent

答案 1 :(得分:0)

您可以使用我的简单库https://github.com/VitaliBov/SmsInterceptor

您需要重写接口方法,创建一个Interceptor类,并将其与生命周期绑定:

public class AuthActivity extends AppCompatActivity implements OnMessageListener {
    private SmsInterceptor smsInterceptor;
    private EditText etAuthPassword;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_auth);
        initViews();
        initSmsInterceptor();
    }

    @Override
    protected void onResume() {
        super.onResume();
        smsInterceptor.register();
    }

    @Override
    protected void onPause() {
        super.onPause();
        smsInterceptor.unregister();
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        smsInterceptor.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

    @Override
    public void messageReceived(String message) {
        // You can perform your validation here
        etAuthPassword.setText(message);
    }

    private void initViews() {
        etAuthPassword = findViewById(R.id.etAuthPassword);
        etAuthPassword.addTextChangedListener(new SmsTextWatcher() {
            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                if (charSequence.length() == 4) {
                    btnAuthPassword.setEnabled(true);
                    checkCode();
                } else {
                    btnAuthPassword.setEnabled(false);
                }
            }
        });
    }

    private void initSmsInterceptor() {
        smsInterceptor = new SmsInterceptor(this, this);
        // Not necessary
        smsInterceptor.setRegex(SMS_CODE_REGEX);
        smsInterceptor.setPhoneNumber(PHONE_NUMBER);
    }

    private void checkCode() {
        // Validation
        if (isValid) {
            navigateToMainScreen();
        }
    }
}