Как использовать службу для отслеживания изменения ориентации в Android

Я пишу виджет, который будет отображать таймер обратного отсчета. У меня виджет работает так, как я хочу, пока я не переверну телефон с альбомной на портретную. Мой виджет не обновляется и переходит в исходное состояние при запуске виджета, пока мой повторяющийся сигнал тревоги не вызовет onupdate. Я хотел бы вызвать onupdate вручную, как только ориентация изменится, чтобы обновить мой виджет. Я некоторое время изучал это и обнаружил, что мне нужно использовать службу, которая будет отслеживать изменения ориентации и вызывать мой onupdate для мой виджет.

Моя проблема в том, что я не могу найти прямого ответа на вопрос, как использовать службу для отслеживания изменений. Я видел, что с помощью действия я могу добавить android:configChanges="orientation|keyboardHidden" в манифест действия и использовать onConfigurationChanged, но могу ли я сделать это за услугу. Если да, то как? Есть ли лучший способ отслеживать изменение ориентации? Я также читал в Интернете, что сервис - не лучший способ сделать это.

Я видел учебные пособия по созданию прослушивателей ориентации, но они, похоже, используют устаревшие вызовы функций.

Заранее спасибо


person Dysen    schedule 07.01.2011    source источник
comment
Вы когда-нибудь находили хорошее решение для этого?   -  person Patrick    schedule 05.06.2013


Ответы (4)


У меня работает Service#onConfigurationChanged(Configuration newConfig). Нет необходимости регистрировать приемники для моего мнения. Я также не добавлял никаких фильтров в AndroidManifest. Я что-то упустил в обсуждении, так как никто не предложил это решение? Моя служба работает на переднем плане.

Просто поместите в свой сервис:

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    //Your handling
}
person OneWorld    schedule 25.02.2015
comment
Да, это работает и намного проще, чем регистрация для широковещательных намерений! - person Flyview; 04.03.2016
comment
Для меня этот метод вызывается, когда устройство поворачивается в альбомную ориентацию И когда я выхожу из приложения из альбомной ориентации. Когда я выхожу из приложения из портрета, onConfigurationChanged() не вызывается, только onUnbind(). @Flyview Вы знаете, почему это происходит? - person Nikola; 13.07.2021
comment
@Nikola Возможно, потому что экран возвращается к портретной ориентации, когда ваше приложение закрывается? - person Flyview; 14.07.2021
comment
@Flyview Возможно, но не уверен в решении. Это не изменение ориентации самого приложения, а устройство (например, домашний экран) является портретным. onUnbind() не вызывается дважды. Таким образом, в основном это одно и то же событие для фактической развязки и развязки ориентации. У вас есть предложение о том, как различить эти два события в этом случае? - person Nikola; 15.07.2021
comment
Я запутался. Вызывается ли onConfigurationChanged дважды при выходе из ландшафта или onUnbind? - person Flyview; 19.07.2021

Пожалуйста, найдите ниже пример, который делает то, что вы просите, надеюсь, что это поможет.

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

а вот и класс 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");
                }
            }
        }
    };
}

и вот часть определения 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>
person beerstorm    schedule 12.02.2011
comment
Проблема в том, что это будет работать только в том случае, если приложение поддерживает вращение. Так что если ваш лаунчер не поддерживает поворот в альбомную ориентацию, из сервиса он работать не будет. Мое предположение состояло бы в том, чтобы использовать датчики, чтобы получить это, но я не уверен, как. - person Archimedes Trajano; 10.02.2012
comment
@WareNinja: вышеприведенное не работает, если пользователь вручную изменил ориентацию, нажав кнопку «Автоповорот» на панели уведомлений. - person ChuongPham; 12.08.2012
comment
@ChuongPham: автоматическое вращение и изменение ориентации вручную? не могли бы вы объяснить больше, это сбивает с толку то, что вы пытались сказать? - person xmen; 19.09.2014

Вы можете создать BroadcastReceiver, который прослушивает Intent.ACTION_CONFIGURATION_CHANGED (android.intent.action.CONFIGURATION_CHANGED)

Обратите внимание, что он говорит:

Вы не можете получить это через компоненты, объявленные в манифестах, только явно зарегистрировавшись для этого с помощью Context.registerReceiver().

Это означает, что вы не можете зарегистрировать получателя в файле манифеста. Вам нужно будет зарегистрировать его в коде.

затем получите конфигурацию и проверьте, какова ориентация, как заявил Флоерн.

person Ryan Conrad    schedule 07.01.2011
comment
Возможно ли Intent.ACTION_CONFIGURATION_CHANGED для appwidgetprovider, поскольку это модифицированный широковещательный приемник? Я предполагаю, что нет. Когда я создаю широковещательный приемник, мне нужно его где-то запускать или он будет запускаться автоматически при запуске моего виджета? - person Dysen; 07.01.2011
comment
Наконец-то я понял, как реализовать то, о чем вы говорите. Мой следующий вопрос: зачем мне регистрировать приемник в сервисе? не выйдет ли служба после регистрации? Могу ли я зарегистрировать Receiver в активности widgetconfiguration? Должен ли объект, зарегистрировавший широковещательный приемник, оставаться в памяти, чтобы он работал? - person Dysen; 10.01.2011
comment
@Dysen, можете ли вы предоставить пример кода? Я попытался реализовать вышеуказанную вещь, но она не работает в эмуляторе Android. - person Raghav Satyadev; 17.11.2020

Я предлагаю вам использовать объект OrientationEventListener. Он делает именно то, что вы ищете, и он не устарел. Он существует с уровня API 3.

person monchote    schedule 02.07.2012
comment
OrientationEventListener не работает, если пользователь вручную изменил ориентацию, нажав кнопку автоматического поворота на панели уведомлений, и положил телефон на поверхность. Это будет работать только в том случае, если пользователь возьмет свой телефон и переместит/повернет его. - person ChuongPham; 12.08.2012