片段上的Sensormanager(如果可见则添加;如果不可见则删除)

时间:2013-09-27 09:40:34

标签: java android android-activity fragment sensormanager

我希望在片段上有一个sensormanager,它只在片段处于活动状态时才有效。如果用户更改了片段,则应删除侦听器。

添加和删除侦听器非常简单。当片段出现/消失时,我不知道片段端有任何监听器/功能。还有一个问题是,在几乎所有函数上,this.getActivity()都返回了一个空指针。

2 个答案:

答案 0 :(得分:1)

这是我的解决方案。我试图将它从我的片段中删除。如果有任何错误/语法问题,请告诉我。

public class MyFragment extends Fragment implements SensorEventListener {
    private SensorManager mSensorManager;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mSensorManager = (SensorManager) this.getActivity().getSystemService(Activity.SENSOR_SERVICE);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.mylayout, container, false);

        return rootView;
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        float x = event.values[0], y = event.values[1];
    }

    @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { }

    @Override
    public void setMenuVisibility(boolean menuVisible) {
        super.setMenuVisibility(menuVisible);

        // First starts (gets called before everything else)
        if(mSensorManager == null) {
            return;
        }

        if(menuVisible) {
            this.registerSensorListener();
        } else {
            this.unregisterSensorListener();
        }   
    }

    @Override
    public void onStart() {
        super.onStart();

        if(this.getUserVisibleHint()) {
            this.registerSensorListener();
        }
    }

    @Override
    public void onStop() {
        super.onStop();
        this.unregisterSensorListener();
    }

    private void registerSensorListener() {
        mSensorManager.registerListener(this, mSensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER).get(0), SensorManager.SENSOR_DELAY_FASTEST);
    }

    private void unregisterSensorListener() {
        mSensorManager.unregisterListener(this);
    }
}

答案 1 :(得分:0)

在片段中保留Activity的引用以处理nullpointerexception。

以下是片段的示例。

public class YourFragment extends Fragment {

    private Activity mActivity;

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        mActivity = activity;
    }

    @Override
    public void onResume() {
        super.onResume();
        // BIND sensor here with mActivity, 
        // could also be done in other fragment lifecycle events, 
        // depends on how you handle configChanges

    }

    @Override
    public void onPause() {
        super.onPause();
        // UNBIND sensor here from mActivity, 
        // could also be done in other fragment lifecycle events, 
        // depends on how you handle configChanges
    }

}

调试该代码确定是否应该在那里或在另一种方法中处理绑定,例如onCreate片段。我没有为您的目的测试此代码。

编辑: 这确实在下面评论了一个脏修复,在某些情况下很容易解决为异常。我只想展示如何使用片段生命周期方法来绑定和取消绑定传感器以及对活动的引用。我目前正在学习片段很长一段时间但仍然没有彻底理解它们。我建议你看一下Fragment的来源和其他相关组件。这是片段被彻底记录的唯一地方,因此我认为参考文献不是那么解释。

有关空值活动的一些选项:

  • 如果您想完全确定getActivity不返回null,您应该等待onActivityCreated被调用。此方法告诉片段其活动具有 完成了自己的Activity.onCreate()。在此之后,getActivity()将不会返回null,直到FragmentManager调用initState()。

     // Called by the fragment manager once this fragment has been removed,
     // so that we don't have any left-over state if the application decides
     // to re-use the instance.  This only clears state that the framework
     // internally manages, not things the application sets.
    
    void initState() {
        mIndex = -1;
        mWho = null;
        mAdded = false;
        mRemoving = false;
        mResumed = false;
        mFromLayout = false;
        mInLayout = false;
        mRestored = false;
        mBackStackNesting = 0;
        mFragmentManager = null;
        mActivity = null;
        mFragmentId = 0;
        mContainerId = 0;
        mTag = null;
        mHidden = false;
        mDetached = false;
        mRetaining = false;
        mLoaderManager = null;
        mLoadersStarted = false;
        mCheckedForLoaderManager = false;
    }
    
  • 在调用getActivity之前,您始终可以通过调用isAdded()方法检查活动是否为null。如下所示,此方法检查mActivity是否为空。 (可选)您可以使用Handler.postDelayed创建递归函数,该函数尝试在intervalls中返回非null活动(您应该添加最大尝试计数器)。但这也是一个肮脏的伎俩。

    //Return true if the fragment is currently added to its activity.
    
    final public boolean isAdded() {
        return mActivity != null && mAdded;
    }