I would like my app to detect if a new outgoing call happened
I want to do something like this :
if (there was a new outgoing call) {
do...
} else {
do...
}
You can use the android Broadcast Reciever. To use it all you have to do is first,
Create a new handler class to handle the broadcast receiver.
public class OutgoingCallReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
//You can do this to get the phone number, it is only optional
String phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
//Handle outgoing call event here
}
}
Then register it in the android manifest so it knows where this method is.
<receiver android:name=".OutgoingCallReceiver" >
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
Finally, create a permission in the android manifest.
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
And that should do it, hope I could help. :)
Create a broadcast receiver to catch the outgoing calls:
public class CallReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
// your code
}
}
Then register it in the manifest:
<receiver android:name=".CallReceiver" >
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
</receiver>
Lastly set the permissions:
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
Detect outgoing phone call event
1)Create OutgoingCallBroadcastReceiver
public class OutgoingCallReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d(OutgoingCallReceiver.class.getSimpleName(), intent.toString());
Toast.makeText(context, "Outgoing call catched!", Toast.LENGTH_LONG).show();
//TODO: Handle outgoing call event here
}
}
Register OutgoingCallBroadcastReceiver in AndroidManifest.xml
Add permission in AndroidManifest.xml
Related
I have my main activity that start a service (Location service) and I want that service to broadcast the new location each time a new location is found.
Thanks to the log I know the service is working and I have new locations every seconds or so, but I never get the broadcast.
MainActivity.java
public class MainActivity extends Activity {
private static final String TAG = "mainActivity";
private CMBroadcastReceiver mMessageReceiver = new CMBroadcastReceiver();
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
// Start Service
startService(new Intent(this, LocationService.class));
super.onCreate(savedInstanceState);
}
#Override
public void onResume()
{
LocalBroadcastManager.getInstance(this).registerReceiver(
mMessageReceiver, new IntentFilter(CMBroadcastReceiver.RECEIVE_LOCATION_UPDATE));
super.onResume();
}
#Override
public void onPause()
{
LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
super.onPause();
}
}
CMBroadcastReceiver.java
public class CMBroadcastReceiver extends BroadcastReceiver {
private static final String TAG = "CMBroadcastReceiver";
public static final String RECEIVE_LOCATION_UPDATE = "LOCATION_UPDATES";
#Override
public void onReceive(Context context, Intent intent) {
Log.i(TAG, "Received broadcast");
String action = intent.getAction();
if (action.equals(RECEIVE_LOCATION_UPDATE))
{
Log.i(TAG, "Received location update from service!");
}
}
}
LocationService.java
/**
* Callback that fires when the location changes.
*/
#Override
public void onLocationChanged(Location location) {
mCurrentLocation = location;
mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
Log.i(TAG, "onLocationChanged " + location);
Intent intent = new Intent(CMBroadcastReceiver.RECEIVE_LOCATION_UPDATE);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
Log.i(TAG, "Broadcast sent");
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.cyclemapapp.gpstracker">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<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"
android:label="#string/title_activity_main"
android:theme="#style/AppTheme.NoActionBar">
android:configChanges="orientation|screenSize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".LocationService" android:process=":location_service" />
</application>
I the log I can see that "Broadcast Sent" But I never get the "Broadcast Received"
Any help will would be greatly appreciated.
EDIT:
Edited how the intent was created in the location service as Shaishav suggested.
Still doesn't work.
LocalBroadcastManager does not work across processes. Your Service is running in a separate process.
You can either run your Service in the same process as the Activity - by removing the process attribute from the <service> element - or use some sort of IPC instead - e.g., by sending and receiving the broadcasts on a Context instead of LocalBroadcastManager.
In your LocationService, send local broadcast using:
Intent intent = new Intent(CMBroadcastReceiver.RECEIVE_LOCATION_UPDATE);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
<service android:name=".LocationService" android:process=":location_service" />
Your service is in a separate process from the activity. LocalBroadcastManager is only for use in one process. Either remove android:process from the <service>, or use some IPC mechanism (e.g., system broadcasts, properly secured).
I have to receive system-sent implicit broadcasts (ACTION_PACKAGE_ADDED) to detect the installation of the application and perform some code. I used the code below:
public class Receiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
// It will trigger when any app is installed
Uri data = intent.getData();
String packageAdv = data.getEncodedSchemeSpecificPart();
//some code...
}
}
In my Manifest file I declared my receiver:
<receiver android:name="com.myapp.Receiver">
<intent-filter>
<action android:name="android.intent.action.PACKAGE_ADDED" />
<data android:scheme="package"/>
</intent-filter>
</receiver>
It works perfect before Version 8.0 Oreo. Now, I have to make my receiver explicit by using registerReceiver. How can I do this? Sample code would be appreciated.
I have decided to create a simple service for listening to PACKAGE_ADDED event.
public class MyService extends Service {
private BroadcastReceiver receiver;
public MyService() { }
#Override
public void onCreate() {
IntentFilter intentFilter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
intentFilter.addDataScheme("package");
receiver = new Receiver();
registerReceiver(receiver, intentFilter);
}
//ensure that we unregister the receiver once it's done.
#Override
public void onDestroy() {
unregisterReceiver(receiver);
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
Also, I needed to declare my service in manifest file:
<service
android:name="com.nolesh.myapp.MyService"
android:enabled="true">
</service>
I found a lot of information on stack about this, but no one has done this to the end.
At the beginning i add to android manifest this:
<receiver android:name=".gps.GpsLocationReceiver">
<intent-filter>
<action android:name="android.location.PROVIDERS_CHANGED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
Next i trying to add a lot of code to my app.
At the beginning i implements to my activity LocationListner
According to the this: Detecting GPS on/off switch in Android phones
LocationListener should override this method:
#Override
public void onReceive(Context context, Intent intent)
{
if (intent.getAction().matches("android.location.PROVIDERS_CHANGED"))
{
// react on GPS provider change action
}
}
But in my app, LocationListner override only this method:
#Override
public void onLocationChanged(Location location) {
}
What is wrong with this androidstudio ?
What i should do now ?
onReceive() is required for the BroadcastReceiver , onLocationChanged() is required and here you can get the changes of geo-location, determined by latitude and longitude:
#Override
public void onLocationChanged(Location location) {
Long myLongitude = location.getLongitude();
Long myLatitude = location.getLatitude();
}
if you don´t require this method in your class don´t implement LocationListener.
onReceive() method is from BroadcastReceiver class. You need to extend BroadcastReceiver first to override this method.
Follow the following steps:
1.Make your broadcast receiver class
public class NameOfYourBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
final LocationManager lM = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
if (lM.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
// do something
} else {
// do something else
}
}
}
2. Register your BroadcastReceiver. For this add the following lines to your AndroidManifest.xml
<receiver android:name="com.yourpackage.NameOfYourBroadcastReceiver">
<intent-filter>
<action android:name="android.location.PROVIDERS_CHANGED" />
</intent-filter>
</receiver>
Is there any way to develop an app that starts up when a user receives a phone call? I can't really go into details about the idea but was wondering if there was some call that would allow that to happen.
You can use a Broadcast Receiver for thatlike this
public class PhoneStatReceiver extends BroadcastReceiver{
private static final String TAG = "PhoneStatReceiver";
private static boolean incomingFlag = false;
private static String incoming_number = null;
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)){
incomingFlag = false;
String phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
Log.i(TAG, "call OUT:"+phoneNumber);
}else{
TelephonyManager tm = (TelephonyManager)context.getSystemService(Service.TELEPHONY_SERVICE);
switch (tm.getCallState()) {
case TelephonyManager.CALL_STATE_RINGING:
incomingFlag = true;//标识当前是来电
incoming_number = intent.getStringExtra("incoming_number");
Log.i(TAG, "RINGING :"+ incoming_number);
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
if(incomingFlag){
Log.i(TAG, "incoming ACCEPT :"+ incoming_number);
}
break;
case TelephonyManager.CALL_STATE_IDLE:
if(incomingFlag){
Log.i(TAG, "incoming IDLE");
}
break;
}
}
}
}
Register this receiver in AndroidManifest like this
<receiver android:name=".filter.PhoneStatReceiver">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE"/>
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
</receiver>
<uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"></uses-permission>
Yes We can start an diffrent app when User receives a phone call.Example :- Truecaller,Mobile no. Tracker apps.
You can use Services for this.
public class CallReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
final Context cont = context;
final Intent in = intent;
if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Intent i = new Intent(cont, MainActivity.class);
i.putExtras(in);
i.addCategory(Intent.CATEGORY_LAUNCHER);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
cont.startActivity(i);
}
}, 1000);
}
}
}
You must implement this handler with postDelayed so that your activity screen can be on top of native call screen. If you dont want this to happen then you must remove this handler.
Add these to your manifest--
<receiver
android:name=".CallReceiver"
android:enabled="true" >
<intent-filter android:priority="1000" >
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
and
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.PROCESS_INCOMING_CALLS" />
You have to use another extra_state for onreceiving call. This is for ringing state.
I am creating a class which uses broadcast receiver. I want to receive the broadcast on unlocking of the phone. But there is some issue. Please help me out.
My Manifest.xml is :-
<receiver android:name=".MyReciever">
<intent-filter>
<intent-filter>
<action android:name="android.intent.action.ACTION_USER_PRESENT" />
<action android:name="android.intent.action.ACTION_BOOT_COMPLETED" />
<action android:name="android.intent.action.ACTION_SCREEN_ON" />
</intent-filter>
</intent-filter>
</receiver>
and my Broadcast reciever class :-
public class MyReiever extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("My Reciever","is intent null => " + (intent == null));
Log.d("My Reciever",intent.getAction()+"");
}
}
Though other application and services are receiving broadcast for "Screen_on" and "USer_Present" eg. WifiService.
Although the Java constants are android.content.intent.ACTION_USER_PRESENT, android.content.intent.ACTION_BOOT_COMPLETED, and android.content.intent.ACTION_SCREEN_ON, the values of those constants are android.intent.action.USER_PRESENT, android.intent.action.BOOT_COMPLETED, and android.intent.action.SCREEN_ON. It is those values which need to appear in your manifest.
Note, however, that a receiver for ACTION_SCREEN_ON can not be declared in a manifest but must be registered by Java code, see for example this question.
Since implicit broadcast receivers are not working as of Android 8.0, you must register your receiver by code and also in the manifest.
Do these steps:
Add manifest tag
<receiver android:name=".MyReciever">
<intent-filter>
<intent-filter>
<action android:name="android.intent.action.ACTION_USER_PRESENT" />
<action android:name="android.intent.action.ACTION_BOOT_COMPLETED" />
<action android:name="android.intent.action.ACTION_SCREEN_ON" />
</intent-filter>
</intent-filter>
</receiver>
Create a receiver class and add your codes
public class MyReciever extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("My Reciever","is intent null => " + (intent == null));
Log.d("My Reciever",intent.getAction()+"");
}
}
Create a service and register the receiver in it
public class MyService extends Service {
MyReceiver receiver = new MyReceiver();
#Override
public IBinder onBind(Intent intent) { return null; }
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
registerReceiver(receiver);
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(receiver);
}
}
Don't forget to define the service in manifest
<service android:name=".MyService"/>
To make your broadcast work, you have to register it in service. And to keep your service alive you can use tools like alarm managers, jobs, etc which is not related to this question.
Check your Class name, that is extending BroadcastReceiver. It should be "MyReciever" not "MyReiever"
Beside Typo that mentioned in earlier answers and the fact that the receiver class package name should be completely mentioned in receiver tag, I think the problem is that the code in question uses two nested intent filters. I believe this code will work correctly:
<receiver android:name=".MyReciever">
<intent-filter>
<action android:name="android.intent.action.ACTION_USER_PRESENT" />
<action android:name="android.intent.action.ACTION_BOOT_COMPLETED" />
<action android:name="android.intent.action.ACTION_SCREEN_ON" />
</intent-filter>
</receiver>
I can only give you a quick tip as i have gone through that path you are following with much less success. Try to read logcat using java.util.logging so that you will not require permission to read logs. And in log view create listener for the one containing "system disable" as its header. it fires up both at lock and unlock. check for the one that gives access to system.android not the other screen.
Hope it helps. Best of luck