<|start_filename|>library/src/main/java/co/lemonlabs/android/slidingdebugmenu/SlidingDebugMenuModule.java<|end_filename|>
package co.lemonlabs.android.slidingdebugmenu;

import android.content.Context;
import co.lemonlabs.android.slidingdebugmenu.modules.BuildModule;
import co.lemonlabs.android.slidingdebugmenu.modules.LocationModule;
import co.lemonlabs.android.slidingdebugmenu.modules.LogModule;
import co.lemonlabs.android.slidingdebugmenu.modules.MenuModule;
import co.lemonlabs.android.slidingdebugmenu.modules.NetworkModule;
import dagger.Module;
import dagger.Provides;

import java.util.List;

@Module(
    library = true,
    complete = false
)
public class SlidingDebugMenuModule {

    @Provides SlidingDebugMenu provideSlidingDebugMenu(Context context, List<MenuModule> modules) {
        return SlidingDebugMenu.create(context, modules);
    }

    @Provides BuildModule provideBuildModule() {
        return new BuildModule();
    }

    @Provides LocationModule provideLocationModule() {
        return new LocationModule();
    }

    @Provides LogModule provideLogModule() {
        return new LogModule();
    }

    @Provides NetworkModule provideNetworkModule() {
        return new NetworkModule();
    }
}


<|start_filename|>library/src/main/java/co/lemonlabs/android/slidingdebugmenu/modules/LogModule.java<|end_filename|>
/*
 * Copyright (C) 2013 <NAME>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package co.lemonlabs.android.slidingdebugmenu.modules;

import android.content.Context;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;

import co.lemonlabs.android.slidingdebugmenu.R;
import co.lemonlabs.android.slidingdebugmenu.util.Log;
import co.lemonlabs.android.slidingdebugmenu.views.ModuleSpinnerProperty;

/**
 * Module to change Log level during runtime using
 * {@link co.lemonlabs.android.slidingdebugmenu.util.Log}.
 */
public class LogModule extends MenuModule {

    private static final String[] LOG_LEVELS = new String[]{"Verbose", "Debug", "Info", "Warn", "Error", "WTF"};
    private static final String TITLE = "Logging";

    @Override
    public String getTitle() {
        return TITLE;
    }

    @Override
    public View getContent(Context context) {
        LinearLayout v = new LinearLayout(context);
        v.setOrientation(LinearLayout.VERTICAL);

        ModuleSpinnerProperty levelProperty = new ModuleSpinnerProperty(context, R.string.sdm__module_log_level);
        v.addView(levelProperty);

        ArrayAdapter<String> levelAdapter = new ArrayAdapter<>(
                context,
                R.layout.sdm__spinner_dropdown_item,
                LOG_LEVELS
        );

        levelProperty.setSpinnerAdapter(levelAdapter);
        levelProperty.setOnSpinnerItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                // const value for VERBOSE is 2
                Log.LOG_LEVEL = position + 2;
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {
            }
        });


        return v;
    }
}


<|start_filename|>library/src/main/java/co/lemonlabs/android/slidingdebugmenu/views/ModuleSpinnerProperty.java<|end_filename|>
package co.lemonlabs.android.slidingdebugmenu.views;

import android.content.Context;
import android.view.LayoutInflater;
import android.widget.AdapterView;
import android.widget.FrameLayout;
import android.widget.Spinner;
import android.widget.SpinnerAdapter;
import android.widget.TextView;

import co.lemonlabs.android.slidingdebugmenu.R;

/**
 * A ModuleProperty containing a TextView label
 * and a Spinner
 * <p/>
 * Created by balysv on 13/01/14.
 * www.lemonlabs.co
 */
public class ModuleSpinnerProperty extends FrameLayout {

    private TextView mPropertyName;
    private Spinner mPropertySpinner;

    public ModuleSpinnerProperty(Context context, String propertyName) {
        this(context);
        setPropertyName(propertyName);
    }

    public ModuleSpinnerProperty(Context context, int propertyResId) {
        this(context);
        setPropertyName(propertyResId);
    }

    public ModuleSpinnerProperty(Context context) {
        super(context);
        inflate();
    }

    private void inflate() {
        LayoutInflater.from(getContext()).inflate(R.layout.sdm__module_property_spinner, this, true);
        mPropertyName = (TextView) findViewById(R.id.sdm__module_property_name);
        mPropertySpinner = (Spinner) findViewById(R.id.sdm__module_property_spinner);
    }

    /**
     * Set name of property
     *
     * @param name
     */
    public void setPropertyName(String name) {
        mPropertyName.setText(name);
    }

    /**
     * Set name of property
     *
     * @param resId
     */
    public void setPropertyName(int resId) {
        mPropertyName.setText(resId);
    }

    /**
     * Set Adapter for Spinner
     *
     * @param adapter
     */
    public void setSpinnerAdapter(SpinnerAdapter adapter) {
        mPropertySpinner.setAdapter(adapter);
    }

    /**
     * Set Spinner Item Selected callback
     *
     * @param listener
     */
    public void setOnSpinnerItemSelectedListener(AdapterView.OnItemSelectedListener listener) {
        mPropertySpinner.setOnItemSelectedListener(listener);
    }

    /**
     * Get the Spinner associated with this property
     *
     * @return
     */
    public Spinner getPropertySpinner() {
        return mPropertySpinner;
    }
}


<|start_filename|>library/src/main/java/co/lemonlabs/android/slidingdebugmenu/util/Log.java<|end_filename|>
package co.lemonlabs.android.slidingdebugmenu.util;

import org.json.JSONObject;

/**
 * Wrapper of core {@link android.util.Log} functions
 * to allow control using SlidingDebugMenu
 * <p/>
 * Created by balysv on 13/01/14.
 * www.lemonlabs.co
 */
public class Log {

    public static int LOG_LEVEL = 2;

    // VERBOSE

    public static void v(String tag, String message) {
        if (LOG_LEVEL <= android.util.Log.VERBOSE)
            android.util.Log.v(tag, message);
    }

    public static void v(String tag, boolean b) {
        v(tag, String.valueOf(b));
    }

    public static void v(String tag, int i) {
        v(tag, String.valueOf(i));
    }

    public static void v(String tag, JSONObject json) {
        v(tag, json.toString());
    }

    // DEBUG

    public static void d(String tag, String message) {
        if (LOG_LEVEL <= android.util.Log.DEBUG)
            android.util.Log.d(tag, message);
    }

    public static void d(String tag, boolean b) {
        d(tag, String.valueOf(b));
    }

    public static void d(String tag, int i) {
        d(tag, String.valueOf(i));
    }

    public static void d(String tag, JSONObject json) {
        d(tag, json.toString());
    }

    // INFO

    public static void i(String tag, String message) {
        if (LOG_LEVEL <= android.util.Log.INFO)
            android.util.Log.i(tag, message);
    }

    // WARN

    public static void w(String tag, String message) {
        if (LOG_LEVEL <= android.util.Log.WARN)
            android.util.Log.w(tag, message);
    }

    // ERROR
    public static void e(String tag, String message) {
        if (LOG_LEVEL <= android.util.Log.ERROR)
            android.util.Log.e(tag, message);
    }

    public static void e(String tag, String message, Throwable error) {
        if (LOG_LEVEL <= android.util.Log.ERROR)
            android.util.Log.e(tag, message, error);
    }

    public static void e(String tag, JSONObject json) {
        e(tag, json.toString());
    }

    // WTF
    public static void wtf(String tag, String message) {
        if (LOG_LEVEL <= android.util.Log.ASSERT)
            android.util.Log.wtf(tag, message);
    }

    public static void wtf(String tag, String message, Throwable error) {
        if (LOG_LEVEL <= android.util.Log.ASSERT)
            android.util.Log.wtf(tag, message, error);
    }

}


<|start_filename|>library/src/main/java/co/lemonlabs/android/slidingdebugmenu/modules/NetworkModule.java<|end_filename|>
/*
 * Copyright (C) 2014 <NAME>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package co.lemonlabs.android.slidingdebugmenu.modules;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import de.greenrobot.event.EventBus;
import co.lemonlabs.android.slidingdebugmenu.R;
import co.lemonlabs.android.slidingdebugmenu.controllers.NetworkController;
import co.lemonlabs.android.slidingdebugmenu.modules.events.NetworkChangeEvent;
import co.lemonlabs.android.slidingdebugmenu.views.ModuleSimpleProperty;

/**
 * Module that provides an interface allowing to switch
 * and view the state of Wifi, Mobile network and Bluetooth.
 * A manually registered broadcast receiver is used, so be
 * sure to call {@link #onStop() onStop} and {@link #onStart() onStart}.
 */
public class NetworkModule extends MenuModule implements View.OnClickListener {

    private static final String TITLE = "Network";

    private NetworkController networkController;

    private ModuleSimpleProperty wifiState;
    private ModuleSimpleProperty mobileState;
    private ModuleSimpleProperty bluetoothState;

    @Override
    public String getTitle() {
        return TITLE;
    }

    @Override
    public View getContent(Context context) {

        networkController = NetworkController.newInstance(context);

        ViewGroup v = (ViewGroup) LayoutInflater.from(context).inflate(R.layout.sdm__module_network, null);
        assert v != null;

        v.findViewById(R.id.sdm__network_wifi_toggle).setOnClickListener(this);
        v.findViewById(R.id.sdm__network_mobile_toggle).setOnClickListener(this);
        v.findViewById(R.id.sdm__network_bluetooth_toggle).setOnClickListener(this);

        wifiState = new ModuleSimpleProperty(context, R.string.sdm__module_network_wifi);
        v.addView(wifiState);

        mobileState = new ModuleSimpleProperty(context, R.string.sdm__module_network_mobile);
        v.addView(mobileState);

        bluetoothState = new ModuleSimpleProperty(context, R.string.sdm__module_network_bluetooth);
        v.addView(bluetoothState);

        return v;
    }

    /**
     * Receive events from broadcast receiver and update UI
     *
     * @param e
     */
    public void onEventMainThread(NetworkChangeEvent e) {
        final String wifiStateString = e.wifiState.name().toLowerCase();
        final String mobileStateString = e.mobileState.name().toLowerCase();

        wifiState.setPropertyValue(Character.toUpperCase(wifiStateString.charAt(0)) + wifiStateString.substring(1));
        mobileState.setPropertyValue(Character.toUpperCase(mobileStateString.charAt(0)) + mobileStateString.substring(1));
        bluetoothState.setPropertyValue(e.bluetoothState.name().replace("_", " "));
    }

    @Override
    public void onStop() {
        networkController.unregisterReceiver();
        EventBus.getDefault().unregister(this);
    }

    @Override
    public void onStart() {
        EventBus.getDefault().register(this);
        networkController.registerReceiver();
    }

    @Override
    public void onClick(View v) {
        final int id = v.getId();
        if (id == R.id.sdm__network_wifi_toggle) {
            networkController.setWifiEnabled(!networkController.isWifiEnabled());
        } else if (id == R.id.sdm__network_mobile_toggle) {
            networkController.setMobileNetworkEnabled(!networkController.isMobileNetworkEnabled());
        } else if (id == R.id.sdm__network_bluetooth_toggle) {
            networkController.setBluetoothEnabled(!networkController.isBluetoothEnabled());
        }
    }
}


<|start_filename|>library/src/main/java/co/lemonlabs/android/slidingdebugmenu/controllers/LocationController.java<|end_filename|>
/*
 * Copyright (C) 2014 Lemon Labs
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package co.lemonlabs.android.slidingdebugmenu.controllers;

import android.content.Context;
import android.location.Location;
import android.os.Bundle;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesClient;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.location.LocationClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;

import de.greenrobot.event.EventBus;
import co.lemonlabs.android.slidingdebugmenu.modules.events.LocationEvent;

/**
 * Created by balysv on 14/01/14.
 * www.lemonlabs.co
 */
public class LocationController implements GooglePlayServicesClient.ConnectionCallbacks,
        GooglePlayServicesClient.OnConnectionFailedListener {

    private static LocationController instance;

    private LocationClient mLocationClient;

    public static LocationController newInstance(Context context) {
        if (instance == null)
            instance = new LocationController(context);
        return instance;
    }

    private LocationController(Context context) {
        if (GooglePlayServicesUtil.isGooglePlayServicesAvailable(context) == ConnectionResult.SUCCESS)
            mLocationClient = new LocationClient(context, this, this);
        else EventBus.getDefault().post(new LocationEvent(null));
    }

    @Override
    public void onConnected(Bundle bundle) {
        final Location location = mLocationClient.getLastLocation();
        EventBus.getDefault().post(new LocationEvent(location));
    }

    @Override
    public void onDisconnected() {
        mLocationClient.removeLocationUpdates(mLocationListener);
    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        EventBus.getDefault().post(new LocationEvent(null));
    }

    /**
     * Connect to GooglePlayServices location client
     */
    public void connect() {
        if (mLocationClient != null) mLocationClient.connect();
    }

    /**
     * Disconnect from GooglePlayServices location client
     */
    public void disconnect() {
        if (mLocationClient != null) mLocationClient.disconnect();

    }

    /**
     * Get last known location
     *
     * @return
     */
    public Location getLastLocation() {
        return mLocationClient != null ? mLocationClient.getLastLocation() : null;
    }

    /**
     * Request for a new location. Callbacks can be received by handling
     * {@link co.lemonlabs.android.slidingdebugmenu.modules.events.LocationEvent} using
     * {@link de.greenrobot.event.EventBus}.
     */
    public void requestLocation() {
        if (mLocationClient != null)
            mLocationClient.requestLocationUpdates(new LocationRequest(), mLocationListener);
    }

    /**
     * Simple location listener that pushes an event on location updates
     */
    private LocationListener mLocationListener = new LocationListener() {
        @Override
        public void onLocationChanged(Location location) {
            EventBus.getDefault().post(new LocationEvent(location));
        }
    };
}


<|start_filename|>demo/src/main/java/co/lemonlabs/android/slidingdebugmenu/demo/LocaleModule.java<|end_filename|>
/*
 * Copyright (C) 2014 Lemon Labs
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package co.lemonlabs.android.slidingdebugmenu.demo;

import android.content.Context;
import android.view.View;
import android.widget.LinearLayout;
import co.lemonlabs.android.slidingdebugmenu.modules.MenuModule;
import co.lemonlabs.android.slidingdebugmenu.views.ModuleSimpleProperty;

import java.util.Calendar;
import java.util.Locale;

/**
 * Demo custom module
 */
public class LocaleModule extends MenuModule {

    private static final String TITLE = "Locale Information";

    @Override
    public String getTitle() {
        return TITLE;
    }

    @Override
    public View getContent(Context context) {
        LinearLayout v = new LinearLayout(context);
        v.setOrientation(LinearLayout.VERTICAL);

        Locale defaultLocale = context.getResources().getConfiguration().locale;

        ModuleSimpleProperty locale = new ModuleSimpleProperty(context, "Locale");
        locale.setPropertyValue(defaultLocale.toString());
        v.addView(locale);

        ModuleSimpleProperty date = new ModuleSimpleProperty(context, "Date");
        date.setPropertyValue(Calendar.getInstance(defaultLocale).getTime().toString());
        v.addView(date);

        return v;
    }
}


<|start_filename|>library/src/main/java/co/lemonlabs/android/slidingdebugmenu/receivers/NetworkReceiver.java<|end_filename|>
package co.lemonlabs.android.slidingdebugmenu.receivers;

import android.bluetooth.BluetoothAdapter;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;

import de.greenrobot.event.EventBus;
import co.lemonlabs.android.slidingdebugmenu.modules.events.NetworkChangeEvent;

import static co.lemonlabs.android.slidingdebugmenu.controllers.NetworkController.BluetoothState;

/**
 * Receiver that handles wifi, mobile networks and
 * Bluetooth connectivity change intents and sends
 * a NetworkChangeEvent using EventBus
 * <p/>
 * Created by balysv on 10/01/14.
 * www.lemonlabs.co
 */
public class NetworkReceiver extends BroadcastReceiver {


    @Override
    public void onReceive(Context context, Intent intent) {
        ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

        NetworkInfo wifiInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
        NetworkInfo mobileInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);

        final int bluetoothState = BluetoothAdapter.getDefaultAdapter().getState();


        EventBus.getDefault().post(new NetworkChangeEvent(
                (wifiInfo != null) ? wifiInfo.getState() : NetworkInfo.State.UNKNOWN,
                (mobileInfo != null) ? mobileInfo.getState() : NetworkInfo.State.UNKNOWN,
                getBluetoothState(bluetoothState))
        );
    }

    /**
     * Converts Bluetooth state representation to an Enum
     *
     * @param state
     * @return
     */
    private BluetoothState getBluetoothState(int state) {
        switch (state) {
            case BluetoothAdapter.STATE_ON:
                return BluetoothState.On;
            case BluetoothAdapter.STATE_OFF:
                return BluetoothState.Off;
            case BluetoothAdapter.STATE_TURNING_ON:
                return BluetoothState.Turning_On;
            case BluetoothAdapter.STATE_TURNING_OFF:
                return BluetoothState.Turning_Off;
        }

        return BluetoothState.Unknown;
    }
}


<|start_filename|>library/src/main/java/co/lemonlabs/android/slidingdebugmenu/SlidingDebugMenu.java<|end_filename|>
/*
 * Copyright (C) 2014 <NAME>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package co.lemonlabs.android.slidingdebugmenu;

import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.provider.Settings;
import android.support.v4.widget.DrawerLayout;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import co.lemonlabs.android.slidingdebugmenu.modules.MenuModule;
import co.lemonlabs.android.slidingdebugmenu.views.ModuleTitle;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class SlidingDebugMenu extends RelativeLayout implements View.OnClickListener {

    private static final String TAG = "SlidingDebugMenu";

    public static SlidingDebugMenu create(Context context, List<MenuModule> modules) {
        SlidingDebugMenu sdm = (SlidingDebugMenu) LayoutInflater.from(context).inflate(R.layout.sdm__drawer, null);
        for (MenuModule module : modules) {
            sdm.addModule(module);
        }
        return sdm;
    }

    /**
     * Root layout of the menu
     */
    private ViewGroup mContainer;

    /**
     * Drawer settings layout
     */
    private View mDrawerSettings;

    /**
     * Drawer subtitle
     */
    private TextView mDrawerSubtitle;

    /**
     * List of currently added and visible modules
     */
    private List<MenuModule> mModules;

    /**
     * Map of modules to their views in the menu
     */
    private Map<MenuModule, ModuleViewHolder> mModuleViews;

    public SlidingDebugMenu(Context context,  AttributeSet attrs) {
        super(context, attrs);
        mModules = new ArrayList<>();
        mModuleViews = new HashMap<>();

        DrawerLayout.LayoutParams params = new DrawerLayout.LayoutParams(context, attrs);
        params.gravity = Gravity.RIGHT;
        setLayoutParams(params);
    }

    @Override protected void onFinishInflate() {
        super.onFinishInflate();

        mContainer = (ViewGroup) findViewById(R.id.sdm__drawer_container);
        mDrawerSettings = findViewById(R.id.sdm__drawer_settings);
        mDrawerSubtitle = (TextView) findViewById(R.id.sdm__drawer_title_description);

        // Set drawer title icon and name
        final ApplicationInfo appInfo = getContext().getApplicationInfo();
        ((ImageView) findViewById(R.id.sdm__drawer_title_icon)).setImageDrawable(appInfo.loadIcon(getContext().getPackageManager()));
        ((TextView) findViewById(R.id.sdm__drawer_title)).setText(appInfo.labelRes);

        // Init drawer settings
        findViewById(R.id.sdm__settings_developer).setOnClickListener(this);
        findViewById(R.id.sdm__settings_battery).setOnClickListener(this);
        findViewById(R.id.sdm__settings_drawer).setOnClickListener(this);
        findViewById(R.id.sdm__settings_uninstall).setOnClickListener(this);
        findViewById(R.id.sdm__settings_app_info).setOnClickListener(this);
    }

    /**
     * Add a new module to the end of the menu
     *
     * @param module      module to add
     */
    public void addModule(MenuModule module) {
        addModule(mModules.size(), module);
    }

    /**
     * Add a new module at the specified position of the menu
     *
     * @param position    the index at which to insert
     * @param module      module to add
     */
    public void addModule(int position, MenuModule module) {
        mModules.add(position, module);
        // drawer has a title view and each module has 2 views
        mModuleViews.put(module, addModuleViews(module, position * 2 + 1));
    }

    /**
     * Add module title and content to drawer layout at the given index
     * of the container and return a wrapper of the views
     *
     * @param module module to get views from
     * @param index  position of view root at which to insert
     * @return
     */
    private ModuleViewHolder addModuleViews(MenuModule module, int index) {
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        final int botMargin = (int) getResources().getDimension(R.dimen.sdm__module_subtitle_margin);
        final int topMargin = (int) getResources().getDimension(R.dimen.sdm__drawer_module_margin);
        params.setMargins(0, topMargin, 0, botMargin);

        ModuleTitle title = new ModuleTitle(getContext(), module.getTitle());
        View content = module.getContent(getContext());
        mContainer.addView(title, index, params);
        mContainer.addView(content, index + 1);

        return new ModuleViewHolder(title, content);
    }

    /**
     * Remove a module from the menu
     *
     * @param module module to remove
     */
    public void removeModule(MenuModule module) {
        if (mModules.remove(module)) {
            ModuleViewHolder holder = mModuleViews.get(module);
            mContainer.removeView(holder.title);
            mContainer.removeView(holder.content);
            module.onStop();
        }
    }

    /**
     * Remove a module from the menu by its position
     *
     * @param position the index which is to be removed
     */
    public void removeModule(int position) {
        MenuModule module = mModules.get(position);
        if (mModules.remove(module)) {
            ModuleViewHolder holder = mModuleViews.get(module);
            mContainer.removeView(holder.title);
            mContainer.removeView(holder.content);
            module.onStop();
        }
    }

    /**
     * Set visibility of drawer settings at the bottom of the menu
     *
     * @param visible
     */
    public void setDrawerSettingsVisible(boolean visible) {
        mDrawerSettings.setVisibility(visible ? VISIBLE : GONE);
    }

    /**
     * Set drawer subtitle
     *
     * @param text
     */
    public void setDrawerSubtitle(String text) {
        mDrawerSubtitle.setText(text);
    }

    /**
     * Get a list of currently loaded and visible modules
     *
     * @return
     */
    public List<MenuModule> getLoadedModules() {
        return mModules;
    }

    /**
     * Get a module by its position in the menu
     *
     * @param position
     * @return
     */
    public MenuModule getModule(int position) {
        return mModules.get(position);
    }

    /**
     * Get first occurrence of a module by given class. Returns null otherwise.
     *
     * @param moduleClass instance of module to look for
     * @return
     */
    public MenuModule getModule(Class<? extends MenuModule> moduleClass) {
        for (MenuModule module : mModules) {
            if (moduleClass.isInstance(module)) return module;
        }

        return null;
    }

    /**
     * Removes all modules and calls their {@link MenuModule#onStop()} method
     */
    public void onStop() {
        for (MenuModule module : mModules) {
            module.onStop();
        }
    }

    /**
     * Starts all modules and calls their {@link MenuModule#onStart()} method
     */
    public void onStart() {
        for (MenuModule module : mModules) {
            module.onStart();
        }
    }

    @SuppressWarnings("ConstantConditions")
    @Override
    public void onClick(View v) {
        final int id = v.getId();
        Context context = getContext();

        if (id == R.id.sdm__settings_developer) {
            // open dev settings
            Intent devIntent = new Intent(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS);
            ResolveInfo resolveInfo = context.getPackageManager().resolveActivity(devIntent, 0);
            if (resolveInfo != null) context.startActivity(devIntent);
            else Toast.makeText(context, "Developer settings not available on device", Toast.LENGTH_SHORT).show();

        } else if (id == R.id.sdm__settings_battery) {
            // try to find an app to handle battery settings
            Intent batteryIntent = new Intent(Intent.ACTION_POWER_USAGE_SUMMARY);
            ResolveInfo resolveInfo = context.getPackageManager().resolveActivity(batteryIntent, 0);
            if (resolveInfo != null) context.startActivity(batteryIntent);
            else Toast.makeText(context, "No app found to handle power usage intent", Toast.LENGTH_SHORT).show();

        } else if (id == R.id.sdm__settings_drawer) {
            // open android settings
            context.startActivity(new Intent(Settings.ACTION_SETTINGS));

        } else if (id == R.id.sdm__settings_app_info) {
            Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
            intent.setData(Uri.parse("package:" + context.getPackageName()));
            context.startActivity(intent);

        } else if (id == R.id.sdm__settings_uninstall) {
            // open dialog to uninstall app
            Uri packageURI = Uri.parse("package:" + context.getPackageName());
            Intent uninstallIntent = new Intent(Intent.ACTION_DELETE, packageURI);
            context.startActivity(uninstallIntent);
        }
    }

    /**
     * Holder for module views
     */
    public static class ModuleViewHolder {
        public final ModuleTitle title;
        public final View content;

        public ModuleViewHolder(ModuleTitle title, View content) {
            this.title = title;
            this.content = content;
        }
    }
}


<|start_filename|>demo/src/main/java/co/lemonlabs/android/slidingdebugmenu/demo/DemoActivity.java<|end_filename|>
package co.lemonlabs.android.slidingdebugmenu.demo;

import android.app.Activity;
import android.os.Bundle;
import android.support.v4.widget.DrawerLayout;
import co.lemonlabs.android.slidingdebugmenu.SlidingDebugMenu;
import dagger.ObjectGraph;

import javax.inject.Inject;

public class DemoActivity extends Activity {

    @Inject SlidingDebugMenu menu;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.demo);

        ObjectGraph og = ObjectGraph.create(new DemoModule(this));
        og.inject(this);

        // show/hide the settings at the bottom of the drawer
        menu.setDrawerSettingsVisible(true);

        DrawerLayout drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        drawerLayout.addView(menu);
    }

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

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


<|start_filename|>library/src/main/java/co/lemonlabs/android/slidingdebugmenu/modules/BuildModule.java<|end_filename|>
/*
 * Copyright (C) 2014 <NAME>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package co.lemonlabs.android.slidingdebugmenu.modules;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.view.View;
import android.widget.LinearLayout;

import co.lemonlabs.android.slidingdebugmenu.R;
import co.lemonlabs.android.slidingdebugmenu.views.ModuleSimpleProperty;

/**
 * Module that provides basic information about
 * the running application.
 */
public class BuildModule extends MenuModule {

    private static final String TITLE = "Build Information";

    @Override
    public String getTitle() {
        return TITLE;
    }

    @Override
    public View getContent(Context context) {
        LinearLayout v = new LinearLayout(context);
        v.setOrientation(LinearLayout.VERTICAL);


        ModuleSimpleProperty name = new ModuleSimpleProperty(context, R.string.sdm__module_build_name);
        v.addView(name);

        ModuleSimpleProperty version = new ModuleSimpleProperty(context, R.string.sdm__module_build_version);
        v.addView(version);

        ModuleSimpleProperty packageName = new ModuleSimpleProperty(context, R.string.sdm__module_build_package);
        v.addView(packageName);

        try {
            final PackageInfo info = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
            version.setPropertyValue(String.valueOf(info.versionCode));
            name.setPropertyValue(info.versionName);
            packageName.setPropertyValue(info.packageName);
        } catch (PackageManager.NameNotFoundException e) {

        }

        return v;
    }
}


<|start_filename|>library/src/main/java/co/lemonlabs/android/slidingdebugmenu/views/ModuleSimpleProperty.java<|end_filename|>
package co.lemonlabs.android.slidingdebugmenu.views;

import android.content.Context;
import android.view.LayoutInflater;
import android.widget.FrameLayout;
import android.widget.TextView;

import co.lemonlabs.android.slidingdebugmenu.R;

/**
 * Simple module property containing
 * two text views
 * <p/>
 * Created by balysv on 10/01/14.
 * www.lemonlabs.co
 */
public class ModuleSimpleProperty extends FrameLayout {

    private TextView mPropertyName;
    private TextView mPropertyValue;

    public ModuleSimpleProperty(Context context, String propertyName) {
        this(context);
        setPropertyName(propertyName);
    }

    public ModuleSimpleProperty(Context context, int propertyResId) {
        this(context);
        setPropertyName(propertyResId);
    }

    public ModuleSimpleProperty(Context context) {
        super(context);
        inflate();
    }

    private void inflate() {
        LayoutInflater.from(getContext()).inflate(R.layout.sdm__module_property_simple, this, true);
        mPropertyName = (TextView) findViewById(R.id.sdm__module_property_name);
        mPropertyValue = (TextView) findViewById(R.id.sdm__module_property_value);
    }

    /**
     * Set name of property
     *
     * @param name
     */
    public void setPropertyName(String name) {
        mPropertyName.setText(name);
    }

    /**
     * Set name of property
     *
     * @param resId
     */
    public void setPropertyName(int resId) {
        mPropertyName.setText(resId);
    }

    /**
     * Set property value
     *
     * @param name
     */
    public void setPropertyValue(String name) {
        mPropertyValue.setText(name);
    }

    /**
     * Set property value
     *
     * @param resId
     */
    public void setPropertyValue(int resId) {
        mPropertyValue.setText(resId);
    }
}


<|start_filename|>library/src/main/java/co/lemonlabs/android/slidingdebugmenu/views/ModuleTitle.java<|end_filename|>
package co.lemonlabs.android.slidingdebugmenu.views;

import android.content.Context;
import android.widget.TextView;

import co.lemonlabs.android.slidingdebugmenu.R;

/**
 * Created by balysv on 10/01/14.
 * www.lemonlabs.co
 */
public class ModuleTitle extends TextView {

    public ModuleTitle(Context context, String title) {
        super(context);
        setTextAppearance(context, R.style.Widget_Sdm_TextView_ModuleTitle);
        setBackgroundResource(R.drawable.sdm__module_title_bg);

        setText(title.toUpperCase());
    }
}


<|start_filename|>library/src/main/java/co/lemonlabs/android/slidingdebugmenu/controllers/NetworkController.java<|end_filename|>
/*
 * Copyright (C) 2014 Lemon Labs
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package co.lemonlabs.android.slidingdebugmenu.controllers;

import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiManager;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import co.lemonlabs.android.slidingdebugmenu.receivers.NetworkReceiver;

/**
 * Created by balysv on 10/01/14.
 * www.lemonlabs.co
 */

public class NetworkController {

    public enum BluetoothState {
        On, Off, Turning_On, Turning_Off, Unknown
    }

    private static NetworkController instance;

    private WifiManager mWifiManager;
    private ConnectivityManager mConnectivityManager;
    private BluetoothAdapter mBluetoothAdapter;

    private NetworkReceiver mReceiver;

    private transient Context mContext;

    public static NetworkController newInstance(Context context) {
        if (instance == null)
            instance = new NetworkController(context);
        return instance;
    }

    /**
     * Controller responsible for switching states related to networks.
     * E.g. wifi, mobile networks
     *
     * @param context
     */
    private NetworkController(Context context) {
        mContext = context.getApplicationContext();
        mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
        mConnectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    }


    /**
     * True if WiFi enabled
     *
     * @return
     */
    public boolean isWifiEnabled() {
        return mWifiManager.isWifiEnabled();
    }

    /**
     * Set WiFi state
     *
     * @param enabled
     */
    public void setWifiEnabled(boolean enabled) {
        mWifiManager.setWifiEnabled(enabled);
    }

    /**
     * True if mobile network enabled
     *
     * @return
     */
    public boolean isMobileNetworkEnabled() {
        final NetworkInfo info = mConnectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
        return (info != null && info.isConnected());
    }

    /**
     * Try to enabled/disable mobile network state using reflection.
     * Returns true if succeeded
     *
     * @param enabled
     * @return
     */
    public boolean setMobileNetworkEnabled(boolean enabled) {
        try {
            final Class conmanClass = Class.forName(mConnectivityManager.getClass().getName());
            final Field iConnectivityManagerField = conmanClass.getDeclaredField("mService");
            iConnectivityManagerField.setAccessible(true);
            final Object iConnectivityManager = iConnectivityManagerField.get(mConnectivityManager);
            final Class iConnectivityManagerClass = Class.forName(iConnectivityManager.getClass().getName());
            final Method setMobileDataEnabledMethod = iConnectivityManagerClass.getDeclaredMethod("setMobileDataEnabled", Boolean.TYPE);
            setMobileDataEnabledMethod.setAccessible(true);
            setMobileDataEnabledMethod.invoke(iConnectivityManager, enabled);
            return true;
        } catch (ClassNotFoundException | InvocationTargetException | NoSuchMethodException | IllegalAccessException | NoSuchFieldException e) {
        }
        return false;
    }

    /**
     * True if bluetooth is enabled
     */
    public boolean isBluetoothEnabled() {
        return mBluetoothAdapter.isEnabled();
    }

    /**
     * Try to enable/disabled bluetooth. Returns false if immediate
     * error occurs
     *
     * @param enabled
     * @return
     */
    public boolean setBluetoothEnabled(boolean enabled) {
        return enabled ? mBluetoothAdapter.enable() : mBluetoothAdapter.disable();
    }


    /**
     * Unregister network state broadcast receiver
     */
    public void unregisterReceiver() {
        try {
            mContext.unregisterReceiver(mReceiver);
        } catch (IllegalArgumentException e) {
        }
    }

    /**
     * Register network state broadcast receiver
     */
    public void registerReceiver() {
        if (mReceiver == null)
            mReceiver = new NetworkReceiver();
        IntentFilter filter = new IntentFilter();
        filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
        filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
        mContext.registerReceiver(mReceiver, filter);
    }

}


<|start_filename|>library/src/main/java/co/lemonlabs/android/slidingdebugmenu/modules/MenuModule.java<|end_filename|>
/*
 * Copyright (C) 2014 Lemon Labs
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package co.lemonlabs.android.slidingdebugmenu.modules;

import android.content.Context;
import android.view.View;

/**
 * Base class for SlidingDebugMenu modules.
 * <p/>
 * Created by balysv on 10/01/14.
 * www.lemonlabs.co
 */
public abstract class MenuModule {

    public MenuModule() {}

    public abstract String getTitle();

    public abstract View getContent(Context context);

    /**
     * Override this method if you need to do
     * some clean up when activity goes to foreground.
     * E.g. unregister receivers
     */
    public void onStop() {
        // do clean up
    }

    /**
     * Override this method if you need to start
     * some processes that would be killed when
     * onStop() is called
     * E.g. register receivers
     */
    public void onStart() {
        // reinitialize stuff
    }
}


<|start_filename|>demo/src/main/java/co/lemonlabs/android/slidingdebugmenu/demo/DemoModule.java<|end_filename|>
package co.lemonlabs.android.slidingdebugmenu.demo;

import android.content.Context;
import co.lemonlabs.android.slidingdebugmenu.SlidingDebugMenuModule;
import co.lemonlabs.android.slidingdebugmenu.modules.BuildModule;
import co.lemonlabs.android.slidingdebugmenu.modules.LocationModule;
import co.lemonlabs.android.slidingdebugmenu.modules.LogModule;
import co.lemonlabs.android.slidingdebugmenu.modules.MenuModule;
import co.lemonlabs.android.slidingdebugmenu.modules.NetworkModule;
import dagger.Module;
import dagger.Provides;

import java.util.ArrayList;
import java.util.List;

@Module(
    includes = {
        SlidingDebugMenuModule.class
    },
    injects = {
        DemoActivity.class
    }
)
public class DemoModule {

    private final Context context;

    public DemoModule(Context context) {
        this.context = context;
    }

    @Provides Context provideContext() {
        return context;
    }

    @Provides List<MenuModule> provideMenuModules(BuildModule build, LocationModule location, LogModule log, NetworkModule network) {
        List<MenuModule> modules = new ArrayList<>();

        // Custom, app specific module
        modules.add(new LocaleModule());

        modules.add(build);
        modules.add(location);
        modules.add(log);
        modules.add(network);

        return modules;
    }

}


<|start_filename|>library/src/main/java/co/lemonlabs/android/slidingdebugmenu/modules/events/LocationEvent.java<|end_filename|>
package co.lemonlabs.android.slidingdebugmenu.modules.events;

import android.location.Location;

/**
 * Created by balysv on 14/01/14.
 * www.lemonlabs.co
 */
public class LocationEvent {

    public final Location location;

    public LocationEvent(Location location) {
        this.location = location;
    }
}


<|start_filename|>library/src/main/java/co/lemonlabs/android/slidingdebugmenu/modules/LocationModule.java<|end_filename|>
/*
 * Copyright (C) 2014 <NAME>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package co.lemonlabs.android.slidingdebugmenu.modules;

import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.net.Uri;
import android.provider.Settings;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import co.lemonlabs.android.slidingdebugmenu.R;
import co.lemonlabs.android.slidingdebugmenu.controllers.LocationController;
import co.lemonlabs.android.slidingdebugmenu.modules.events.LocationEvent;
import co.lemonlabs.android.slidingdebugmenu.views.ModuleSimpleProperty;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import de.greenrobot.event.EventBus;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Module that provides information about the current
 * location of the device, allows to get new locations,
 * go to settings and open maps.
 * GooglePlayServices {@link com.google.android.gms.location.LocationClient} is used,
 * so be sure to call {@link #onStop() onStop} and {@link #onStart() onStart}.
 * Module will not work in devices without GooglePlayServices installed.
 */
public class LocationModule extends MenuModule {

    private static final String TITLE = "Location";

    private LocationController mLocationController;

    private ModuleSimpleProperty latitude;
    private ModuleSimpleProperty longitude;
    private ModuleSimpleProperty accuracy;
    private ModuleSimpleProperty time;
    private ModuleSimpleProperty provider;

    private Location mLocation;

    private boolean mPlayServicesAvailable;

    @Override
    public String getTitle() {
        return TITLE;
    }

    @Override
    public View getContent(final Context context) {
        mPlayServicesAvailable = GooglePlayServicesUtil.isGooglePlayServicesAvailable(context) == ConnectionResult.SUCCESS;
        // add module contents only if Google Play Services are available
        if (mPlayServicesAvailable) {
            mLocationController = LocationController.newInstance(context);

            ViewGroup v = (ViewGroup) LayoutInflater.from(context).inflate(R.layout.sdm__module_location, null);
            assert v != null;

            final View.OnClickListener onClickListener = new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    final int id = v.getId();
                    if (id == R.id.sdm__location_map) {
                        openMaps(context);
                    } else if (id == R.id.sdm__location_get) {
                        mLocationController.requestLocation();
                    } else if (id == R.id.sdm__location_settings) {
                        context.startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
                    }
                }
            };

            v.findViewById(R.id.sdm__location_get).setOnClickListener(onClickListener);
            v.findViewById(R.id.sdm__location_settings).setOnClickListener(onClickListener);
            v.findViewById(R.id.sdm__location_map).setOnClickListener(onClickListener);

            latitude = new ModuleSimpleProperty(context, R.string.sdm__module_location_latitide);
            v.addView(latitude);

            longitude = new ModuleSimpleProperty(context, R.string.sdm__module_location_longitude);
            v.addView(longitude);

            accuracy = new ModuleSimpleProperty(context, R.string.sdm__module_location_accuracy);
            v.addView(accuracy);

            time = new ModuleSimpleProperty(context, R.string.sdm__module_location_time);
            v.addView(time);

            provider = new ModuleSimpleProperty(context, R.string.sdm__module_location_provider);
            v.addView(provider);
            return v;
        } else {
            TextView errorText = new TextView(context);
            errorText.setTextAppearance(context, R.style.Widget_Sdm_TextView_PropertyValue);
            errorText.setText(R.string.sdm__module_location_play_unavailable);
            return errorText;
        }
    }

    /**
     * Receive location update events
     *
     * @param e
     */
    public void onEventMainThread(LocationEvent e) {
        updateLocation(e.location);
    }

    @Override
    public void onStart() {
        if (mPlayServicesAvailable) {
            EventBus.getDefault().register(this);
            mLocationController.connect();
        }
    }

    @Override
    public void onStop() {
        if (mPlayServicesAvailable) {
            mLocationController.disconnect();
            EventBus.getDefault().unregister(this);
        }
    }

    /**
     * Update the module UI
     *
     * @param location
     */
    private void updateLocation(Location location) {
        mLocation = location;
        if (location != null) {
            latitude.setPropertyValue(String.valueOf(location.getLatitude()));
            longitude.setPropertyValue(String.valueOf(location.getLongitude()));
            accuracy.setPropertyValue(String.valueOf(location.getAccuracy()) + "m");

            Date date = new Date(location.getTime());
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            time.setPropertyValue(sdf.format(date));

            provider.setPropertyValue(location.getProvider());
        } else {
            latitude.setPropertyValue(R.string.sdm__module_location_empty);
            longitude.setPropertyValue(R.string.sdm__module_location_empty);
            accuracy.setPropertyValue(R.string.sdm__module_location_empty);
            time.setPropertyValue(R.string.sdm__module_location_empty);
            provider.setPropertyValue(R.string.sdm__module_location_no_provider);
        }
    }


    /**
     * Tries to open an activity that handles geo coordinates
     *
     * @param context
     */
    private void openMaps(Context context) {
        try {
            if (mLocation != null) {
                String uri = "geo:" + mLocation.getLatitude() + "," + mLocation.getLongitude();
                context.startActivity(new Intent(android.content.Intent.ACTION_VIEW, Uri.parse(uri)));
            } else {
                Toast.makeText(context, R.string.sdm__module_location_not_found, Toast.LENGTH_SHORT).show();
            }
        } catch (ActivityNotFoundException e) {
            Toast.makeText(context, R.string.sdm__module_location_map_not_found, Toast.LENGTH_SHORT).show();
        }
    }
}


<|start_filename|>library/src/main/java/co/lemonlabs/android/slidingdebugmenu/modules/events/NetworkChangeEvent.java<|end_filename|>
package co.lemonlabs.android.slidingdebugmenu.modules.events;

import android.net.NetworkInfo;

import static co.lemonlabs.android.slidingdebugmenu.controllers.NetworkController.BluetoothState;

/**
 * Created by balysv on 10/01/14.
 * www.lemonlabs.co
 */
public class NetworkChangeEvent {

    public final NetworkInfo.State wifiState;
    public final NetworkInfo.State mobileState;
    public final BluetoothState bluetoothState;

    public NetworkChangeEvent(NetworkInfo.State wifiState, NetworkInfo.State mobileState, BluetoothState bluetoothState) {
        this.wifiState = wifiState;
        this.mobileState = mobileState;
        this.bluetoothState = bluetoothState;
    }
}
