如何使用服务来监控 Android 中的方向变化

Posted

技术标签:

【中文标题】如何使用服务来监控 Android 中的方向变化【英文标题】:How do I use a service to monitor Orientation change in Android 【发布时间】:2011-06-05 05:46:00 【问题描述】:

我正在编写一个显示倒数计时器的小部件。我让小部件按我想要的方式工作,直到我将手机从横向翻转到纵向。我的小部件不会更新并在小部件开始时进入其初始状态,直到我的重复警报调用 onupdate。我想在方向更改后手动调用 onupdate 来更新我的小部件我的小部件。

我的问题是我找不到关于如何使用服务来监控更改的直接答案。我已经看到,通过一个活动,我可以将 android:configChanges="orientation|keyboardHidden" 添加到活动的清单中并使用 onConfigurationChanged,但我可以这样做吗为服务。如果有怎么办?有没有更好的方法来监控方向变化?我还在互联网上读到,服务也不是最好的方法。

我看过创建方向侦听器的教程,但它们似乎使用了已弃用的函数调用。

提前致谢

【问题讨论】:

你有没有找到一个好的解决方案? 【参考方案1】:

Service#onConfigurationChanged(Configuration newConfig) 为我工作。无需为我的意见注册接收者。我也没有向 AndroidManifest 添加任何过滤器。由于没有人建议此解决方案,我是否错过了讨论中的某些内容?我的服务正在前台运行。

只需放在您的服务中:

@Override
public void onConfigurationChanged(Configuration newConfig) 
    super.onConfigurationChanged(newConfig);
    //Your handling

【讨论】:

是的,这很有效,而且比注册广播意图要简单得多! 对我来说,当设备旋转到横向以及从横向退出应用程序时,会调用此方法。当我从肖像退出应用程序时,不会调用 onConfigurationChanged(),只是调用 onUnbind()。 @Flyview 你知道为什么会这样吗? @Nikola 可能是因为您的应用退出时屏幕恢复为纵向? @Flyview 可能,但不确定解决方案。这不是应用程序本身的方向更改,而是设备(例如主屏幕)是纵向的。 onUnbind() 不会被调用两次。所以基本上它是实际解除绑定和方向解除绑定的相同事件。您对在这种情况下如何区分这两个事件有什么建议吗? 我很困惑。在横向退出时,onConfigurationChanged 会被调用两次,还是 onUnbind?【参考方案2】:

请在下面找到符合您要求的示例,希望对您有所帮助。

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>

【讨论】:

问题是这只有在应用程序支持旋转时才有效。因此,如果您的启动器不支持旋转到横向,它将无法通过服务运行。我的猜测是使用传感器来获取它,但我不确定如何。 @WareNinja:如果用户通过单击通知栏中的“自动旋转”按钮手动更改方向,上述方法将不起作用。 @ChuongPham:自动旋转和手动改变方向?你能解释一下吗,你想说什么令人困惑?【参考方案3】:

你可以创建一个BroadcastReceiver 来监听Intent.ACTION_CONFIGURATION_CHANGED (android.intent.action.CONFIGURATION_CHANGED)

请注意,它确实说:

您无法通过 仅在清单中声明的​​组件 通过显式注册 Context.registerReceiver()。

这意味着您无法在清单文件中注册您的接收者。您必须在代码中注册它。

然后获取配置并检查 Floern 所说的方向。

【讨论】:

是否可以 Intent.ACTION_CONFIGURATION_CHANGED 到 appwidgetprovider,因为它是一个修改后的广播接收器?我猜不是。当我创建广播接收器时,我需要在某个地方启动它还是会在我的小部件启动时自动启动? 我终于弄清楚了如何实现你所说的。我的下一个问题是为什么我要在服务中注册接收器?注册后服务不会退出吗?我可以在小部件配置活动中注册接收器吗?注册广播接收器的实体是否必须留在内存中才能运行? @Dysen 你能提供一些示例代码吗?我试图实现上述的东西,但它在 Android Emulator 中不起作用【参考方案4】:

我建议您使用OrientationEventListener 对象。它完全符合您的要求,并且没有被弃用。它从 API 级别 3 开始就存在。

【讨论】:

如果用户通过单击通知栏中的“自动旋转”按钮手动更改方向并将手机平放在表面上,OrientationEventListener 不起作用。只有当用户拿起他的手机并移动/旋转它时它才会起作用。

以上是关于如何使用服务来监控 Android 中的方向变化的主要内容,如果未能解决你的问题,请参考以下文章

Android开发之Sensors与摇一摇

如何监控android网络请求

Martrix源码分析系列-如何监控帧率变化

Android屏幕旋转不生效

iOS - 如何处理自定义表格单元格中的方向变化

Sencha Touch V2 中如何处理方向变化