我已经开发了用于检测呼出和呼入电话的应用程序。我写了“后台呼叫检测服务”。它对于API 23效果很好,但是它的作用远不止于此。协助我清除此错误,请
清单文件
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="in.ds.buttdail.buttdial">
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<uses-permission android:name="android.permission.ANSWER_PHONE_CALLS" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission
android:name="android.permission.MODIFY_PHONE_STATE"
tools:ignore="ProtectedPermissions" />
<application
android:name=".App"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:isolatedProcess="true"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".SplashActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".DialActivity" />
<service
android:name=".ButtDial.CallDetectService"
android:enabled="true"
android:exported="false" />
<activity
android:name=".Utils.IncomingCallActivity"
android:launchMode="singleTask" />
<activity android:name=".Utils.OutGoingCallActivity" />
<receiver
android:name=".ButtDial.PhoneCallReceiver"
android:enabled="true"
android:exported="true"
android:label="RestartServiceWhenStopped"></receiver>
<activity android:name=".ButtDial.CallEndActivity"></activity>
</application>
CallDetect服务
public class CallDetectService extends Service {
private CallHelper callHelper;
public CallDetectService() {
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
callHelper = new CallHelper(this);
int res = super.onStartCommand(intent, flags, startId);
callHelper.start();
return res;
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public void onDestroy() {
super.onDestroy();
sendBroadcast(new Intent("IWillStartAuto"));
// Toast.makeText(this, "Closed", Toast.LENGTH_SHORT).show();
callHelper.stop();
}
@Override
public IBinder onBind(Intent intent) {
// not supporting binding
return null;
}
public class MyBinder extends Binder {
public CallDetectService getService() {
return CallDetectService.this;
}
}
@Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
// sendBroadcast(new Intent("IWillStartAuto"));
}
}
呼叫助手
我已经对此进行了编码,以检测呼入和呼出电话。但是它无法检测到我何时终止应用程序
public class CallHelper {
private final int interval = 5000; // 1 Second
private Handler handler = new Handler();
private Runnable runnable;
private String checkedcall,userChecked;
/**
* Listener to detect incoming calls.
*/
private class CallStateListener extends PhoneStateListener {
@Override
public void onCallStateChanged(int state, String incomingNumber) {
System.out.println("**********Call State is: " + state + "*********");
Var.share = ctx.getSharedPreferences(Var.PERF, MODE_PRIVATE);
String incomings = Var.share.getString(Var.INCOMING, "");
Log.e("incomings", incomings);
if (incomings.equals("incoming")) {
switch (state) {
case TelephonyManager.CALL_STATE_RINGING:
// called when someone is ringing to this phone
System.out.println("**********Inside CAll_STATE_RINGING state - case*********");
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
String date = df.format(Calendar.getInstance().getTime());
String tempData = date + "::" + "Incoming::" + incomingNumber + "\n";
// Toast.makeText(ctx, date + ": " + "Incoming: " + incomingNumber, Toast.LENGTH_LONG).show();
Intent incoming = new Intent(ctx, IncomingCallActivity.class);
incoming.putExtra("mobilenumber", incomingNumber);
incoming.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
ctx.startActivity(incoming);
break;
case 0:
try {
Var.share = ctx.getSharedPreferences(Var.PERF, MODE_PRIVATE);
String Call = Var.share.getString(Var.CALL, "");
//Toast.makeText(ctx, Call, Toast.LENGTH_LONG).show();
if (Call.equals("online")) {
Intent i = new Intent(ctx, CallEndActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
ctx.startActivity(i);
}
} catch (Exception e) {
Log.e("Error", e.getMessage());
}
break;
}
}
}
}
/**
* Broadcast receiver to detect the outgoing calls.
*/
public class OutgoingReceiver extends BroadcastReceiver {
public OutgoingReceiver() {
}
@Override
public void onReceive(Context context, Intent intent) {
String outgng = Var.share.getString(Var.OUTGOING, "");
checkedcall = Var.share.getString(Var.CHECKEDCALL, "");
userChecked = Var.share.getString(Var.USERCHECKED, "");
//context.startService(new Intent(context.getApplicationContext(), CallDetectService.class));
Log.e("outgng", outgng);
if (outgng.equals("outgng") && checkedcall.equals("no")) {
System.out.println("**********Inside BroadcaseReceiver class for detecting outgoing calls*********");
String number = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
//context.startService(new Intent(context, CallDetectService.class));
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
String date = df.format(Calendar.getInstance().getTime());
Log.e("outgng1", checkedcall);
Var.share = ctx.getSharedPreferences(Var.PERF, MODE_PRIVATE);
Var.editor = Var.share.edit();
Var.editor.putString(Var.CHECKEDCALL, "yes");
Var.editor.putString(Var.OUTGOING, "0");
Var.editor.commit();
number = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
setResultData(null);
endCall(ctx);
String tempData = date + "::" + "Outgoing::" + number + "\n";
// Toast.makeText(context, tempData, Toast.LENGTH_SHORT).show();
Intent outcoming = new Intent(ctx, OutGoingCallActivity.class);
outcoming.putExtra("mobilenumber", number);
outcoming.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
ctx.startActivity(outcoming);
}
new Timer().schedule(new TimerTask() {
@Override
public void run() {
Var.share = ctx.getSharedPreferences(Var.PERF, MODE_PRIVATE);
Var.editor = Var.share.edit();
Var.editor.putString(Var.CHECKEDCALL, "no");
Var.editor.putString(Var.OUTGOING, "outgng");
Var.editor.putString(Var.USERCHECKED, "no");
Var.editor.commit();
}
}, 5000);
// logHelper.logTheRecord("callsLog.log", tempData);
}
}
private Context ctx;
private TelephonyManager tm;
private CallStateListener callStateListener;
private OutgoingReceiver outgoingReceiver;
public CallHelper(Context ctx) {
this.ctx = ctx;
callStateListener = new CallStateListener();
outgoingReceiver = new OutgoingReceiver();
}
/**
* Start calls detection.
*/
public void start() {
System.out.println("**********Inside START DETECTING method*********");
tm = (TelephonyManager) ctx.getSystemService(Context.TELEPHONY_SERVICE);
tm.listen(callStateListener, PhoneStateListener.LISTEN_CALL_STATE);
IntentFilter intentFilter = new IntentFilter(Intent.ACTION_NEW_OUTGOING_CALL);
ctx.registerReceiver(outgoingReceiver, intentFilter);
}
/**
* Stop calls detection.
*/
public void stop() {
System.out.println("**********Inside STOP DETECTING method*********");
tm.listen(callStateListener, PhoneStateListener.LISTEN_NONE);
ctx.unregisterReceiver(outgoingReceiver);
}
public void endCall(Context context) {
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
try {
Class c = Class.forName(tm.getClass().getName());
Method m = c.getDeclaredMethod("getITelephony");
m.setAccessible(true);
Object telephonyService = m.invoke(tm);
c = Class.forName(telephonyService.getClass().getName());
m = c.getDeclaredMethod("endCall");
m.setAccessible(true);
m.invoke(telephonyService);
} catch (Exception e) {
e.printStackTrace();
}
}}
答案 0 :(得分:0)
您可以通过对CallDetectService类进行一些更改来实现:
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
callHelper = new CallHelper(this);
int res = super.onStartCommand(intent, flags, startId);
callHelper.start();
return START_STICKY;
}
@Override
public void onTaskRemoved(Intent rootIntent) {
callHelper.start();
}
@Override
public void onDestroy() {
super.onDestroy();
sendBroadcast(new Intent("IWillStartAuto"));
// Toast.makeText(this, "Closed", Toast.LENGTH_SHORT).show();
callHelper.start();
}
答案 1 :(得分:-1)
很明显,谷歌文档指定一旦该进程被杀死,该进程中的所有组件都将被销毁。也许您想尝试多进程以使您的服务在另一个进程中运行。