I have made small app for Android mobile.
In one situation I am not getting any solution.
Actually my app has small functionality for calling to customer.
So after call ended I need that event of which last number will dialed or which app is runs.
AndroidManifest:
<receiver android:name=".PhoneStateBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE">
</action></intent-filter>
</receiver>
Add following permission:
<uses-permission android:name="android.permission.READ_PHONE_STATE">
</uses-permission>
PhoneStateBroadcastReceiver.java (refactored the code a bit)
package com.mobisys.android.salesbooster;
import com.mobisys.android.salesbooster.database.HelperDatabase;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.provider.ContactsContract.PhoneLookup;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
public class PhoneStateBroadcastReceiver extends BroadcastReceiver {
private static final String TAG = "PhoneStateBroadcastReceiver";
Context mContext;
String incoming_number;
private int prev_state;
#Override
public void onReceive(Context context, Intent intent) {
TelephonyManager telephony = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE); //TelephonyManager object
CustomPhoneStateListener customPhoneListener = new CustomPhoneStateListener();
telephony.listen(customPhoneListener, PhoneStateListener.LISTEN_CALL_STATE); //Register our listener with TelephonyManager
Bundle bundle = intent.getExtras();
String phoneNr = bundle.getString("incoming_number");
Log.v(TAG, "phoneNr: "+phoneNr);
mContext = context;
}
/* Custom PhoneStateListener */
public class CustomPhoneStateListener extends PhoneStateListener {
private static final String TAG = "CustomPhoneStateListener";
#Override
public void onCallStateChanged(int state, String incomingNumber){
if( incomingNumber != null && incomingNumber.length() > 0 )
incoming_number = incomingNumber;
switch(state){
case TelephonyManager.CALL_STATE_RINGING:
Log.d(TAG, "CALL_STATE_RINGING");
prev_state=state;
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
Log.d(TAG, "CALL_STATE_OFFHOOK");
prev_state=state;
break;
case TelephonyManager.CALL_STATE_IDLE:
Log.d(TAG, "CALL_STATE_IDLE==>"+incoming_number);
if((prev_state == TelephonyManager.CALL_STATE_OFFHOOK)){
prev_state=state;
//Answered Call which is ended
}
if((prev_state == TelephonyManager.CALL_STATE_RINGING)){
prev_state=state;
//Rejected or Missed call
}
break;
}
}
}
}
Read more here, Source : http://mobisys.in/blog/2011/09/is-your-call-ended-on-android-phone/
Related
I've been playing around with some Android recently and have the following setup:
I have app A, which is a service. This has no activity. Here's its manifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.sandbox.sampleservice">
<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.SampleService">
<service
android:name=".DummyService"
android:exported="true"
android:enabled="true">
</service>
</application>
</manifest>
and here's the Java code:
package com.sandbox.sampleservice;
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.util.Log;
public class DummyService extends Service {
private static final String TAG = "DummyService";
static class MessageHandler extends Handler {
#Override
public void handleMessage(Message msg) {
// TODO: sort this later
super.handleMessage(msg);
}
}
Messenger mMessenger = null;
#Override
public IBinder onBind(Intent intent) {
Log.i(TAG, "Binding");
mMessenger = new Messenger(new MessageHandler());
return mMessenger.getBinder();
}
#Override
public boolean onUnbind(Intent intent) {
Log.i(TAG, "No longer bound");
return false;
}
}
I then have an app B with an empty activity which I want to bind to the service in app A. This is it's MainActivity:
package com.sandbox.sampleclient;
import androidx.appcompat.app.AppCompatActivity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "SampleClient";
private ServiceConnection mServiceConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.i(TAG, "Bound");
}
#Override
public void onServiceDisconnected(ComponentName name) {
Log.i(TAG, "Unbound");
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.sandbox.sampleservice", ".DummyService"));
boolean result = this.bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
if (result) {
Toast.makeText(this, "success", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "failed", Toast.LENGTH_SHORT).show();
}
}
}
I'm running on the default emulator that comes with Android Studio - API 30/x86.
I've installed the service using the installDebug Gradle task and can see the app in the Settings. But running app B, the call to bindService() returns false (it shows the failure toast). And I have the following message in logcat:
2021-04-03 20:33:59.743 500-1764/system_process W/ActivityManager: Unable to start service Intent { cmp=com.sandbox.sampleservice/.DummyService } U=0: not found
I've tried a few things - using the app context rather than the activity one when binding, using the fully qualified class name, and more. No change in behaviour, and the error in logcat is always the same.
I am developing an android application related to geofencing and I tried Broadcast receiver to get a notification when entering into geofence and I will work only when the application is running and then I tried Service to get a notification but now no notification is coming when entering into geofence.
Here is the code
**
package com.example.fypautosilenceapp;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
import androidx.annotation.Nullable;
import com.google.android.gms.location.Geofence;
import com.google.android.gms.location.GeofencingEvent;
import java.util.List;
public class GeofenceService extends Service {
private static final String TAG = "GeofenceBroadcastRecive";
AudioManager audioManager;
#Nullable
#Override
public IBinder onBind(Intent intent) {
NotificationHelper notificationHelper=new NotificationHelper(getApplicationContext());
GeofencingEvent geofencingEvent=GeofencingEvent.fromIntent(intent);
if(geofencingEvent.hasError()){
Toast.makeText(getApplicationContext(), "Geofence has error", Toast.LENGTH_SHORT).show();
Log.d(TAG,"OnRecive:Error recive geofence event...");
}
List<Geofence> geofenceslist=geofencingEvent.getTriggeringGeofences();
//Location geofencelocation=geofencingEvent.getTriggeringLocation();
for (Geofence geofence:geofenceslist){
Log.d(TAG,"OnRecive:"+geofence.getRequestId());
}
int transtiontype=geofencingEvent.getGeofenceTransition();
switch (transtiontype){
case Geofence.GEOFENCE_TRANSITION_ENTER:
// Toast.makeText(getApplicationContext(),"Enter geofence",Toast.LENGTH_SHORT).show();
notificationHelper.sendHighPriorityNotification("Enter geofence","",MapsActivity.class);
// audioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
break;
case Geofence.GEOFENCE_TRANSITION_EXIT:
// Toast.makeText(getApplicationContext(),"Exit geofence",Toast.LENGTH_SHORT).show();
notificationHelper.sendHighPriorityNotification("Exit geofence","",MapsActivity.class);
// audioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
break;
case Geofence.GEOFENCE_TRANSITION_DWELL:
// Toast.makeText(getApplicationContext(),"Enter Dwell",Toast.LENGTH_SHORT).show();
notificationHelper.sendHighPriorityNotification("Enter Dewell","",MapsActivity.class);
// audioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
break;
}
return null;
}
}
**
I am creating a app which can detetct incomming sms to android phone but app is not working in background.
Here is my mainactivity.java in which i am asking for the permission from user to allow access to read sms.
package com.example.times;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.widget.Switch;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private static final int READ_SMS_PERMISSION=0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECEIVE_SMS) != PackageManager.PERMISSION_GRANTED)
{
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.RECEIVE_SMS))
{
// do nothing
}
else
{
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECEIVE_SMS}, READ_SMS_PERMISSION);
}
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults)
{
switch(requestCode)
{
case READ_SMS_PERMISSION:
{
if(grantResults.length>0 && grantResults[0]==PackageManager.PERMISSION_GRANTED)
{
Toast.makeText(this, "Thankyou for granting access", Toast.LENGTH_LONG).show();
}
else
{
Toast.makeText(this, "No problem", Toast.LENGTH_LONG).show();
}
}
}
}
}
Here is myreciver.java in which i am detecting incomming sms and making toast of that msg.
When app is opened then it is working properly but when i exit the app it is not detecting any sms.
package com.example.times;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.telephony.SmsMessage;
import android.util.Log;
import android.widget.Toast;
public class MyReceiver extends BroadcastReceiver {
private static final String SMS_RECEIVED="android.provider.Telephony.SMS_RECEIVED";
private static final String TAG="SmsBroadcastReceiver";
String msg, phoneNo ="";
#Override
public void onReceive(Context context, Intent intent) {
// TODO: This method is called when the BroadcastReceiver is receiving
// an Intent broadcast.
// throw new UnsupportedOperationException("Not yet implemented");
Log.i(TAG, "Intent Received: " +intent.getAction());
if (intent.getAction()==SMS_RECEIVED)
{
Bundle dataBundle = intent.getExtras();
if (dataBundle!=null)
{
Object[] mypdu=(Object[])dataBundle.get("pdus");
final SmsMessage[] message = new SmsMessage[mypdu.length];
for (int i =0; i<mypdu.length; i++)
{
if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.M)
{
String format= dataBundle.getString("format");
message[i] = SmsMessage.createFromPdu((byte[])mypdu[i],format);
}
else
{
message[i] = SmsMessage.createFromPdu((byte[]) mypdu[i]);
}
msg =message[i].getMessageBody();
phoneNo= message[i].getOriginatingAddress();
}
Toast.makeText(context, "Message: " +msg +"\nNumber: " +phoneNo, Toast.LENGTH_SHORT).show();
}
}
}
}
Telll me if i am doing something wrong.
Make sure you have these in your Android Mainfest.xml
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
And the following
<receiver
android:name=
"com.example.times.MyReceiver"
android:enabled="true"
android:exported="true">
</receiver>
EDIT
You need an Intent Service to read sms while your app is closed or in background.
Intent Service - Run in Background
Steps:
Create Intent Service
Add it Manifest
Call it from your Broadcast Receiver onReceive() method via Intent
I would like to block call from specific number I tried some solution but I get errors.
I tried this solution but it is not working.
https://stackoverflow.com/a/9904826/1937692
It gives
Can not resolve symbol ITelephony
Project Structure:
http://i.hizliresim.com/P02XOd.png
PhoneCallReceiver:
package com.example.myapplication;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.widget.Toast;
public class PhoneCallReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
TelephonyManager telephony = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
PhoneCallStateListener customPhoneListener = new PhoneCallStateListener(context);
telephony.listen(customPhoneListener, PhoneStateListener.LISTEN_CALL_STATE);
}}
ITelephony.aidl:
package com.android.internal.telephony;
interface ITelephony {
boolean endCall();
void answerRingingCall();
void silenceRinger();
}
PhoneCallStateListener:
package com.example.myapplication;
import java.lang.reflect.Method;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.media.AudioManager;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.widget.Toast;
import com.android.internal.telephony.ITelephony; //Error Line
public class PhoneCallStateListener extends PhoneStateListener {
private Context context;
public PhoneCallStateListener(Context context){
this.context = context;
}
#Override
public void onCallStateChanged(int state, String incomingNumber) {
SharedPreferences prefs=PreferenceManager.getDefaultSharedPreferences(context);
switch (state) {
case TelephonyManager.CALL_STATE_RINGING:
String block_number = prefs.getString("block_number", null);
AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
//Turn ON the mute
audioManager.setStreamMute(AudioManager.STREAM_RING, true);
TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
try {
Toast.makeText(context, "in"+block_number, Toast.LENGTH_LONG).show();
Class clazz = Class.forName(telephonyManager.getClass().getName());
Method method = clazz.getDeclaredMethod("getITelephony");
method.setAccessible(true);
ITelephony telephonyService = (ITelephony) method.invoke(telephonyManager); //Error Line
//Checking incoming call number
System.out.println("Call "+block_number);
if (incomingNumber.equalsIgnoreCase("+91"+block_number)) {
//telephonyService.silenceRinger();//Security exception problem
telephonyService = (ITelephony) method.invoke(telephonyManager);
telephonyService.silenceRinger();
System.out.println(" in "+block_number);
telephonyService.endCall();
}
} catch (Exception e) {
Toast.makeText(context, e.toString(), Toast.LENGTH_LONG).show();
}
//Turn OFF the mute
audioManager.setStreamMute(AudioManager.STREAM_RING, false);
break;
case PhoneStateListener.LISTEN_CALL_STATE:
}
super.onCallStateChanged(state, incomingNumber);
}}
Error - Red Lines:
http://i.hizliresim.com/YD8zQA.png
The interface ITelephony is package-visible and therefore not accessible from outside of the package com.android.internal.telephony.
That's because it is an internal Android API.
you have added ITelephony.AIDL file in your project? and if you have added then your package name must be com/android/internal/telephony/ITelephony.AIDL: for more information Blocking Incoming call. download AIDL file from here
On StackOverflow, I noticed a number of people having trouble catching INSTALL_REFERRER over the years, and a number of bug reports on the Android forum (all closed due to "wrong forum" -- but, I'm not seeing any public issue tracker). I'm wondering if anyone has a way to get INSTALL_REFERRER to work in the current 2014 version of Google Play.
Edit: I did find an issue tracker and created an issue:
https://code.google.com/p/play-games-platform/issues/detail?id=202
Edit 2: (replace com.myapp with the app's name)
Here's what I did for a test of the response. This is the same as on Google's Analytics help docs. This works.
adb shell am broadcast -a com.android.vending.INSTALL_REFERRER -n com.myapp/com.flyingsoftgames.googleplayquery.QueryReceiver --es "referrer" "utm_source=testSource&utm_medium=testMedium&utm_term=testTerm&utm_content=testContent&utm_campaign=testCampaign"``
Here's what I did for a test of the response from Google's Play Store. This is also the same as Google's Analytics help docs, from the link generation utility. (Yes, the keys are different, but that's per the docs, and not what I'm testing -- I just want ANY response, and the docs indicate that referrer should work...) I installed from this rank and ran, listening for QueryReceiver with logcat (adb logcat -s QueryReceiver). This doesn't work.
https://play.google.com/store/apps/details?id=com.myapp&referrer=utm_source%3Dgoogle%26utm_medium%3Dcpc%26utm_term%3Dpodcast%252Bapps%26utm_content%3DdisplayAd1%26utm_campaign%3Dpodcast%252Bgeneralkeywords
Here is my (Cordova plugin) code, which works perfectly when triggering a manual broadcast:
AndroidManifest.xml:
<receiver android:exported="true" android:name="com.flyingsoftgames.googleplayquery.QueryReceiver">
<intent-filter>
<action android:name="com.android.vending.INSTALL_REFERRER" />
</intent-filter>
</receiver>
GooglePlayQuery.java:
package com.flyingsoftgames.googleplayquery;
import com.flyingsoftgames.googleplayquery.QueryReceiver;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaInterface;
import org.apache.cordova.CordovaWebView;
import org.apache.cordova.CordovaPlugin;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.Context;
import android.app.Activity;
import android.content.ComponentName;
import android.content.pm.PackageManager;
import org.json.JSONArray;
import org.json.JSONException;
public class GooglePlayQuery extends CordovaPlugin {
public static CallbackContext queryCallback = null;
public static CordovaInterface cordova = null;
#Override public void initialize (CordovaInterface initCordova, CordovaWebView webView) {
// Create a static cordova reference so that QueryReceiver can access it.
cordova = initCordova;
// Enable the broadcast receiver in case it isn't enabled.
Activity activity = cordova.getActivity ();
ComponentName receiver = new ComponentName (activity, QueryReceiver.class);
PackageManager pm = activity.getPackageManager ();
pm.setComponentEnabledSetting (receiver, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
super.initialize (cordova, webView);
}
public boolean execute (String action, JSONArray inputs, CallbackContext callbackContext) throws JSONException {
if ("getURI".equals(action)) {this.queryCallback = callbackContext;}
return true;
}
}
QueryReceiver.java:
package com.flyingsoftgames.googleplayquery;
import com.flyingsoftgames.googleplayquery.GooglePlayQuery;
import org.apache.cordova.PluginResult;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.app.Activity;
import android.content.ComponentName;
import android.content.pm.PackageManager;
import android.util.Log;
public class QueryReceiver extends BroadcastReceiver {
#Override public void onReceive (Context context, Intent intent) {
if (GooglePlayQuery.queryCallback != null) {
Log.d ("QueryReceiver", intent.toURI());
GooglePlayQuery.queryCallback.sendPluginResult (new PluginResult (PluginResult.Status.OK, intent.toURI()));
}
// Now disable the broadcast receiver since we don't need it anymore.
Activity activity = GooglePlayQuery.cordova.getActivity ();
ComponentName receiver = new ComponentName (activity, QueryReceiver.class);
PackageManager pm = activity.getPackageManager ();
pm.setComponentEnabledSetting (receiver, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
}
}
I believe I finally found the reason that it does not work. There is a silent error where GooglePlayQuery.cordova is null. QueryReceiver.onReceive runs before GooglePlayQuery.initialize, but only in production mode. Insane.
I still need a few hours to test it (as my game is published) to verify, but here's my new code. It's also available at https://github.com/agamemnus/cordova-plugin-google-play-query-receiver.
AndroidManifest.xml:
<receiver android:exported="true" android:name="com.flyingsoftgames.googleplayquery.QueryReceiver">
<intent-filter>
<action android:name="com.android.vending.INSTALL_REFERRER" />
</intent-filter>
</receiver>
GooglePlayQuery.java:
package com.flyingsoftgames.googleplayquery;
import com.flyingsoftgames.googleplayquery.QueryReceiver;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaInterface;
import org.apache.cordova.CordovaWebView;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.PluginResult;
import android.content.Intent;
import android.app.Activity;
import android.content.ComponentName;
import android.content.pm.PackageManager;
import org.json.JSONArray;
import org.json.JSONException;
public class GooglePlayQuery extends CordovaPlugin {
public static CallbackContext queryCallback = null;
public static CordovaInterface cordova = null;
public static String referrer_uri = "";
public static Intent QueryReceiverCachedIntent = null;
#Override public void initialize (CordovaInterface initCordova, CordovaWebView webView) {
// Create a static cordova reference so that QueryReceiver can access it.
cordova = initCordova;
// Enable the broadcast receiver in case it isn't enabled.
Activity activity = cordova.getActivity ();
ComponentName receiver = new ComponentName (activity, QueryReceiver.class);
PackageManager pm = activity.getPackageManager ();
pm.setComponentEnabledSetting (receiver, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
// If the QueryReceiver's onReceive already ran, run the cached data.
if (QueryReceiver.cachedIntent != null) {QueryReceiver.runCachedOnReceive (QueryReceiver.cachedIntent);}
super.initialize (cordova, webView);
}
public boolean execute (String action, JSONArray inputs, CallbackContext callbackContext) throws JSONException {
if ("getURI".equals(action)) {
if (referrer_uri != "") {
callbackContext.sendPluginResult (new PluginResult (PluginResult.Status.OK, referrer_uri));
referrer_uri = "";
return true;
}
this.queryCallback = callbackContext;
}
return true;
}
}
QueryReceiver.java:
package com.flyingsoftgames.googleplayquery;
import com.flyingsoftgames.googleplayquery.GooglePlayQuery;
import org.apache.cordova.PluginResult;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.app.Activity;
import android.content.ComponentName;
import android.content.pm.PackageManager;
import android.util.Log;
public class QueryReceiver extends BroadcastReceiver {
public static Intent cachedIntent = null;
#Override public void onReceive (Context context, Intent intent) {
// If the onReceive occurred before the GooglePlayQuery initialize function ran: cache the intent. Otherwise, run as intended.
if (GooglePlayQuery.cordova == null) {cachedIntent = intent;} else {runCachedOnReceive (intent);}
}
public static void runCachedOnReceive (Intent intent) {
if (cachedIntent != null) cachedIntent = null;
Log.e ("QueryReceiver", intent.toURI());
if (GooglePlayQuery.queryCallback != null) {
GooglePlayQuery.queryCallback.sendPluginResult (new PluginResult (PluginResult.Status.OK, intent.toURI()));
} else {
GooglePlayQuery.referrer_uri = intent.toURI();
}
// Now disable the broadcast receiver since we don't need it anymore.
Activity activity = GooglePlayQuery.cordova.getActivity ();
ComponentName receiver = new ComponentName (activity, QueryReceiver.class);
PackageManager pm = activity.getPackageManager ();
pm.setComponentEnabledSetting (receiver, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
}
}