问题
即使在我使用了 START_STICKY 之后,服务也并非始终运行。
有时我没有收到任何拨出电话的 Toast Action,这是否意味着服务会在一段时间后停止?
我的需求
每当用户从手机拨出电话时,应用程序都会显示 Toast。为此,我使用 BroadcastReceiver 来点击调用操作和服务(始终运行 Receiver)。一旦我开始这项 Activity ,它就会在拨出电话时开始显示 toast ..但并非总是如此。
完整代码如下-
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();
}
}
}
最佳答案
你在这里得到了错误的方法,将一个简单的想法(如果正确完成会起作用)与更复杂的想法(不起作用)混合在一起。
请记住:服务不是“始终运行”的组件,即使在使用 START_STICKY 时也是如此。
如果 Android 系统在其他地方需要内存,它会毫不犹豫地终止您的服务。 START_STICKY 仅表示 Android 系统将在可能的情况下重新启动您的服务,并按指定调用 onStartCommand in the documentation .
如果您需要一项服务以真正坚持下去,那么您必须使用 foreground service .但这会对 UI(烦人的通知图标总是显示)和电池生命周期产生影响,您在这里不需要这样做。
现在这是魔术:您的应用程序不需要运行您的 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();
}
}
没有 Activity (除了在 Android 6+ 上请求 PROCESS_OUTGOING_CALLS 权限),没有服务,什么都没有。简单且省电!
关于android - 即使在我使用了 START_STICKY 之后,服务也不总是运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35647788/