即使我使用了START_STICKY,服务也不会一直运行。
有时候我没有得到任何Togoing Action for Outgoing,这是否意味着服务在一段时间后停止了?
只要用户通过电话拨打电话,应用就会显示Toast。为此,我使用BroadcastReceiver来点击调用操作和服务(始终运行Receiver)。一旦我开始这项活动,它就会在拨打电话时开始显示吐司..但不是总是。
以下是完整的代码 -
MainActivity.class
public class MainActivity extends Activity
{
CallNotifierService m_service;
boolean isBound = false;
private ServiceConnection m_serviceConnection = new ServiceConnection()
{
@Override
public void onServiceConnected(ComponentName className, IBinder service)
{
m_service = ((CallNotifierService.MyBinder)service).getService();
Toast.makeText(MainActivity.this, "Service Connected", Toast.LENGTH_LONG).show();
isBound = true;
Intent intent = new Intent(MainActivity.this, CallNotifierService.class);
startService(intent);
}
@Override
public void onServiceDisconnected(ComponentName className)
{
m_service = null;
isBound = false;
}
};
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent(this, CallNotifierService.class);
bindService(intent, m_serviceConnection, Context.BIND_AUTO_CREATE);
}
.
.
.
}
CallNotifierService.class
public class CallNotifierService extends Service
{
private final IBinder myBinder = new MyBinder();
private static final String ACTION_OUTGOING_CALL = "android.intent.action.NEW_OUTGOING_CALL";
private CallBr br_call;
@Override
public IBinder onBind(Intent arg0)
{
return myBinder;
}
@Override
public void onDestroy()
{
Log.d("service", "destroy");
this.unregisterReceiver(this.br_call);
Toast.makeText(CallNotifierService.this, "Receiver Un-Registered", Toast.LENGTH_LONG).show();
super.onDestroy();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
final IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_OUTGOING_CALL);
this.br_call = new CallBr();
this.registerReceiver(this.br_call, filter);
Toast.makeText(CallNotifierService.this, "onStartCommand Called", Toast.LENGTH_LONG).show();
return START_STICKY;
}
public class MyBinder extends Binder
{
CallNotifierService getService()
{
return CallNotifierService.this;
}
}
public class CallBr extends BroadcastReceiver
{
public CallBr() {}
@Override
public void onReceive(Context context, Intent intent)
{
Toast.makeText(context, "Action:"+intent.getAction(), Toast.LENGTH_LONG).show();
}
}
}
答案 0 :(得分:5)
你在这里得到了错误的方法,通过混合一个简单的想法(如果做得正确可以工作)和更复杂的想法(这是行不通的)。
请记住:服务不是"始终在运行"组件,即使使用START_STICKY。
Android系统会毫不犹豫地杀死你的服务,如果它需要其他地方的内存。 START_STICKY仅表示Android系统会尽可能重新启动您的服务,并按指定的in the documentation调用onStartCommand。
如果您需要真正的服务,那么您必须使用foreground service。但它会对用户界面造成影响(恼人的通知图标总是显示)和电池寿命,你不需要这里。
现在,这是一个神奇的伎俩:您的应用无需为了您的BroadcastReceiver工作而运行。您需要做的就是使用正确的intent-filter在AndroidManifest.xml中注册它:
<receiver android:name=".broadcastreceivers.CallBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL"/>
</intent-filter>
</receiver>
(同时确保您的应用具有所需的权限,即PROCESS_OUTGOING_CALLS。)
然后您在代码中所需要的只是:
public class CallBroadcastReceiver extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent)
{
Toast.makeText(context, "Action: " + intent.getAction(), Toast.LENGTH_LONG).show();
}
}
没有活动(除了要求Android 6+上的PROCESS_OUTGOING_CALLS权限),没有服务,没有。简单且省电!
答案 1 :(得分:0)
服务会重新创建,而不是未重新启动。 如果您覆盖onCreate并执行Log.d或Toast,您将看到在应用程序销毁后将被调用。
因此,在重新创建它后使其保持运行的诀窍是在onCreate方法上执行代码,并使用onStartCommand仅返回START_STICKY。