I once had a broadcast receiver defined in my manifest to receive the Phone State, like this...
<receiver
android:name=".TelephonyManagerReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
I know in Android O I need to remove this and register the receiver in code, so I've done this...
private BroadcastReceiver callReceiver;
#Override
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
callReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.i("Phone","received");
}
};
this.registerReceiver(
callReceiver,
new IntentFilter(TelephonyManager.ACTION_PHONE_STATE_CHANGED)
); }
I'd expect to see some logging when I receive/make a call, but I do not. Any ideas?
I had the same problem. I added two dynamic permissions: CALL_PHONE, READ_PHONE_STATE and receiver is working well even if it's declared only in Manifest file.
I tested solution on emulator and also on phone - Nexus 5.
(This way it's working when app is open or in background, if you close app it won't work. For this I think you have to use foreground service)
I hope it's not too late.
Did you add the permission in the manifest and also request the permission at runtime?
Manifest:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
Runtime:
private static final int REQUEST_PHONE_STATE = 1;
private static String[] PERMISSIONS_PHONE_STATE = {
Manifest.permission.READ_PHONE_STATE
};
public static void verifyPhonePermissions(Activity activity) {
// Check if we have this permission
int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.READ_PHONE_STATE);
if (permission != PackageManager.PERMISSION_GRANTED) {
// We don't have permission so prompt the user
ActivityCompat.requestPermissions(
activity,
PERMISSIONS_PHONE_STATE,
REQUEST_PHONE_STATE
);
}
}
Related
I know this question has been a lot of times already, but I tried, I think, all the accepted answers, but it didn't solve my problem. I might be missing something, being new to Services and these kind of intents.
I have two apps, and one of them needs to call a service implemented in the second one.
In my app being called, I declared this in manifest :
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.myapp">
<application
android:name=".MyApplication">
<service
android:name="com.myapp.SynchronizationService"
android:exported="true"
android:enabled="true" >
</service>
</application>
</manifest>
My service being declared as follows :
package com.myapp;
/**
* Sync service
*/
public class SynchronizationService extends Service {
#Override
public void onCreate() {
super.onCreate();
initSync();
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
private void initSync() {
//do some work
}
}
And then, in my app calling the service, I have declared this :
val i = Intent().apply {
component = ComponentName("com.myapp", "com.myapp.SynchronizationService")
}
val c: ComponentName? = startService(i)
And in AndroidManifest.xml :
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.test.intentcaller">
<application>
...
</application>
<queries>
<package android:name="com.myapp" />
</queries>
</manifest>
But when I try to call this, I get this error in logs :
Unable to start service Intent { cmp=com.myapp/.SynchronizationService } U=0: not found
Thanks
You can declare permission in the app with service and use this permission in the app when you start intent
I'm developing an app where the app has OTP phone call for setting the user pin. So what i'm going to is to set automaticly the phone number i got from phone call to textview. The problem is PhoneStateReceiver class which extend BroadcastReceiver not working on Pie but working on Oreo.
It's work perfectly fine on my Oreo phone but not with Pie phone, there is no error i got, except on Pie the onReceive at PhoneStateReceiver is not called.
public class PhoneStateReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (action.equals(TelephonyManager.ACTION_PHONE_STATE_CHANGED)) {
String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
String incomingNumber = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
if((state.equals(TelephonyManager.EXTRA_STATE_RINGING))){
Toast.makeText(context,"Received State",Toast.LENGTH_SHORT).show();
}
if ((state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK))){
Intent local = new Intent();
local.setAction("service.to.activity.transfer");
local.setAction("android.intent.action.PHONE_STATE");
local.setAction("android.intent.action.NEW_OUTGOING_CALL");
local.putExtra("number", incomingNumber);
context.sendBroadcast(local);
}
if (state.equals(TelephonyManager.EXTRA_STATE_IDLE)){
Intent local = new Intent();
local.setAction("service.to.activity.transfer");
local.setAction("android.intent.action.PHONE_STATE");
local.setAction("android.intent.action.NEW_OUTGOING_CALL");
local.putExtra("number", incomingNumber);
context.sendBroadcast(local);
}
}
}
}
This is my Manifest.xml
<?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.jpx.qur">
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.CALL_PHONE"/>
<application
android:name=".modules.App"
android:allowBackup="false"
android:icon="#mipmap/ic_launcher_square"
android:label="#string/app_name"
android:networkSecurityConfig="#xml/network_security_config"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme"
tools:replace="android:allowBackup">
<receiver android:name=".utils.phoneutil.PhoneStateReceiver">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
</application>
</manifest>
This is how i handle the register receiver on my Activity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_otp);
getNumberPhone();
}
public void getNumberPhone(){
IntentFilter filter = new IntentFilter();
filter.addAction("service.to.activity.transfer");
BroadcastReceiver updateUIReciver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//UI update here
if (intent != null){
String message = intent.getStringExtra("number");
if(message != null){
if(message.length() == DIGITLENGTH){
String asubstring = message.substring(1, message.length());
pin1.setText(""+asubstring.charAt(0));
pin2.setText(""+asubstring.charAt(1));
pin3.setText(""+asubstring.charAt(2));
pin4.setText(""+asubstring.charAt(3));
}
}
}
}
};
registerReceiver(updateUIReciver, filter);
}
It's work perfectly fine on my Oreo phone but not with Pie phone, there is no error i got, except on Pie the onReceive at PhoneStateReceiver is not called. Please help me to fix this
Add READ_CALL_LOG permission in manifest as below and also take runtime permission:
<uses-permission android:name="android.permission.READ_CALL_LOG" />
As per Android doc:
Restricted access to call logs
Android 9 introduces the CALL_LOG permission group and moves the
READ_CALL_LOG, WRITE_CALL_LOG, and PROCESS_OUTGOING_CALLS permissions
into this group. In previous versions of Android, these permissions
were located in the PHONE permission group.
Restricted access to phone numbers Apps running on Android 9 cannot
read phone numbers or phone state without first acquiring the
READ_CALL_LOG permission, in addition to the other permissions that
your app's use cases require.
Phone numbers associated with incoming and outgoing calls are visible
in the phone state broadcast, such as for incoming and outgoing calls
and are accessible from the PhoneStateListener class. Without the
READ_CALL_LOG permission, however, the phone number field that's
provided in PHONE_STATE_CHANGED broadcasts and through
PhoneStateListener is empty.
To read phone numbers from phone state, update your app to request the
necessary permissions based on your use case:
To read numbers from the PHONE_STATE intent action, you need both the
READ_CALL_LOG permission and the READ_PHONE_STATE permission. To read
numbers from onCallStateChanged(), you need the READ_CALL_LOG
permission only. You don't need the READ_PHONE_STATE permission.
Check full documentation here.
This is my Menifest file
<receiver
android:name="com.agribazaar.android.receivers.OTPReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
This is my Broadcast Receiver class
public class OTPReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")){
}
}
This fixed the issue for me -
I wasn't explicitly requesting permission at runtime for android.Manifest.permission.RECEIVE_SMS.
In earlier versions of android it was working fine but in android O devices i got the issue.
int SMS_PERMISSION_REQ_CODE_SUBMIT = 101;
if (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.RECEIVE_SMS)
!= PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(SmsActivity.this, new String[]{Manifest.permission.RECEIVE_SMS},
SMS_PERMISSION_REQ_CODE_SUBMIT);
}
I have a service that is running in the foreground, inside this service i have a broadcast receiver, that listen to the SMS_RECEIVED action.
When the user is inside the application (both the application and the service are in the foreground) everything works well, and i am receiving the intent.
But when the user exists the application (only the service with the broadcast is in the foreground), the service stops when sms is received.
When the service is stopped no error reports are found anywhere (not in the logcat and no crash dialog pops up).
My service with the broadcast:
public class myService extends IntentService {
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(myService.this, intent.getAction(), Toast.LENGTH_SHORT).show();
}
};
#Override
public void onCreate() {
super.onCreate();
IntentFilter i= new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
i.setPriority(999);
registerReceiver(mReceiver, receiverFilter);
startForeground(...);
}
public void onDestroy() {
super.onDestroy();
stopForeground(true);
}
}
And i also have the following permission in my manifest:
<uses-permission android:name="android.permission.RECEIVE_SMS" />
myService is declared like this in the manifest:
<service
android:name=".Services.myService"
android:enabled="true"
android:exported="false" />
I had the same problem and I solved it removing <uses-permission android:name="android.permission.RECEIVE_SMS" />. But removing this permission I can't detect incoming SMS, so I created a class like these Catching Outgoing SMS using ContentObserver and used MESSAGE_TYPE_RECEIVED = 1 instead MESSAGE_TYPE_SENT = 2. You need to add this permission <uses-permission android:name="android.permission.READ_SMS" />.
http://developer.android.com/reference/android/provider/VoicemailContract.html
i don't know how to make a brocast receiver with VOICEMAIL. When you receive a voicemail,you will see "NEW VOICEMAIL" in notification,the icon just like a tape.
here is my code:
AndroidManifest.xml
<receiver android:name=".VoiceBrocast" >
<intent-filter>
<action android:name="android.intent.action.NEW_VOICEMAIL" />
</intent-filter>
</receiver>
<uses-permission android:name="com.android.voicemail.permission.ADD_VOICEMAIL" />
i tried to register in xx.java,but it's no works.
MainActivity.java:
protected VoiceBrocast mUiBroadcastReceiver;
mUiBroadcastReceiver = new VoiceBrocast();
IntentFilter mIntentFilter = new IntentFilter();
mIntentFilter.addAction("android.intent.action.ACTION_NEW_VOICEMAIL");
MainActivity.this.registerReceiver(mUiBroadcastReceiver, mIntentFilter);
VoiceBrocast.Java
public class VoiceBrocast extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
System.out.println("voicemail");
}
}
when i received a voicemail, nothing to print, i can't see "voicemail" in LogCat.
Not sure that else is wrong, but one problem is: the intent action is not called "android.intent.action.ACTION_NEW_VOICEMAIL" but "android.intent.action.NEW_VOICEMAIL".
Perhaps you mixed it up with the constant name on the VoicemailContract class which is VoicemailContract.ACTION_NEW_VOICEMAIL.
The minimum permission needed to access this content provider is ADD_VOICEMAIL
Do you have such permission ?