現在、Truecallerのようなコールブロッカーアプリケーションを開発しています。
必要なもの
最近のアプリリストから自分のアプリが削除されていても、着信を検出したい。
Manifest.xmlコード
<receiver Android:name=".PhoneStateReceiver">
<intent-filter>
<action Android:name="Android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
私の放送受信機コード
@Override
public void onReceive(Context context, Intent intent) {
//my call blocking code
}
私の問題
BroadcastReceiverは、最近のアプリリストから削除したかのようにバックグラウンドで動作しません。
ここに私の完全なマニフェストコード
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:Android="http://schemas.Android.com/apk/res/Android"
package="ranjith.callblocker">
<uses-permission Android:name="Android.permission.READ_PHONE_STATE" />
<uses-permission Android:name="Android.permission.CALL_PHONE" />
<uses-permission Android:name="Android.permission.READ_CONTACTS" />
<uses-permission Android:name="Android.permission.GET_TASKS" />
<application
Android:allowBackup="true"
Android:enabled="true"
Android:icon="@mipmap/ic_launcher"
Android:label="@string/app_name"
Android:supportsRtl="true"
Android:theme="@style/AppTheme">
<receiver
Android:name=".PhoneStateReceiver"
Android:enabled="true"
Android:exported="true"
Android:process=":anotherProcess">
<intent-filter Android:priority="1000">
<action Android:name="Android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
<activity
Android:name=".MainActivity"
Android:label="@string/app_name"
Android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action Android:name="Android.intent.action.MAIN" />
<category Android:name="Android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
サービスなどを利用する必要がありますか?
更新:
Surajの回答で、レシーバーでこのタグを試しました
Android:enabled="true"
Android:exported="true"
Android:process=":anotherProcess"
kitKatで動作します。ただし、Lollipopでは動作しません。
更新された質問:
放送受信機を存続させることができない場合アプリが閉じていても着信を検出するにはどうすればよいですか?
誰もが詳細な答えを与えます。
Service
を作成し、マニフェストに登録する必要があります。その後、マニフェストではなく、サービス内にBroadcastReceiver
を登録する必要があります。
アプリが最近から削除されても、Service
は停止しないため、レシーバーも引き続き機能します。アプリが最近から削除されると、Service#onTaskRemoved
を介してコールバックを受け取ることもあります。
他のいくつかのケースも処理する必要がありますが、Service
を停止できる場合。
1つのケースは、システムのメモリが不足しているときにAndroidがサービスを停止できる場合、onStartCommand
メソッドからSTART_STICKY
を返すことで修正できます。
他のケースは、デバイスが再起動されたとき、これを修正するためにmnifestでACTION_BOOT_COMPLETED
のブロードキャストレシーバーを登録する必要があります。 onReceive
メソッドでサービスを再起動できます。
以下のサンプルコードがお役に立てば幸いです-
private BroadcastReceiver mReceiver;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Log.v(LOG_TAG, "worked");
}
};
registerReceiver(mReceiver,
new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
return START_STICKY;
}
@Override
public void onDestroy() {
unregisterReceiver(mReceiver);
super.onDestroy()
}
これがコードですそれは私にとってはうまくいきます:
マニフェストで権限を追加します。<uses-permission Android:name="Android.permission.READ_PHONE_STATE" />
次のステップでは、アプリの起動時にService
startを作成します(おそらくMainActivity
)。このコードをonCreate
のメソッドService
で呼び出します。
コード
((TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE)).listen(new PhoneStateListener(new PhoneStateListener.PhoneCallListener() {
@Override
public void PhoneCall() {
// Do something
}
@Override
public void PhoneOff() {
// Do something
}
@Override
public void MissCall() {
// Do something
}
}), PhoneStateListener.LISTEN_CALL_STATE);
PhoneStateListener.Java
import Android.telephony.TelephonyManager;
/**
* PhoneStateListener.
*
* @author DaoLQ
*/
public class PhoneStateListener extends Android.telephony.PhoneStateListener {
public interface PhoneCallListener {
void PhoneCall();
void PhoneOff();
void MissCall();
}
private PhoneCallListener mPhoneCallListener;
private boolean ring = false;
private boolean callReceived = false;
public PhoneStateListener(PhoneCallListener listener) {
mPhoneCallListener = listener;
}
@Override
public void onCallStateChanged(int state, String incomingNumber) {
super.onCallStateChanged(state, incomingNumber);
switch (state) {
case TelephonyManager.CALL_STATE_IDLE:
mPhoneCallListener.PhoneOff();
if (ring && !callReceived) {
mPhoneCallListener.MissCall();
}
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
// CALL_STATE_OFFHOOK;
callReceived = true;
mPhoneCallListener.PhoneCall();
break;
case TelephonyManager.CALL_STATE_RINGING:
ring = true;
mPhoneCallListener.PhoneCall();
break;
default:
break;
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:Android="http://schemas.Android.com/apk/res/Android"
package="com.Android.phonestatelistener">
<uses-permission Android:name="Android.permission.RECEIVE_SMS" />
<uses-permission Android:name="Android.permission.READ_PHONE_STATE"/>
<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.Android.receiver.PhoneStateListener" Android:exported="true" >
<intent-filter >
<action Android:name="Android.intent.action.PHONE_STATE"/>
<action Android:name="Android.intent.action.NEW_OUTGOING_CALL"/>
<action Android:name="Android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
</application>
public class PhoneStateListener extends BroadcastReceiver {
public static String TAG="PhoneStateListener";
public static String ACTION_PHONE_STATE = "Android.intent.action.PHONE_STATE";
public static String ACTION_OUTGOING_CALL = "Android.intent.action.NEW_OUTGOING_CALL";
public static String ACTION_SMS_RECEIVED = "Android.provider.Telephony.SMS_RECEIVED";
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(ACTION_PHONE_STATE)) {
String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
Toast.makeText(context, "Incoming call", Toast.LENGTH_SHORT).show();
Log.d(TAG, "Incoming call");
}
} else if (intent.getAction().equals(ACTION_OUTGOING_CALL)) {
Toast.makeText(context, "Outgoing call", Toast.LENGTH_SHORT).show();
Log.d(TAG, "Outgoing call");
} else if (intent.getAction().equals(ACTION_SMS_RECEIVED)) {
Toast.makeText(context, "Incoming message", Toast.LENGTH_SHORT).show();
Log.d(TAG, "Incoming message");
}
}
}
これを試して 。アプリケーションを強制的に閉じるまで機能します
アクティビティのonCreate()でブロードキャストレシーバーを内部に登録してみてください。