6

Tworzę aplikację, która uruchamia działanie, gdy tylko użytkownik naciśnie przycisk zasilania 3 razy. Po pewnych badaniach dowiedziałem się, że aby to zrobić, najpierw musisz utworzyć usługę, która uruchamia odbiornik, aby sprawdzić stan włączenia/wyłączenia ekranu.Jak utrzymać działanie usługi w tle

Zasadniczo chcę, aby to działało, nawet gdy aplikacja jest zamknięta. Powinien rozpocząć inną aktywność, gdy tylko przycisk zasilania zostanie naciśnięty 3 lub więcej razy.

Jeśli znasz rozwiązanie, podaj pełny kod lub link do odpowiedzi.

jakoś udało się napisać ten kod, ale nie działa:

UpdateService.java

Jest to klasa usługa użyłem:

import android.app.Service; 
import android.content.BroadcastReceiver; 
import android.content.Intent; 
import android.content.IntentFilter; 
import android.os.IBinder; 
import android.util.Log; 
import android.widget.Toast; 

public class UpdateService extends Service { 

    BroadcastReceiver mReceiver; 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
    // register receiver that handles screen on and screen off logic 
     IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON); 
     filter.addAction(Intent.ACTION_SCREEN_OFF); 
     mReceiver = new MyReceiver(); 
     registerReceiver(mReceiver, filter); 
    } 

    @Override 
    public void onDestroy() { 

     unregisterReceiver(mReceiver); 
     Log.i("onDestroy Reciever", "Called"); 

     super.onDestroy(); 
    } 

    @Override 
    public void onStart(Intent intent, int startId) { 
     boolean screenOn = intent.getBooleanExtra("screen_state", false); 
     if (!screenOn) { 
     Log.i("screenON", "Called"); 
     Toast.makeText(getApplicationContext(), "Awake", Toast.LENGTH_LONG) 
      .show(); 
     } else { 
     Log.i("screenOFF", "Called"); 
     Toast.makeText(getApplicationContext(), "Sleep", 
    Toast.LENGTH_LONG) 
    .show(); 
     } 
} 

@Override 
public IBinder onBind(Intent intent) { 
// TODO Auto-generated method stub 
return null; 
} 
} 

MyReceiver.java

import android.content.BroadcastReceiver; 
import android.content.Context; 
import android.content.Intent; 

public class MyReceiver extends BroadcastReceiver { 
private boolean screenOff; 

@Override 
public void onReceive(Context context, Intent intent) { 
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) { 
    screenOff = true; 
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) { 
    screenOff = false; 
} 
Intent i = new Intent(context, UpdateService.class); 
i.putExtra("screen_state", screenOff); 
context.startService(i); 
} 
} 

mainfest.xml

<receiver android:name=".MyReceiver"> 
<intent-filter> 
<action android:name="android.intent.action.SCREEN_OFF"/> 
<action android:name="android.intent.action.SCREEN_ON"/> 
</intent-filter> 
</receiver> 
<service android:name=".UpdateService" /> 

Należy również wspomnieć, czy muszę w pliku lub aktywności, do której należy przekierować, cokolwiek dodać.

Użyłem tych uprawnień:

<uses-permission android:name="com.android.alarm.permission.SET_ALARM" /> 
<uses-permission android:name="android.permission.VIBRATE" /> 
<uses-permission android:name="android.permission.READ_CONTACTS" /> 
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> 
<uses-permission android:name="android.permission.WAKE_LOCK" /> 
<uses-permission android:name="android.permission.INTERNET" /> 
<uses-permission android:name="android.permission.SEND_SMS" /> 
<uses-permission android:name="android.permission.RECEIVE_SMS" /> 
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> 
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> 
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> 
+0

Czy to jest prawidłowy sposób czy muszę użyć innej metody –

+2

Proszę o pomoc nie mogę zmusić go do pracy ichecked usługami tła ale updateservice nie jest wyświetlany –

Odpowiedz

0

Nie masz całkowitą kod, aby wiedzieć na pewno, ale pozwól mi zgaduje:

że nie wdrożenia aplikacji lub aktywny Tak?

Myślę, że potrzebujesz przynajmniej jednego z nich, aby zarejestrować odbiornik w onCreate() wywołania zwrotne onResume(), po prostu stwierdzając, że odbiorca w manifeście MOGA NIE działa.

I debugowanie w środowisku Eclipse lub jakimkolwiek innym IDE z integracją z Androidem może być bardzo pomocne, ponieważ pokazuje procesy aplikacji i możesz być pewien, czy są one rozwijane, czy nie. Trochę debugowania powie ci, czy twój odbiornik działa poprawnie.

Jeśli chcesz udostępnić więcej kodu, możemy oczywiście przedyskutować dalej.

+0

co sugerujesz powinienem zrobić –

+0

Podłączyć kod w zaćmieniu i debugowania odbiornika ypur? Jeśli nie masz szczęścia, spróbuj zarejestrować programistycznie program w środowisku wykonawczym za pomocą aplikacji lub działania? –

0

Spróbuj tego?

MyService 
public class MyService extends Service { 
    @Override 
    public void onCreate() { 
     super.onCreate(); 

     ... 

     if (!registered) { 
      MyReceiver mybroadcast = new MyReceiver() { 
      registerReceiver(mybroadcast, new IntentFilter(Intent.ACTION_SCREEN_ON)); 
      registerReceiver(mybroadcast, new IntentFilter(Intent.ACTION_SCREEN_OFF)); 
     } 
    } 
} 

MyReceiver 
public class MyReceiver extends BroadcastReceiver { 
    @Override 
    public void onReceive(Context context, Intent intent) { 
     ... 
    } 
} 

BootStartUpReciever 
public class BootStartUpReciever extends BroadcastReceiver { 
    @Override 
    public void onReceive(Context context, Intent intent) { 
     // Start Service On Boot Start Up 
     Intent service = new Intent(context, MyService.class); 
     context.startService(service); 
    } 
} 



Manifest 

<service android:name="my.package.MyService" /> 
<receiver 
    android:name="my.package.BootStartUpReciever" android:enabled="true" android:exported="true" > 
    <intent-filter> 
     <action android:name="android.intent.action.BOOT_COMPLETED" /> 
     <category android:name="android.intent.category.LAUNCHER" /> 
    </intent-filter> 
</receiver> 
+0

pokazuje błędy w pliku MySevice –

+0

Błąd składniowy lub tokken, niewłaściwie umieszczony konstruktor, również trzeba dodać metodę wiązania –

+2

Podałem minimalne kody. Widzisz ...? To powinno zostać zastąpione przez twoje kody logiczne. – twb

0

Myślę, że nie ma potrzeby, aby klasa serwisowa spełniała Twoje wymagania. Ponieważ rozpoczniesz działanie po wywołaniu ekranu z działania. Prosimy o zapoznanie się z poniższą implementacją i podzielenie się przemyśleniami.

//Application class. 
    public class MyApplication extends Application { 
     static String TAG = "MyApplication"; 
     @Override 
     public void onCreate() { 
      super.onCreate(); 

      IntentFilter intentFilter = new IntentFilter(Intent.ACTION_SCREEN_ON); 
      intentFilter.addAction(Intent.ACTION_SCREEN_OFF); 
      registerReceiver(new BroadcastReceiver() { 
       @Override 
       public void onReceive(Context context, Intent intent) { 
        // screen off 
        if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) { 
         Log.d(TAG, Intent.ACTION_SCREEN_OFF); 
         //screen on 
        } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) { 
         Log.d(TAG, Intent.ACTION_SCREEN_ON); 
         // To open your main activity. 
         Intent i = new Intent(); 
         i.setClass(context, MainActivity.class); 
         i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
         i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
         context.startActivity(i); 
        } 
       } 
      }, intentFilter); 
     } 

    } 

    // Manifest.xml 

    <?xml version="1.0" encoding="utf-8"?> 
    <manifest xmlns:android="http://schemas.android.com/apk/res/android" 
     package="com.hopabit.wakeup" 
     android:versionCode="1" 
     android:versionName="1.0" > 

     <uses-sdk 
      android:minSdkVersion="8" 
      android:targetSdkVersion="19" /> 

     <application 
      android:name=".MyApplication" 
      android:allowBackup="true" 
      android:icon="@drawable/ic_launcher" 
      android:label="@string/app_name" 
      android:theme="@style/AppTheme" > 
      <activity 
       android:name="com.hopabit.wakeup.MainActivity" 
       android:label="@string/app_name" > 
       <intent-filter> 
        <action android:name="android.intent.action.MAIN" /> 

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

    </manifest> 
0

Aby utrzymać działanie usługi, należy wprowadzić wątek. Upewnij się, że service jest w dodatkowym wątku, ponieważ sama usługa nie jest dodatkowym procesem ani wątkiem. Można to zrobić, na przykład za pomocą Handler.

HandlerThread thread = new HandlerThread(SERVICE_THREAD_NAME); 
thread.start(); 
handlerThreadId = thread.getId(); 
serviceLooper = thread.getLooper(); 
serviceHandler = new ServiceHandler(serviceLooper); 
0

Widziałem twój kod. Jesteś bardzo blisko rozwiązania.

zarejestrować swój szeroki odbiornik oddanych na oba wydarzenia ekran wyłączony, a także ekran na środku onCreate() z was Aktywny

if (!registered) { 
      MyReceiver mybroadcast = new MyReceiver() { 
      registerReceiver(mybroadcast, new IntentFilter(Intent.ACTION_SCREEN_ON)); 
      registerReceiver(mybroadcast, new IntentFilter(Intent.ACTION_SCREEN_OFF)); 
} 

Utrzymanie licznika int w udostępnionym preferencji lub gdziekolwiek indziej, zainicjowany go z 0 w pierwszym i przyrostu że licznik w onReceive():

public class MyReceiver extends BroadcastReceiver { 
private boolean screenOff; 

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

int counter = get counter value from shared preference. 

if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) { 
    screenOff = true; 
    //increment the counter++ 

} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) { 
    screenOff = false; 
    //increment the counter++ 
} 

if(counter>3){ 
Intent i = new Intent(context, UpdateService.class); 
i.putExtra("screen_state", screenOff); 
context.startService(i); 
} 
} 
} 
0

Myślę, że potrzebujesz użyć IntentService.

powiem wam dlaczego:

usługi są uruchomione na wątku UI (nawet gdy są na tle), więc jest to lepsze dla interakcji z UI, ale z drugiej strony, nie powinny one być działa przez długi czas, jak chcesz. Poza tym IntentService działają na innym wątku, więc lepiej jest używać ich do zadań w tle, które są dłuższe.

Co należy zrobić, to zaoszczędzić na pamięci (za pomocą obiektu aplikacji) lub innym Singleton razy na ekranie status włączenia/wyłączenia.

Jeśli potrzebujesz więcej pomocy, po prostu daj mi znać

Powiązane problemy