de.questmaster.fatremote.fragments.SelectFATFragment.java Source code

Java tutorial

Introduction

Here is the source code for de.questmaster.fatremote.fragments.SelectFATFragment.java

Source

/*
 * Copyright (C) 2010 Daniel Jacobi
 * 
 * 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 de.questmaster.fatremote.fragments;

import java.io.IOException;
import java.net.InetAddress;
import java.util.List;

import android.app.Activity;
import android.app.ProgressDialog;
import android.database.Cursor;
import android.database.sqlite.SQLiteException;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.ListFragment;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.Toast;
import de.questmaster.fatremote.FatDevicesDbAdapter;
import de.questmaster.fatremote.NetworkProxy;
import de.questmaster.fatremote.R;
import de.questmaster.fatremote.datastructures.FATDevice;

// TODO: set marker on auto detected entries, e.g. icon

/**
 * This Fragment is instantiated to search, enter and select FreeAgent devices.
 * 
 * @author daniel
 *
 */
public class SelectFATFragment extends ListFragment {

    private static final String LOG_TAG = "SelectFATFragment";

    private Activity c = null;
    private ProgressDialog mDialog = null;
    private FatDevicesDbAdapter mDbHelper = null;
    private FATSelectedListener mListener = null;

    private SimpleCursorAdapter mListAdapter;

    /**
     * To forward data to the parent activity the container activity must implement this interface.
     * 
     * @author daniel
     *
     */
    public interface FATSelectedListener {

        /**
         * The selected FAT device is forwarded to the implementing entity.
         * @param dev selected device.
         */
        void onFATSelected(FATDevice dev);
    }

    /**
    * Called when the activity is first created. 
    * 
    * @see android.app.Activity#onCreate(android.os.Bundle) 
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // enable options menu
        this.setHasOptionsMenu(true);

        // set activity
        c = this.getActivity();

        // set Listener callback
        mListener = (FATSelectedListener) this.getActivity();

        // Init Database
        mDbHelper = new FatDevicesDbAdapter(c);
        try {
            mDbHelper.open();
        } catch (SQLiteException e) {
            Log.e(LOG_TAG, "Database failed to initialize.", e);
        }

        // Create the item list
        Cursor cursor = mDbHelper.fetchAllFatDevices();
        //      getActivity().startManagingCursor(cursor);

        String[] childFrom = new String[] { FatDevicesDbAdapter.KEY_NAME, FatDevicesDbAdapter.KEY_IP };
        int[] childTo = new int[] { R.id.textName, R.id.textIP };

        mListAdapter = new SimpleCursorAdapter(c, R.layout.selectfat_list_item, cursor, childFrom, childTo);
        setListAdapter(mListAdapter);

    }

    /**
     * Instantiates the user interface view
     * 
     * @see android.app.Fragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle)
     */
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);

        if (container == null) {
            // We have different layouts, and in one of them this
            // fragment's containing frame doesn't exist.  The fragment
            // may still be created from its saved state, but there is
            // no reason to try to create its view hierarchy because it
            // won't be displayed.  Note this is not needed -- we could
            // just run the code below, where we would create and return
            // the view hierarchy; it would just never be used.
            return null;
        }

        // Inflate the layout for this fragment
        View root = inflater.inflate(R.layout.selectfat_fragment, container, false);
        registerForContextMenu(root.findViewById(android.R.id.list));

        return root;
    }

    /**
     * This fragments Activity is created and the fragment instantiated.
     * 
     * @see android.app.Fragment#onActivityCreated(android.os.Bundle)
     */
    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        // check if WIFI available
        if (!NetworkProxy.getInstance(c).isWifiEnabled()) {
            Toast.makeText(c, R.string.app_err_enwifi, Toast.LENGTH_LONG).show();
        }
    }

    /**
     * Item from the ListView selected.
     * 
     * @see android.app.ListFragment#onListItemClick(android.widget.ListView, android.view.View, int, long)
     */
    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        super.onListItemClick(l, v, position, id);

        // retrieve selected fat
        FATDevice fd = mDbHelper.fetchFatDeviceTyp(id);

        mListener.onFATSelected(fd);

    }

    /**
     * Called in the restart process.
     * 
     * @see android.app.Activity#onResume() 
     */
    @Override
    public void onResume() {
        super.onResume();

        // check for database connection
        // maybe canceled due to low memory, etc.
        if (mDbHelper == null) {
            mDbHelper = new FatDevicesDbAdapter(c);
        }
        if (!mDbHelper.isOpen()) {
            mDbHelper.open();
        }

        // fill list
        this.updateListView();
    }

    /**
     * Called in the closing process.
     * 
     * @see android.app.Activity#onStop() 
     */
    @Override
    public void onStop() {
        super.onStop();

        Cursor cursor = mListAdapter.getCursor();
        if (!cursor.isClosed()) {
            cursor.close();
        }
        if (mDbHelper.isOpen()) {
            mDbHelper.close();
        }
    }

    /**
     * Discovers all FAT devices on the network. The found devices are entered into 
     * the database and shown in the List.
     */
    private void getAvailableIps() {

        // show progress dialog
        mDialog = ProgressDialog.show(c, "", getResources().getString(R.string.dialog_wait_searching), true);

        // get data
        new Thread(new Runnable() {
            public void run() {
                List<FATDevice> dev = null;

                // grab available ip's
                try {
                    dev = NetworkProxy.getInstance(c).discoverFAT();

                    // enter dev's into database
                    for (FATDevice f : dev) {
                        addFATDeviceToDatabase(f);
                    }
                } catch (IOException e) {
                    Log.e(LOG_TAG, e.getMessage(), e);
                }

                // close progress dialog
                mDialog.dismiss();
            }
        }).start();
    }

    /**
     * Add menu items
     * 
     * @see android.app.Activity#onCreateOptionsMenu(android.view.Menu)
     */
    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        super.onCreateOptionsMenu(menu, inflater);

        inflater.inflate(R.menu.menu_select_fat, menu);
    }

    /**
     * Define menu action
     * 
     * @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem)
     */
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.MENU_ADD:
            showAddDeviceDialog();

            break;
        case R.id.MENU_REFRESH:
            getAvailableIps();

            break;
        default:
            // should not happen
            break;
        }
        return super.onOptionsItemSelected(item);
    }

    /**
     * Create context menu
     * 
     * @see android.app.Activity#onCreateContextMenu(android.view.ContextMenu, android.view.View, android.view.ContextMenu.ContextMenuInfo)
     */
    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo);

        MenuInflater inflater = getActivity().getMenuInflater();
        inflater.inflate(R.menu.contextmenu_select_fat, menu);
    }

    /**
     * An item of the context menu was selected.
     * 
     * @see android.app.Activity#onContextItemSelected(android.view.MenuItem)
     */
    @Override
    public boolean onContextItemSelected(MenuItem item) {
        AdapterContextMenuInfo menuInfo = (AdapterContextMenuInfo) item.getMenuInfo();

        switch (item.getItemId()) {
        case R.id.cm_delete:
            mDbHelper.deleteFatDevice(menuInfo.id);
            updateListView();

            return true;
        case R.id.cm_delete_all:
            mDbHelper.deleteAllFatDevices();
            updateListView();

            return true;
        default:
            Log.e(LOG_TAG, "Should not happen: default case of switch reached.");
        }
        return super.onContextItemSelected(item);
    }

    /**
     * Updates the FAT devices displayed in the ListView. Data is extracted from the database.
     */
    private void updateListView() {
        // close old cursor
        Cursor oldCursor = mListAdapter.getCursor();
        if (!oldCursor.isClosed()) {
            oldCursor.close();
        }

        // Get all of the notes from the database and create the item list
        Cursor cursor = mDbHelper.fetchAllFatDevices();

        mListAdapter.changeCursor(cursor);
    }

    /**
     * Adds a manually entered FAT device to the database.
     * 
     * @param dev manually entered device.
     */
    private void addFATDeviceToDatabase(FATDevice dev) {
        long rowId = mDbHelper.fetchFatDeviceId(dev.getIp());
        if (rowId < 0) {
            mDbHelper.createFatDevice(dev);
        } else {
            mDbHelper.updateFatDevice(rowId, dev);
        }

        if (mDbHelper.getAllFatDevicesCount() == 0) {
            c.runOnUiThread(new Runnable() {
                public void run() {
                    Toast.makeText(c, R.string.app_err_wifioff, Toast.LENGTH_LONG).show();
                }
            });
        } else {
            c.runOnUiThread(new Runnable() {
                public void run() {
                    updateListView();
                }
            });
        }

    }

    /**
     * Shows the add device dialog. Here a device can be entered manually. 
     */
    private void showAddDeviceDialog() {
        DialogFragment addDialog = AddDeviceDialogFragment.newInstance(R.string.dialog_adddev_title);
        addDialog.setTargetFragment(this, 0);
        addDialog.show(getFragmentManager(), "dialog");
    }

    /**
     * Evaluates the result of the add device dialog. Checks entered data and stores it in the database.
     * 
     * @param name Name of the device.
     * @param ip IP of the device.
     */
    public void doPositiveClick(String name, String ip) {
        InetAddress ia = null;
        boolean errOccured = false;

        // check ip: 1. Match against regex, 2. check if ip correct
        try {
            if (ip.matches("\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b")) {
                ia = InetAddress.getByName(ip);
            } else {
                throw new Exception("Bad Format");
            }
        } catch (Exception e) {
            c.runOnUiThread(new Runnable() {
                public void run() {
                    Toast.makeText(c, R.string.app_err_wrongip, Toast.LENGTH_LONG).show();
                }
            });
            errOccured = true;
        }

        // set
        if (!errOccured) {
            FATDevice dev = new FATDevice(name, ia, false);
            addFATDeviceToDatabase(dev);
        }
    }

}