如何在Fire中使用Firebase EventListener作为后台服务?

时间:2016-06-10 15:20:59

标签: android service firebase firebase-realtime-database

我正在尝试创建一个即使应用程序关闭也会运行的后台服务。此服务应该监听Firebase更改,并根据触发器启动应用程序。我不知道我是否遗漏了代码中的某些内容,或者甚至没有找到正确的答案,但这是我的代码:

from django.contrib.auth import login as auth_login

# Then use auth_login(user) in your code

}

这就是明白:

public class FireBaseService extends Service {

private HashMap<String, String> fireBaseBattery;

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

    fireBaseBattery = new HashMap<>();
    final Firebase firebaseRef_Battery = new Firebase("the url i want to take data from");

    firebaseRef_Battery.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            if (dataSnapshot.getValue() != null) {
                fireBaseBattery = (HashMap<String, String>) dataSnapshot.getValue();
                String battery = (String) fireBaseBattery.get("battery");
                int battery_int = Integer.parseInt(battery);

                System.out.println("SERVICE FIREBASE : " + battery);
                if (battery_int <= 10) {
                    Intent intent = new Intent(getApplicationContext(), MainActivity.class);
                    startActivity(intent);
                }
            }
        }

        @Override
        public void onCancelled(FirebaseError firebaseError) {

        }
    });
}

@Nullable
@Override
public IBinder onBind(Intent intent) {
    return null;
}

编辑:我在MainActivity.class中添加了一行来启动服务

    <uses-permission android:name="android.permission.READ_SMS" />
    <application
        android:name=".ParseApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

<service android:enabled="true"
        android:name=".FireBaseService">
    </service>
        <activity
            android:name=".Launcher"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

</manifest>

3 个答案:

答案 0 :(得分:1)

我按照以下方式编辑了应用程序:

  1. Service类扩展了Activity而不是Service
  2. 我直接在应用程序代码中添加了服务清单,如下所示:
  3.   

    机器人:名称=&#34; .FireBaseService&#34;

    1. 无需从主要活动启动服务。
    2. Edited Manifest:

       <uses-permission android:name="android.permission.READ_SMS" />
      <application
          android:name=".FireBaseService"
          android:allowBackup="true"
          android:icon="@mipmap/ic_launcher"
          android:label="@string/app_name"
          android:supportsRtl="true"
          android:theme="@style/AppTheme">
      
          <activity
              android:name=".Launcher"
              android:label="@string/app_name"
              android:theme="@style/AppTheme.NoActionBar">
              <intent-filter>
                  <action android:name="android.intent.action.MAIN" />
      
                  <category android:name="android.intent.category.LAUNCHER" />
              </intent-filter>
          </activity>
      

答案 1 :(得分:0)

你想要什么,它只是startForeground你可以做到的。出于安全原因,用户应该知道某些内容正在后台运行。

答案 2 :(得分:0)

我想我已经破解了它。

我使用子事件监听器粘性服务解决了这个问题。这是怎么回事:

我首先在数据存储类中添加一个子事件侦听器:

class DataStore {

        private static DataStore sDataStore;
        private List<EmergencyZoneEventListener> mEmergencyZoneEventListeners = null;

        static DataStore get() {
            if (sDataStore == null) {
                sDataStore = new DataStore();
            }

            return sDataStore;
        }

        void addEmergencyZoneEventListener(EmergencyZoneEventListener emergencyZoneEventListener) {
            if (emergencyZoneEventListener != null && !sDataStore.mEmergencyZoneEventListeners.contains(emergencyZoneEventListener)) {
                sDataStore.mEmergencyZoneEventListeners.add(emergencyZoneEventListener);
            }
        }

        void removeEmergencyZoneEventListener(EmergencyZoneEventListener emergencyZoneEventListener) {
            mEmergencyZoneEventListeners.remove(emergencyZoneEventListener);
        }

        DataStore() {
            FirebaseDatabase.getInstance().getReference("/emergencyZones/").
                    addChildEventListener(new ChildEventListener() {
                        @Override
                        public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                            emergencyZoneAddedOrChangedRemotely(dataSnapshot);
                        }

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

                        @Override
                        public void onChildRemoved(DataSnapshot dataSnapshot) {
                            emergencyZoneRemovedRemotely(dataSnapshot);
                        }

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

                        @Override
                        public void onCancelled(DatabaseError databaseError) {
                            Log.w(TAG, "onCancelled: " + databaseError.getMessage() + ": "
                                    + databaseError.getDetails());
                        }
                    });
        }
    }

以下是 emergencyZoneAddedOrChangedRemotely 中发生的事情:

private void emergencyZoneAddedOrChangedRemotely(DataSnapshot dataSnapshot) {
        EmergencyZone ez = dataSnapshot.getValue(EmergencyZone.class);
        if (ez == null || ez.getKey() == null) {
            Log.w(TAG, "emergencyZoneAddedRemotely: EmergencyZone or getKey is null");
            return;
        }

        for (EmergencyZoneEventListener listener : mEmergencyZoneEventListeners) {
            listener.onEmergencyZoneAdded(ez);
        }
    }

此处,每次Firebase发生更改,Firebase触发我的ChildEventListener时,我依次使用 listener.onEmergencyZondeAdded 触发本地连接的侦听器。

最后是粘性服务:

public class NotificationService extends Service {

    private static final String TAG = "NotificationService";

    private DataStore mDataStore;
    private DataStore.EmergencyZoneEventListener mEmergencyZoneEventListener = new DataStore.EmergencyZoneEventListener() {
        @Override
        public void onEmergencyZoneAdded(EmergencyZone emergencyZone) {
            Log.i(TAG, "onEmergencyZoneAdded: " + emergencyZone.getKey());
        }

        @Override
        public void onEmergencyZoneChanged(EmergencyZone emergencyZone) {
            Log.i(TAG, "onEmergencyZoneChanged: " + emergencyZone.getKey());
        }

        @Override
        public void onEmergencyZoneRemoved(EmergencyZone emergencyZone) { }
    };

    public static Intent getIntent(Context packageContext) {
        return new Intent(packageContext, NotificationService.class);
    }

    @Override
    public void onCreate() {
        Log.i(TAG, "onCreate: NotificationService is being created...");
        mDataStore = DataStore.get(this);
        mDataStore.addEmergencyZoneEventListener(mEmergencyZoneEventListener);
        QueryPreferences.setIsNotificationsOn(this, true);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i(TAG, "onStartCommand: Received start id " + startId + ": " + intent);
        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        Log.i(TAG, "onDestroy: NotificationService is being destroyed...");
        mDataStore.removeEmergencyZoneEventListener(mEmergencyZoneEventListener);
        QueryPreferences.setIsNotificationsOn(this, false);
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}

我在退出应用程序并且手机处于睡眠状态时测试了此解决方案,并且工作正常。当我从任务管理器关闭应用程序时,服务没有被销毁但是被重新创建并继续接收远程更改。

希望它有所帮助。

注意:我的回调最多可能需要5分钟才能在firebase数据库中进行实际更改后被解雇。