Servicio de Android para mostrar brindis

Se supone que este código utiliza un servicio para mostrar un mensaje de brindis. No hay errores, pero no muestra el brindis.

actividad principal

public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Intent i= new Intent(this, BackgroundMusic.class); this.startService(i); } } 

Servicio (su llamada música de fondo, pero por ahora se supone que mostrar un mensaje de brindis)

 public class BackgroundMusic extends IntentService { public BackgroundMusic() { super("BackgroundMusic"); } @Override protected void onHandleIntent(Intent intent) { // Normally we would do some work here, like download a file. // For our sample, we just sleep for 5 seconds. Context context = getApplicationContext(); CharSequence text = "Hello toast!"; int duration = Toast.LENGTH_SHORT; Toast toast = Toast.makeText(context, text, duration); toast.show(); } } 

manifiesto

 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.starwars" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="18" /> <application android:allowBackup="true" android:debuggable="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <service android:name=".BackgroundMusic" /> <activity android:name="com.example.starwars.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> <activity android:label="@string/app_name" android:name="BackgroundMusic"/> </application> </manifest> 

Ver esta parte de la documentación

(An IntentService tiene algunas limitaciones:

No puede interactuar directamente con su interfaz de usuario. Para poner sus resultados en la interfaz de usuario, tiene que enviarlos a una actividad.

Necesitas ponerlo en el Thread principal. Vea la respuesta aquí por rony de una manera de hacer eso.

Y de la documentación completa sobre IntentService

Maneja cada intento a su vez usando un hilo de trabajo

Prueba esto:

 Handler handler = new Handler(Looper.getMainLooper()); handler.post(new Runnable() { @Override public void run() { Toast.makeText(TrackerService.this.getApplicationContext(),"Video is playing...",Toast.LENGTH_SHORT).show(); } }); 

Probablemente sea mejor delegar todas las actividades de la GUI (incluyendo tostadas) en la actividad que está utilizando su servicio. Por ejemplo, tengo un servicio enlazado para realizar la captura de ubicación en segundo plano y publicar actualizaciones en la pantalla mientras mi aplicación está visible.

Mi aplicación implementa una interfaz sencilla:

 public interface ICapture { void update(Location location); } 

Y mi clase def se ve así:

 public class MyActivity extends Activity implements ICapture { ... 

Aquí está el material para manejar el servicio enlazado:

 private CaptureService captureService; private ServiceConnection captureServiceConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { CaptureService.MyLocalBinder binder = (CaptureService.MyLocalBinder) service; captureService = binder.getService(); captureService.setOwner(ICapture.this); } public void onServiceDisconnected(ComponentName arg0) { } }; 

Lo único que aquí no es estándar es la línea

 captureService.setOwner(ICapture.this); 

Que proporciona al servicio una referencia a la implementación de la aplicación de ICapture. Consulte a continuación para saber cómo se utiliza.

Inicie el servicio en onCreate ():

  Intent intent = new Intent(this, CaptureService.class); startService(intent); bindService(intent, captureServiceConnection, Context.BIND_AUTO_CREATE); 

Y utilizo estos métodos para informar al servicio cuando la aplicación es visible y capaz de satisfacer las solicitudes de GUI:

 @Override public void onPause() { super.onPause(); if (captureService != null) { captureService.setOwner(null); } } @Override public void onResume() { super.onResume(); if (captureService != null) { captureService.setOwner(this); } } 

El servicio se ve así:

 package *****; import android.app.Service; import android.content.Intent; import android.location.Location; import android.os.Binder; import android.os.Bundle; import android.os.IBinder; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.GooglePlayServicesUtil; import com.google.android.gms.common.api.GoogleApiClient; import com.google.android.gms.location.LocationRequest; import com.google.android.gms.location.LocationServices; public class CaptureService extends Service implements com.google.android.gms.location.LocationListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener { private static final long UPDATE_INTERVAL = 1000 * 10; private static final long FASTEST_INTERVAL = 1000 * 5; private final IBinder myBinder = new MyLocalBinder(); private GoogleApiClient mGoogleApiClient; private LocationRequest mLocationRequest; private ICapture owner; @Override public void onCreate() { if (isGooglePlayServicesAvailable()) { mGoogleApiClient = new GoogleApiClient.Builder(this) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .addApi(LocationServices.API) .build(); mLocationRequest = new LocationRequest(); mLocationRequest.setInterval(UPDATE_INTERVAL); mLocationRequest.setFastestInterval(FASTEST_INTERVAL); mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); mGoogleApiClient.connect(); } } @Override public void onConnected(Bundle bundle) { LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this); } @Override public void onConnectionSuspended(int i) { } @Override public void onConnectionFailed(ConnectionResult connectionResult) { } /************************************************************************** * The binder that returns the service activity. */ public class MyLocalBinder extends Binder { public CaptureService getService() { return CaptureService.this; } } @Override public IBinder onBind(Intent arg0) { return myBinder; } /************************************************************************** * Bound methods. * * Set the owner, to be notified when the position changes. * * @param owner */ public void setOwner(ICapture owner) { this.owner = owner; } /************************************************************************** * Start the service and keep it running when the phone is idle. */ @Override public int onStartCommand(Intent intent, int flags, int startId) { return START_STICKY; } /** * Callback when the location changes. Inform the owner. * * @param location */ @Override public void onLocationChanged(Location location) { if (owner != null) { owner.update(location); } } private boolean isGooglePlayServicesAvailable() { int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this); if (ConnectionResult.SUCCESS == status) { return true; } else { return false; } } } 

Todo esto es bastante estándar código que puedes encontrar en otro lugar. Lo principal es que cuando se produce una actualización de ubicación el código llama a la aplicación a través de su interfaz ICapture implementada, pero sólo si la aplicación está visible. La implementación de onPause () y onResume () en la aplicación asegura que el servicio sepa cuándo la aplicación puede aceptar llamadas.

Para hacer una ventana emergente de tostadas, agregue otro método a la interfaz de ICapture y aplíquelo en la aplicación. Su servicio puede entonces llamarlo en cualquier momento que sepa que la pantalla puede aceptarlo. De hecho, las ventanas emergentes de tostadas seguirán apareciendo aunque la aplicación no esté en primer plano, pero creo que se bloquean cuando la pantalla se inactiva, lo que a su vez bloquea el servicio. Por lo tanto, es mejor enviarlos sólo cuando la aplicación esté en primer plano.

  • ¿Por qué no se inicia el servicio después de BOOT_COMPLETED?
  • AlarmManager no se repite
  • ¿Cuándo y por qué se requiere PARTIAL_WAKE_LOCK?
  • Opcionalmente, iniciar actividades y utilizar notificaciones de servicios en Android. Sólo lanzar o notificar si una determinada aplicación está presente
  • Android: comprueba si mi servicio se está ejecutando en segundo plano
  • Una forma correcta de depurar un servicio en Android Studio?
  • Comprobación de la conexión a Internet con el servicio en android
  • ¿Cómo iniciar un servicio Android desde una actividad y detener el servicio en otra actividad?
  • Cómo forzar el onServiceDisconnected () obtener llamado?
  • Android AlarmManager a veces tarde
  • Cómo mantener mi servicio de aplicación sigue funcionando incluso si la aplicación está cerrada desde el administrador de tareas en MI teléfono
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.