Android在自定义首选项类中检测关闭事件

时间:2018-09-10 00:02:38

标签: android android-preferences

我有一个偏好类,在其中实现了一些逻辑。我希望能够检测到该偏好设置何时关闭,以便可以断开google API客户端的连接。

我的自定义首选项类。一切正常,但是当我关闭首选项并再次打开它时,它显示出一个错误,即具有该ID的API客户端已经存在。

我的首选项类别代表具有位置自动完成文本编辑器的整个首选项屏幕。

preferences.xml

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory
    android:title="Notifications"
    android:key="pref_key_storage_settings">
    <SwitchPreference
        android:key="pref_enable_notifications"
        android:title="News notifications"
        android:defaultValue="true" />
    <EditTextPreference
        android:key="pref_confirms_needed"
        android:digits="0123456789"
        android:inputType="number"
        android:title="@string/pref_confirmsNeeded"
        android:defaultValue="0"
        android:dialogMessage="Enter minimum number of confirms news should have for you to be notified about it."
        android:summary="You will be notified only for news that have higher number of confirms than the number you set here." />
    <Preference
        android:key="pref_location_screen"
        android:persistent="false"
        android:title="Notification range" />
</PreferenceCategory>
</PreferenceScreen>

为了保持简单,我没有显示任何代码。如果您需要它,请告诉我!

编辑

我添加了代码

LocationPreference.xml

public class LocationPreference extends Preference implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
    private static final String TAG = "LocationPreference";
    private Context mContext;
    private PlaceAutocompleteAdapter mLocationAutocompleteAdapter;
    private GoogleApiClient mGoogleApiClient;
    private static final LatLngBounds LAT_LNG_BOUNDS = new LatLngBounds(
        new LatLng(-40, -168), new LatLng(71, 136));
    private View autocompleteSearch;

    // widgets
    private AutoCompleteTextView mSearchText;

    public LocationPreference(Context context) {
        super(context);
        setLayoutResource(R.layout.location_preference);

        mContext = context;
    }

    public LocationPreference(Context context, AttributeSet attrs)
    {
    super(context, attrs);
        setLayoutResource(R.layout.location_preference);

        mContext = context;
    }

    public LocationPreference(Context context, AttributeSet attrs, int defStyle)     {
        super(context, attrs, defStyle);
        setLayoutResource(R.layout.location_preference);

        mContext = context;
    }


    private void init() {
        if (mGoogleApiClient == null) {
        mGoogleApiClient = new GoogleApiClient
                .Builder(mContext)
                .addApi(Places.GEO_DATA_API)
                .addApi(Places.PLACE_DETECTION_API)
                .enableAutoManage((AppCompatActivity) mContext,this)
                .build();
        }

        mLocationAutocompleteAdapter = new PlaceAutocompleteAdapter(
            mContext, mGoogleApiClient, LAT_LNG_BOUNDS, null);
        mSearchText.setAdapter(mLocationAutocompleteAdapter);

        mSearchText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
            @Override
            public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) {
                if (i == EditorInfo.IME_ACTION_SEARCH
                    || i == EditorInfo.IME_ACTION_DONE
                    || keyEvent.getAction() == keyEvent.ACTION_DOWN
                        || keyEvent.getAction() == keyEvent.KEYCODE_ENTER) {
                    //geoLocate();
                }

                return false;
            }
        });
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
            mGoogleApiClient.stopAutoManage((AppCompatActivity) mContext);
            mGoogleApiClient.disconnect();
        }
    }

    @Override
    protected View onCreateView(ViewGroup parent) {
        super.onCreateView(parent);
        LayoutInflater li = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        if (autocompleteSearch == null) {
            autocompleteSearch = li.inflate(R.layout.location_preference, parent, false);
            mSearchText = autocompleteSearch.findViewById(R.id.location_pref_input);
            mSearchText.setOnItemClickListener(mAutocompleteClickListener);
            init();
        }

        return autocompleteSearch;
    }

    private AdapterView.OnItemClickListener mAutocompleteClickListener = new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
            //hideSoftKeyboard();
            Log.d(TAG, "OnItemClick()");
            final AutocompletePrediction item = mLocationAutocompleteAdapter.getItem(i);
            final String placeId = item.getPlaceId();

            PendingResult<PlaceBuffer> placeResult = Places.GeoDataApi
                   .getPlaceById(mGoogleApiClient, placeId);
            placeResult.setResultCallback(mUpdatePlaceDetailsCallback);
        }
    };



    private ResultCallback<PlaceBuffer> mUpdatePlaceDetailsCallback = new ResultCallback<PlaceBuffer>() {
        @Override
        public void onResult(@NonNull PlaceBuffer places) {
            Log.d(TAG, "onResult()");
            if(!places.getStatus().isSuccess()){
                Log.d(TAG, "onResult: Place query did not complete successfully: " + places.getStatus().toString());
                places.release();
                return;
            }
            final Place place = places.get(0);

                persistString(CommonUtils.latLngToStr(place.getViewport().getCenter().latitude,
                place.getViewport().getCenter().longitude));

            SharedPreferences preferences =     PreferenceManager.getDefaultSharedPreferences(mContext);
            Map<String, ?> allEntries = preferences.getAll();
            for (Map.Entry<String, ?> entry : allEntries.entrySet()) {
                Log.d(TAG, entry.getKey() + ": " + entry.getValue().toString());
            }

            places.release();

        }
    };

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

    }

    @Override
    public void onConnected(@Nullable Bundle bundle) {

    }

    @Override
    public void onConnectionSuspended(int i) {
        Log.i(TAG, "Connection suspended");
        mGoogleApiClient.connect();
    }
}

EDIT2

我认为最好的选择是简单地检查Google Api客户端是否存在。

1 个答案:

答案 0 :(得分:0)

确实需要查看您的代码,并对要执行的操作有更清晰的了解。

但是,如果您要在用户关闭首选项时尝试关闭所有内容(本质上返回到您的应用主屏幕),则可以尝试在 onBackPressed活动Calllback 中断开google API客户端的连接

<罢工>
@Override
public void onBackPressed()
{
    super.onBackPressed();

    // Do your stuff here.
}

实际上,您可以进行更深入的研究,并在onBackPressed之后触发的on Destroy回调中进行操作

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

    // Do your stuff here.
}

哪个应该是返回到您的应用活动之前触发的最后一个回调。 哦,很抱歉,请尝试使用onPrepareForRemoval回调

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

    // Close the google api here.
}

然后,如果这不起作用,请尝试将Google API的关闭/断开连接移至PreferenceActvity onDestroy回调。

我个人建议将代码重构为使用PreferenceFragment而不是Preference。