Following this tutorial: http://www.vogella.de/articles/AndroidServices/article.html#receiver I created my own project. Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="alex.broadcast.sample"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="13" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<receiver android:name="MyPhoneReceiver">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE"></action>
</intent-filter>
</receiver>
<uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
</application>
</manifest>
Code:
public class MyPhoneReceiver extends BroadcastReceiver {
final String logTag = "BroadcastReceiverSample";
#Override
public void onReceive(Context context, Intent intent) {
Bundle extras = intent.getExtras();
if (extras != null) {
String state = extras.getString(TelephonyManager.EXTRA_STATE);
Log.i(logTag, "Call state: " + state);
if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
String phoneNumber = extras.getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
Log.i(logTag, "Phone number: " + phoneNumber);
}
}
}
}
Running this sample on Android simulator, I see that it is successfully installed. However, onReceive function is never called. I make incoming call using:
telnet localhost 5554
gsm call 12345678
Emulator shows incoming call, but onReceive is not called.
Shouldn't it be:
<receiver android:name=".MyPhoneReceiver">
^ note the dot
Also, the location of the permission is wrong, it should be a child of <manifest> not of <Application>.
On Android 6 dont forget to allow the permission :
onCreate(){
if (
ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED
&&
ActivityCompat.checkSelfPermission(this, Manifest.permission.PROCESS_OUTGOING_CALLS) != PackageManager.PERMISSION_GRANTED
)
{
requestPermission();
}else {
IntentFilter filter = new IntentFilter();
filter.addAction("android.intent.action.PHONE_STATE");
filter.addAction("android.intent.action.NEW_OUTGOING_CALL");
registerReceiver(receiver, filter);
}
}
private void requestPermission() {
final List<String> permissionsList = new ArrayList<String>();
permissionsList.add(Manifest.permission.READ_PHONE_STATE);
permissionsList.add(Manifest.permission.PROCESS_OUTGOING_CALLS);
ActivityCompat.requestPermissions(this,permissionsList.toArray(new String[permissionsList.size()]),
REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode){
case REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS:{
IntentFilter filter = new IntentFilter();
filter.addAction("android.intent.action.PHONE_STATE");
filter.addAction("android.intent.action.NEW_OUTGOING_CALL");
registerReceiver(receiver, filter);
}
}
}
Related
I write an Android App that should receive data from a Bluetooth low energy device. As a first step I try to scan for devices. Because the scan did not work I reduced my code to a minimum. When I click the checkPermissionBtn Log shows:
BLE_TESTApp: BLUETOOTH grated.
BLE_TESTApp: BLUETOOTH_ADMIN grated.
BLE_TESTApp: ACCESS_COARSE_LOCATION grated.
So I assume all permissions are o.k..
When I click searchBtn Log shows: BLE_TESTApp: Start scan... after 35 sec. BLE_TESTApp: Stop scan.
But leScanCallback is obviously not called. There is no Device found in the Log.
There is definitely at least one Bluetooth LE device available. I checked it with an Bluetooth LE Terminal App from the Appstore.
Wy does scan not found a device?
Here is my code:
public class MainActivity extends AppCompatActivity {
private static final String TAG = "BLE_TESTApp";
private Button searchBtn, checkPermissionBtn;
final int REQ_CODE_BLUETOOTH_PERMISSION = 42;
final int REQ_CODE_BLUETOOTH_ADMIN_PERMISSION = 43;
final int REQ_CODE_COARSE_PERMISSION = 44;
private BluetoothManager bluetoothManager;
private BluetoothAdapter bluetoothAdapter;
private BluetoothLeScanner bluetoothLeScannerLeScanner;
private final static int REQUEST_ENABLE_BT = 1;
private Handler handler = new Handler();
private static final long INTERVAL = 35000;
private ScanCallback leScanCallback = new ScanCallback() {
#Override
public void onScanResult(int callbackType, ScanResult result) {
Log.d(TAG, "Device found");
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
searchBtn = findViewById(R.id.searchBtn);
checkPermissionBtn = findViewById(R.id.cpBtn);
checkPermissionBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.BLUETOOTH) == PackageManager.PERMISSION_GRANTED){
Log.d(TAG, "BLUETOOTH grated.");
}else{
Log.d(TAG, "BLUETOOTH NOT grated!");
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.BLUETOOTH}, REQ_CODE_BLUETOOTH_PERMISSION);
}
if(ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.BLUETOOTH_ADMIN) == PackageManager.PERMISSION_GRANTED){
Log.d(TAG, "BLUETOOTH_ADMIN grated.");
}else{
Log.d(TAG, "BLUETOOTH_ADMIN NOT grated!");
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.BLUETOOTH_ADMIN}, REQ_CODE_BLUETOOTH_ADMIN_PERMISSION);
}
if(ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED){
Log.d(TAG, "ACCESS_COARSE_LOCATION grated.");
}else{
Log.d(TAG, "ACCESS_COARSE_LOCATION NOT grated!");
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, REQ_CODE_COARSE_PERMISSION);
}
}
});
bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
bluetoothAdapter = bluetoothManager.getAdapter();
bluetoothLeScannerLeScanner = bluetoothAdapter.getBluetoothLeScanner();
if (bluetoothAdapter != null && !bluetoothAdapter.isEnabled()) {
Log.d(TAG, "Bluetooth not enabled!");
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
}
searchBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.i(TAG, "Start scan...");
searchBtn.setEnabled(false);
AsyncTask.execute(new Runnable() {
#Override
public void run() {
bluetoothLeScannerLeScanner.startScan(leScanCallback);
}
});
handler.postDelayed(new Runnable() {
#Override
public void run() {
Log.i(TAG, "Stop scan.");
searchBtn.setEnabled(true);
AsyncTask.execute(new Runnable() {
#Override
public void run() {
bluetoothLeScannerLeScanner.stopScan(leScanCallback);
}
});
}
}, INTERVAL);
}
});
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(requestCode == REQ_CODE_BLUETOOTH_PERMISSION && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
Log.d(TAG, "REQ_CODE_BLUETOOTH_PERMISSION granted.");
}
if(requestCode == REQ_CODE_BLUETOOTH_ADMIN_PERMISSION && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
Log.d(TAG, "REQ_CODE_BLUETOOTH_ADMIN_PERMISSION granted.");
}
if(requestCode == REQ_CODE_COARSE_PERMISSION && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
Log.d(TAG, "REQ_CODE_COARSE_PERMISSION granted.");
}
}
}
And the Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.bluetooth_le_test_03">
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<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/Theme.Bluetooth_Le_Test_03">
<activity android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
In addition to what you have done, try adding ACCESS_FINE_LOCATION to the list of permissions. Also have a look at the links below for more information on how to do scanning with Android:-
The ultimate guide to Android BLE
Location needs to be enabled on Android 6.0
Location needs to be enabled on Android 10.0
Turn on BLE scanning without asking for user permission
I want to write a program that will list the available Bluetooth devices and allow the user to pair with them.
I have pieced together the code below. Unfortunately, the only intent that is called is ACTION_STATE_CHANGED, which occurs when I manually enable/disable Bluetooth on the device I am using for testing.
When I manually enable and disable Bluetooth on the device I am using for testing, it does trigger the intent, because I get the corresponding output. However, none of the other intents, such as "Discovery Started" are triggered.
When I run the adapter.startDiscovery() it always returns false, so I do not think it is looking for devices.
This code always returns the device address as 02:00:00:00:00:00
How can I fix this?
public class MainActivity extends Activity {
private BluetoothAdapter BTAdapter;
private ListView mLvDevices;
public static int REQUEST_BLUETOOTH = 1;
private ArrayList<String> mDeviceList = new ArrayList<String>();
#RequiresApi(api = Build.VERSION_CODES.M)
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_find_bluetooth);
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothDevice.ACTION_FOUND);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(mReceiver, filter);
if (!adapter.isEnabled()) {
Intent enableBluetoothIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivity(enableBluetoothIntent);
}
ActivityCompat.requestPermissions(this, new String[]
{Manifest.permission.ACCESS_FINE_LOCATION},1);
System.out.println("Discovery"+adapter.startDiscovery());
String mydeviceaddress = adapter.getAddress();
String mydevicename = adapter.getName();
System.out.println(mydevicename + " : " + mydeviceaddress+","+adapter.getState());
}
#Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(mReceiver);
}
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
System.out.println("Action"+action);
if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
System.out.println("Started");
} else if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
System.out.println("changed");
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
System.out.println("finished");
} else if (BluetoothDevice.ACTION_FOUND.equals(action)) {
//bluetooth device found
BluetoothDevice device = (BluetoothDevice) intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// System.out.println("Found device " + device.getName());
}
}
};
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.easyinfogeek.bluetooth">
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="11"
android:targetSdkVersion="18" />
<application
android:allowBackup="true"
android:label="#string/app_name"
android:theme="#android:style/Theme.Holo.Light" >
<activity
android:name="com.easyinfogeek.bluetooth.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Check if your app have the follow permissions before start discovery:
Manifest.permission.ACCESS_FINE_LOCATION;
Manifest.permission.ACCESS_COARSE_LOCATION;
Example:
if(ActivityCompat.checkSelfPermission(context,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
//without permission, attempt to request it.
requestPermissions(Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION, PERM_REQUEST_CODE);
}
Request Permission:
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
if(requestCode == PERM_REQUEST_CODE && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//example permission granted
//request startDiscovery again.
}
}
Remember, if you want to enable/disable bluetooth a better way is
BluetoothAdapter.ACTION_REQUEST_ENABLE and
BluetoothAdapter.ACTION_REQUEST_DISABLE.
BluetoothAdapter.ACTION_REQUEST_DISABLE is hide, but you can do it yet.
public static final String ACTION_REQUEST_DISABLE = "android.bluetooth.adapter.action.REQUEST_DISABLE";
//to enable bluetooth
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent, REQUEST_ENABLE_BT);
// to disable bluetooth
Intent intent = new Intent(ACTION_REQUEST_DISABLE);
startActivityForResult(intent, REQUEST_DISABLE_BT);
I'm trying to scan for wifi networks
WifiWizard2.scan().then(function (results) {
console.log("SCANRESULTS", results);
}, function () {
console.log("TOUGH LUCK");
});
But every time I get an empty array
SCANRESULTS []
How am I doing this wrong?
I can confirm there are at least 20 networks around me.
I'm using an android 7 device if it makes any difference.
Sender class
public class WifiFunction {
private final String tag = WifiFunction.class.getSimpleName();
private WifiManager wifiManager;
public List<WifiDetail> getListofWifi(Context context) {
List<WifiDetail> wifiDetails = new ArrayList<>();
List<ScanResult> results = wifiManager.getScanResults();
Log.d(tag,"Wifi Details " + wifiManager.getScanResults().size());
for (ScanResult result : results) {
wifiDetails.add(new WifiDetail(result.BSSID, result.SSID));
Log.d(tag, result.BSSID + result.SSID);
}
return wifiDetails;
}
public void startScan(Context context)
{
wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
wifiManager.startScan();
IntentFilter filter = new IntentFilter();
filter.addAction(SCAN_RESULTS_AVAILABLE_ACTION);
context.registerReceiver(new resultReciever(this),filter);
}
}
Receiver class
public class resultReciever extends BroadcastReceiver {
private WifiFunction wifiFunction;
resultReciever(WifiFunction wifiFunction)
{
this.wifiFunction = wifiFunction;
}
#Override
public void onReceive(Context context, Intent intent) {
Log.d("Receiver","started");
wifiFunction.getListofWifi(context);
}
}
From Main Activity I am just calling:
(new WifiFunction()).startScan(this);
Manifest
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permisiion.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permisiion.ACCESS_FINE_LOCATION" />
<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>
<receiver android:name=".resultReciever"/>
</application>
Runtime Permission :
private boolean checkPermission() {
List<String> permissionsList = new ArrayList<String>();
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_WIFI_STATE) != PackageManager.PERMISSION_GRANTED) {
permissionsList.add(Manifest.permission.ACCESS_WIFI_STATE);
}
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CHANGE_WIFI_STATE) != PackageManager.PERMISSION_GRANTED) {
permissionsList.add(Manifest.permission.CHANGE_WIFI_STATE);
}
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
permissionsList.add(Manifest.permission.ACCESS_COARSE_LOCATION);
}
if (permissionsList.size() > 0) {
ActivityCompat.requestPermissions(this, permissionsList.toArray(new String[permissionsList.size()]),
1);
return false;
}
return true;
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions,
int[] grantResults) {
switch (requestCode) {
case 1:
(new WifiFunction()).startScan(this);
break;
}
}
This should work. Tried it with the full code.
My onReceive is never executed. I've tried following guides online including from the official site. I'm testing on a virtual API 28 device. I understand that some of the GUI-related code might be wrong, but I should at least get a log output right? What am I missing?
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.receivesms">
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
<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"
tools:ignore="GoogleAppIndexingWarning">
<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=".SMSReceiver"
android:enabled="true"
android:exported="true"
android:permission="android.permission.BROADCAST_SMS">
<intent-filter android:priority="100">
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
</application>
Receiver, the first Log.D doesn't even execute:
public class SMSReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("MESS", intent.getAction());
Bundle bundle = intent.getExtras();
if (bundle != null) {
SmsMessage[] msgs;
String message;
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], bundle.getString("format"));
message = msgs[i].getMessageBody();
Log.d("MESS", message);
((EditText) LayoutInflater.from(context).inflate(R.layout.activity_main, null)
.findViewById(R.id.editText)).append(msgs[i].getDisplayOriginatingAddress()
+ "\n" + message + "\n");
}
abortBroadcast();
}
}
}
Main:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
requestSmsPermission();
}
private void requestSmsPermission() {
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);
} else {
Toast.makeText(this, "Permission granted", Toast.LENGTH_SHORT).show();
Log.d("", "Permission granted");
}
}
#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) {
requestSmsPermission();
} else {
Toast.makeText(this, "permission not granted", Toast.LENGTH_SHORT).show();
}
}
}
}
Your actual problem is in the SMS PERMISSION. You only request READ_SMS Permission from user not RECEIVE_SMS permission. You also have to give this permission to achieve this.
Manifest.permission.RECEIVE_SMS
Try adding this:
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_SMS, Manifest.permission.RECEIVE_SMS}, 1);
It looks like:
private void requestSmsPermission() {
String readSms = Manifest.permission.READ_SMS;
String receiveSms = Manifest.permission.RECEIVE_SMS;
int grant = ContextCompat.checkSelfPermission(this, readSms) + ContextCompat.checkSelfPermission(this, receiveSms);
if (grant != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{readSms, receiveSms}, 1);
} else {
Toast.makeText(this, "Permission granted", Toast.LENGTH_SHORT).show();
Log.d("", "Permission granted");
}
}
try to increase the priority so that your app receives the SMS first, I would set it to max:
<intent-filter android:priority="2147483647">
In my application, I am trying to read otp from SMS without typing inside my app.
but it is not working I cant find out the error I am trying to correct the error more than a week please help me to find out where is the mistake, i create a class for reading incoming message and pass the value to my OTPActivity page but null value reaching there
IncomingSms.java
public class IncomingSms extends BroadcastReceiver {
// Get the object of SmsManager
final SmsManager sms = SmsManager.getDefault();
public void onReceive(Context context, Intent intent) {
// Retrieves a map of extended data from the intent.
final Bundle bundle = intent.getExtras();
try {
if (bundle != null) {
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().replaceAll("\\D", "");
//message = message.substring(0, message.length()-1);
Log.i("SmsReceiver", "senderNum: " + senderNum + "; message: " + message);
Intent myIntent = new Intent("otp");
myIntent.putExtra("message", message);
myIntent.putExtra("number", senderNum);
LocalBroadcastManager.getInstance(context).sendBroadcast(myIntent);
// Show Alert
}
} // bundle is null
} catch (Exception e) {
Log.e("SmsReceiver", "Exception smsReceiver" + e);
}
}
}
OTPActivity
#Override
public void onResume() {
LocalBroadcastManager.getInstance(this).registerReceiver(receiver, new IntentFilter("otp"));
super.onResume();
}
#Override
public void onPause() {
super.onPause();
LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver);
}
private BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equalsIgnoreCase("otp")) {
final String message = intent.getStringExtra("message");
// message is the fetching OTP
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
mPinEditText.setText(message);
}
}
};
//Initialization Varibles
private void initViews() {
if ((ActivityCompat.checkSelfPermission(OTPActivity.this, Manifest.permission.READ_SMS) != PackageManager.PERMISSION_GRANTED)) {
ActivityCompat.requestPermissions(OTPActivity.this, new String[]{Manifest.permission.READ_SMS}, 100);
} else {
//Permission Granted
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case 100:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//Permission Granted
} else {
//Permission Not Granted
Toast.makeText(getApplicationContext(), "Permission not granted", Toast.LENGTH_SHORT).show();
}
}
}
manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mypkg.appanme">
<uses-permission android:name="android.permission.WRITE_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<receiver android:name=".IncomingSms">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
Log shows this error
Permission Denial: receiving Intent { act=android.provider.Telephony.SMS_RECEIVED flg=0x19000010 (has extras) } to com.gameloft.android.HEP.GloftM5HP/.iab.SmsReceiver requires android.permission.RECEIVE_SMS due to sender com.android.phone (uid 1001)
You need to add android:permission="android.permission.BROADCAST_SMS" to your receiver block in AndroidManifest.xml which is required to receive the SMS. Something like this:
<receiver
android:name=".IncomingSms"
android:permission="android.permission.BROADCAST_SMS">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
If you don't want to write a receiver, you can use a simple lightweight library https://github.com/VitaliBov/SmsInterceptor
You only need to override the interface method, create an Interceptor class and bind it with the life cycle. It looks like this:
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();
}
}
}