2011-01-07 16 views
13

? Estoy escribiendo un widget que mostrará un temporizador de cuenta regresiva. Tengo el widget funcionando como quiero hasta que muevo el teléfono de paisaje a retrato. Mi widget no se actualiza y va a su estado inicial al inicio del widget hasta que mi alarma recurrente llame a ondate. Me gustaría llamar a una actualización manualmente una vez que la orientación cambia para actualizar mi widget. He estado investigando esto por un tiempo y descubrí que necesito usar un servicio que supervise los cambios de orientación y llame a mi onupdate para mi widget¿Cómo uso un servicio para supervisar el cambio de orientación en Android

Mi problema es que no puedo encontrar una respuesta directa sobre cómo usar un servicio para controlar el cambio. He visto que con una actividad puedo agregar android: configChanges = "orientation | keyboardHidden" al manifiesto para una actividad y usar onConfigurationChanged, pero puedo hacer esto para un servicio. ¿Si es así, cómo? ¿Hay una mejor manera de monitorear el cambio de orientación? También he leído en Internet que un servicio tampoco es la mejor manera de hacer esto.

He visto tutoriales para crear oyentes de orientación pero parecen usar llamadas a funciones depreciadas.

Gracias de antemano

+0

¿alguna vez encontrar una buena solución para esto? – Patrick

Respuesta

1

Se puede crear un BroadcastReceiver que escucha Intent.ACTION_CONFIGURATION_CHANGED (android.intent.action.CONFIGURATION_CHANGED)

Tenga en cuenta que sí dice:

no se puede recibir este a través de componentes declarados en manifiestos, solo registrándolo explícitamente con Context.registerReceiver().

Lo que significa que no puede registrar su receptor en el archivo de manifiesto. Deberías registrarlo en el código.

luego obtenga la configuración y compruebe cuál es la orientación, como lo indicó Floern.

+0

¿Es posible _Intent.ACTION_CONFIGURATION_CHANGED_ al appwidgetprovider ya que es un receptor de difusión modificado Supongo que no. Cuando creo el receptor de transmisión, ¿tengo que iniciarlo en algún lugar o se iniciará automáticamente cuando comience mi Widget? – Dysen

+0

Finalmente descubrí cómo implementar lo que estás hablando. Mi siguiente pregunta es ¿por qué registraría el receptor en un servicio? ¿No saldría el servicio después de registrarse? ¿Puedo registrar el receptor en la actividad de configuración del widget? ¿La entidad que registró el receptor de la transmisión debe permanecer en la memoria para que se ejecute? – Dysen

13

A continuación, encontrará un ejemplo que hace lo que pide, espero que esto ayude.

public class ScreenOrientationListener extends Activity { 

    private static final String TAG = "ScreenOrientationListener"; 

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

     mContext = this; 

     setContentView(R.layout.main); 

     startService(new Intent(this, MyService.class)); 
    } 
} 

y aquí viene la clase MyService

public class MyService extends Service { 
    private static final String TAG = "MyService"; 

    private static final String BCAST_CONFIGCHANGED = "android.intent.action.CONFIGURATION_CHANGED"; 
    private static Context mContext; 

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

    @Override 
    public void onCreate() { 
     Log.d(TAG, "onCreate()"); 

     mContext = this; 

     IntentFilter filter = new IntentFilter(); 
     filter.addAction(BCAST_CONFIGCHANGED); 
     this.registerReceiver(mBroadcastReceiver, filter); 
    } 

    @Override 
    public void onDestroy() {   
     Log.d(TAG, "onDestroy()"); 
     //Unregister receiver to avoid memory leaks 
     mContext.unregisterReceiver(mBroadcastReceiver); 
    } 

    @Override 
    public void onStart(Intent intent, int startid) { 
     Log.d(TAG, "onStart()"); 
    } 

    public BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { 
     @Override 
     public void onReceive(Context context, Intent myIntent) { 

      if (myIntent.getAction().equals(BCAST_CONFIGCHANGED)) { 

       Log.d(TAG, "received->" + BCAST_CONFIGCHANGED); 


       if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE){ 
        // it's Landscape 
        Log.d(TAG, "LANDSCAPE"); 
       } 
       else { 
        Log.d(TAG, "PORTRAIT"); 
       } 
      } 
     } 
    }; 
} 

y aquí está la parte de definir en el archivo de manifiesto MyService

<!-- Services --> 
     <service android:enabled="true" android:name="com.wareninja.android.external.screenorientationlistener.services.MyService"> 
      <intent-filter> 
       <action android:name="android.intent.action.CONFIGURATION_CHANGED"/> 
      </intent-filter> 
     </service> 
+0

El problema es que esto solo funcionará si la aplicación admite la rotación. Por lo tanto, si su iniciador no admite rotación a horizontal, no funcionará desde un servicio. Mi suposición sería usar los sensores para obtenerlo, pero no estoy seguro de cómo. –

+0

@WareNinja: Lo anterior no funciona si el usuario cambió manualmente la orientación haciendo clic en el botón "Rotación automática" en la barra de notificaciones. – ChuongPham

+0

@ChuongPham: rotación automática y cambiar manualmente la orientación? ¿podría explicar más, es confuso lo que estaba tratando de decir? – xmen

0

Yo sugeriría que utilice un objeto OrientationEventListener. Hace exactamente lo que está buscando y no está en desuso. Ha estado presente desde API nivel 3.

+0

OrientationEventListener no funciona si el usuario cambió manualmente la orientación haciendo clic en el botón "Rotación automática" en la barra de notificaciones y tiene el teléfono plano sobre una superficie. Solo funcionará si el usuario levanta su teléfono y lo mueve/gira. – ChuongPham

20

Service#onConfigurationChanged(Configuration newConfig) funciona para mí. No es necesario registrar receptores para mi opinión. Tampoco agregué ningún filtro a AndroidManifest. ¿Me perdí algo en la discusión ya que nadie sugirió esta solución? Mi servicio se ejecuta en primer plano.

Sólo tiene que colocar en el interior de su servicio:

@Override 
public void onConfigurationChanged(Configuration newConfig) { 
    super.onConfigurationChanged(newConfig); 
    //Your handling 
} 
+1

Sí, esto funciona y es mucho más simple que registrarse para transmitir intenciones! – Flyview

Cuestiones relacionadas