I am trying to read all incoming SMS in my Android application. I have written a Broadcast Receiver to read the messages and have added the permissions for it in the AndroidManifest. I am getting the following error:
android.content.ActivityNotFoundException: Unable to find explicit activity class {com.example.asus.otpclippr/com.example.asus.otpclippr.readerService}; have you declared this activity in your AndroidManifest.xml?
This is the 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 ;
}*/
}
And this is the BroadcastReceiver package 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 ;
}
}
What is the correct way to call a Broadcast Receiver from the MainActivity?Thanks in advance
You are doing this in an
OnClickListener
:You are calling
startActivity()
with anIntent
that targets aBroadcastReceiver
.readerService
is aBroadcastReceiver
, not anActivity
. This can't work.