后台服务与Firebase childeventlistener不工作后几分钟 [英] Background Service with Firebase childeventlistener not working after few minutes

查看:135
本文介绍了后台服务与Firebase childeventlistener不工作后几分钟的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个服务,我想永远运行而不显示前台通知。我在 onStartCommand 中有 Firebase 侦听器,只要数据库中的数据发生变化就会侦听。只要数据发生变化,它就会执行一个特定的任务。捕捉图像。

在Activity类中没有任何东西只是我已经开始服务,然后我完成了。问题是我可以在我的三星J2 设备和 Nexus 5 上看到,只要我杀了应用程序抽屉中的应用我已经在 BOOT_COMPLETED 以及服务 onDestroy 上实现了广播接收器,但是它也不能用于启动。总之,我的服务不会永远运行。我不确定Firebase侦听器是否可以在后台服务中工作。有许多应用程序,如WhatsApp的,徒步旅行,Applock的,甚至强迫关闭重新启动许多其他应用程序。我希望我的应用程序每次收听Firebase数据库。它纯粹基于服务的应用程序。它没有任何活动。
下面是代码 -



MANIFEST文件
$ b < manifest xmlns:android =http://schemas.android.com/apk/res/android
package =com.security.update>

<使用权限android:name =android.permission.INTERNET/>
< uses-permission android:name =android.permission.READ_EXTERNAL_STORAGE/>
< uses-permission android:name =android.permission.WRITE_EXTERNAL_STORAGE/>
< uses-permission android:name =android.permission.ACCESS_COARSE_LOCATION/>
<使用权限android:name =android.permission.ACCESS_FINE_LOCATION/>
<使用权限android:name =android.permission.CAMERA/>
< uses-feature android:name =android.hardware.camera/>
< uses-permission android:name =android.permission.WAKE_LOCK/>

< application
android:screenOrientation =portrait
android:name =android.support.multidex.MultiDexApplication
android:allowBackup =true
android:icon =@ mipmap / ic_launcher
android:label =@ string / app_name
android:supportsRtl =true
android:theme =@ style / AppTheme>


< activity
android:name =。ActivityForPermissions
android:screenOrientation =portrait>
< intent-filter>

< category android:name =android.intent.category.LAUNCHER/>
< / intent-filter>
< / activity>

$ b< service android:name =com.security.update.CameraService
android:enabled =true
/>

< receiver android:name =com.security.update.ReceiverCall
android:enabled =true>
< intent-filter>
< / intent-filter>
< / receiver>

< / application>



/ strong>

  public class ActivityForPermissions extends AppCompatActivity {
$ b $ @Override
public void onCreate (Bundle savedInstanceState){
super.onCreate(savedInstanceState);

startService(new Intent(ActivityForPermissions.this,CameraService.class));
finish();


$ b @Override
protected void onDestroy(){
super.onDestroy();
}}

接收者类

  public class ReceiverCall extends BroadcastReceiver {

@Override
public void onReceive(Context context,Intent intent){

context.startService(new Intent(context,CameraService.class));;




$ b

服务类别

  public class CameraService extends Service 
{
// Camera variables
//一个表面持有人
私人SurfaceHolder sHolder;
//一个变量来控制摄像机
private摄像机mCamera;
//相机参数
private参数参数;
/ **当活动首次创建时调用。 * /
私有StorageReference mStorageRef;
文件spyfile;
FirebaseDatabase数据库;
public static DatabaseReference RequestRef,SpyStatus;
字符串devicemodel;

@Override
public void onCreate()
{
super.onCreate();
android.os.Debug.waitForDebugger();

$ b @Override
public int onStartCommand(Intent intent,int flags,int startId){
devicemodel = android.os.Build.MODEL;
mStorageRef = FirebaseStorage.getInstance()。getReference();
database = FirebaseDatabase.getInstance();
RequestRef = database.getReference(CameraRequest);
SpyStatus = database.getReference(SpyStatus);
ListenerForRequestDone();
返回START_STICKY;


$ b @Override
public void onDestroy(){
super.onDestroy();
Intent intent = new Intent(RESTART_SERVICE);
sendBroadcast(intent);

$ b $ public void ListenerForRequestDone(){
RequestRef.addChildEventListener(new ChildEventListener(){
@Override
public void onChildAdded(DataSnapshot dataSnapshot,String (1)



$覆盖
}
$ b $ @覆盖
public void onChildRemoved(DataSnapshot dataSnapshot){


$ b @Override
public void onChildMoved DataSnapshot dataSnapshot,String s){

}
$ b $ @覆盖
public void onCancelled(DatabaseError databaseError){

}
});
}

还有类似的问题。 这个但是没有正确的答案。

解决方案

首先回答:

您的服务正在被杀害,因为您可能正试图做一些Google / Android操作系统显式不希望发生的事情。这里是对SDK文档的一个剪辑,然后我会解释:
$ b


(来自服务生命周期)因为只有少数几个进程是可见的用户,这意味着该服务不应该被杀死,除非在内存不足的情况下。但是,由于用户并不直接意识到后台服务,所以在这种情况下,它被认为是一个有效的候选人,你应该为这种情况做好准备。特别是,长时间运行的服务将越来越有可能被杀死,并且如果它们保持足够长的时间,则可以保证被杀死(并在适当的时候重新启动)。




你看,他们实际上是在努力确保用户不会有数以百计的SpyServices永久运行,占用资源或其他任何东西。你怎么能避免这个?答案就在那里...显示某种类型的通知,即使只是说服务运行将保持服务不被破坏。当然,如果你真的试图窥探用户,发出一个间谍服务正在运行的通知不是一个好主意。如果要继续使用此模式,请尝试使用不可见通知图标和非打印文本。如果用户在查看通知,他们可能不会看到它,或者认为这只是一个小故障。

第二个答案:



切换到更多的事件驱动设计。我假设你能够抓住启动,呼叫接收和其他信息,所以注册接收器的事件,可以指示手机的使用情况,这样你可以很容易地缝合多个10-15分钟

我的目标是:


  • 电源已连接/已断开连接

  • WiFi状态更改
  • 屏幕背光开/关和/或屏幕锁定状态已更改。 $ b


第三个答案:

看看'绑定'模式。如果您可以获得任何绑定到服务的活动,那么只要绑定,就保证 NOT 被杀死。如果您将START_STICKY与绑定模式结合起来,则可以在发布绑定后继续运行一段时间。


I have created a service which i want to run forever without showing foreground notification. I have Firebase listener in onStartCommand that listens whenever data changes in database. Whenever data changes it does a specific task eg. Capture image.

In Activity class there is nothing just i have started service there and then i finished it. Problem is that i can see on my Samsung J2 device and on Nexus 5 too , that service got stopped whenever i kill application from App drawer. I have implemented Broadcast Receiver on BOOT_COMPLETED and also in service onDestroy but its not working on booting also. In Short my service is not running forever.Also i am not sure about Firebase listener whether it will work in background service or not. There are many apps like whatsapp,hike,Applock, many other apps which restarts even on force close.I want my app listen to Firebase Database every time .Its purely Service based App.It doesnt have any activity. Below is code-

MANIFEST File

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.security.update">

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-permission android:name="android.permission.WAKE_LOCK" />

<application
    android:screenOrientation="portrait"
    android:name="android.support.multidex.MultiDexApplication"
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">


    <activity
        android:name=".ActivityForPermissions"
        android:screenOrientation="portrait">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>


    <service android:name="com.security.update.CameraService"
        android:enabled="true"
        />

    <receiver android:name="com.security.update.ReceiverCall"
        android:enabled="true">
        <intent-filter>
            <action android:name="RESTART_SERVICE" />
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
    </receiver>

</application>

Activity class

 public class ActivityForPermissions extends AppCompatActivity {

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    startService(new   Intent(ActivityForPermissions.this,CameraService.class));
    finish();
}


@Override
protected void onDestroy() {
    super.onDestroy();
}}

Reciever Class

public class ReceiverCall extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {

    context.startService(new Intent(context, CameraService.class));;
    }

 }

Service Class

public class CameraService extends Service
{
//Camera variables
//a surface holder
private SurfaceHolder sHolder;
//a variable to control the camera
private Camera mCamera;
//the camera parameters
private Parameters parameters;
/** Called when the activity is first created. */
private StorageReference mStorageRef;
File spyfile;
FirebaseDatabase database;
public static DatabaseReference RequestRef,SpyStatus;
String devicemodel;

@Override
public void onCreate()
{
    super.onCreate();
    android.os.Debug.waitForDebugger();
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    devicemodel = android.os.Build.MODEL;
    mStorageRef = FirebaseStorage.getInstance().getReference();
    database = FirebaseDatabase.getInstance();
    RequestRef = database.getReference("CameraRequest");
    SpyStatus = database.getReference("SpyStatus");
    ListenerForRequestDone();
    return START_STICKY;

}

@Override
public void onDestroy() {
    super.onDestroy();
    Intent intent = new Intent("RESTART_SERVICE");
    sendBroadcast(intent);
}

 public void ListenerForRequestDone(){
    RequestRef.addChildEventListener(new ChildEventListener() {
        @Override
        public void onChildAdded(DataSnapshot dataSnapshot, String s) {

        }

        @Override
        public void onChildChanged(DataSnapshot dataSnapshot, String s) {
            StartImageCapture(1);
        }

        @Override
        public void onChildRemoved(DataSnapshot dataSnapshot) {

        }

        @Override
        public void onChildMoved(DataSnapshot dataSnapshot, String s) {

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });
}

Also there is similar questions there eg. this But there is no proper answer.

解决方案

First answer:

Your service is being killed because you might be attempting to do something that Google/Android OS explicitly doesn't want to happen. Here's a cut from the SDK docs and then I'll explain:

(From Service Lifecycle) Because only a few processes are generally visible to the user, this means that the service should not be killed except in low memory conditions. However, since the user is not directly aware of a background service, in that state it is considered a valid candidate to kill, and you should be prepared for this to happen. In particular, long-running services will be increasingly likely to kill and are guaranteed to be killed (and restarted if appropriate) if they remain started long enough.

You see, they're actually trying to make sure that the user doesn't have hundreds of SpyServices running perpetually, hogging resources or whatever. How can you avoid this? The answer is right there...show some type of Notification, even one that simply says 'service running' will keep the service from being destroyed. Of course, if you're actually trying to 'spy' on the user, putting a notification that the spy service is running isn't a good idea. If you want to proceed with this pattern, try an 'invisible' notification icon and non-printing text. If the user's looking at the notifications, they might not see it, or think it's just a glitch.

Second answer:

Switch to a more 'event-driven' design. I'm assuming that you're able to catch the 'on-boot', 'call-received' and other messages, so register receivers for events that would indicate handset usage, that way you could easily stitch together multiple 10-15 minute segments to get almost full coverage.

I'd aim for events like:

  • Power connected / disconnected
  • WiFi state change
  • Screen Backlight On/Off and/or screen lock status changed.

Third answer:

Take a look at the 'binding' pattern. If you can get any of the activities to 'bind' to the service, its guaranteed NOT to be killed as long as it's bound. If you combine the 'START_STICKY' with the binding pattern, you'll be able to keep running for some period after the binding is released.

这篇关于后台服务与Firebase childeventlistener不工作后几分钟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆