2016-06-10 63 views
4

我試圖做一個後臺服務,即使應用程序關閉也能運行。此服務應該偵聽Firebase更改,並根據觸發器啓動應用程序。我不知道我是否缺少代碼的東西或者甚至還沒有接近正確的答案,但這裏是我的代碼:如何在Android中使用Firebase EventListener作爲後臺服務?

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

}

這是清單:

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

編輯:我加入MainActivity.class一個行開始

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    startService(new Intent(this, FireBaseService.class)); 
} 
+0

在應用程序標記內添加您的服務 – Shubhank

+0

我做了,但沒有起作用 – MuhammadNe

+0

如果您的服務正在啓動並且代碼正在其中執行,請進行調試。 – Shubhank

回答

1

我編輯的A中的服務pplication如下:

  1. 的服務類擴展活動和不服務
  2. 我添加應用程序標記內清單中的服務直接作爲以下內容:

機器人:名稱=」 FireBaseService 「

  1. 沒有必要從主要活動開始服務。

編輯清單:

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

0

你想要什麼,它只是startForeground你可以做到這一點。出於安全原因,用戶應該知道背景中正在運行的東西。

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

我測試了這個解決方案在應用程序中退出,而當手機在睡覺,它巧妙地工作。當我從任務管理器關閉應用程序時,服務沒有被破壞,而是被重新創建並繼續接收遠程更改。

希望它有幫助。

注意:根據Firebase數據庫中的實際更改,我的回調最多可能需要5分鐘才能觸發。