com.kii.demo.sync.ui.fragments.FileListFragment.java Source code

Java tutorial

Introduction

Here is the source code for com.kii.demo.sync.ui.fragments.FileListFragment.java

Source

//
//
//  Copyright 2012 Kii Corporation
//  http://kii.com
//
//  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 com.kii.demo.sync.ui.fragments;

import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;

import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.support.v4.app.ListFragment;
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.BaseAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;

import com.kii.cloud.sync.BackupService;
import com.kii.cloud.sync.KiiSyncClient;
import com.kii.cloud.sync.SyncNewEventListener;
import com.kii.demo.sync.R;
import com.kii.demo.sync.ui.view.ActionItem;
import com.kii.demo.sync.ui.view.KiiListItemView;
import com.kii.demo.sync.ui.view.QuickAction;
import com.kii.demo.sync.utils.MimeInfo;
import com.kii.demo.sync.utils.MimeUtil;
import com.kii.demo.sync.utils.UiUtils;
import com.kii.demo.sync.utils.Utils;
import com.kii.sync.KiiFile;
import com.kii.sync.SyncMsg;

public class FileListFragment extends ListFragment {
    protected File mDirectory;
    protected ArrayList<File> mFiles;
    protected FilePickerListAdapter mAdapter;
    protected boolean mShowHiddenFiles = false;
    protected String[] acceptedFileExtensions;
    private final static String DEFAULT_INITIAL_DIRECTORY = "/mnt/sdcard/";
    private View mView;
    private NewEventListener mListener = null;

    private final static int OPTIONS_MENU_SCAN_CHANGE = 0;
    private final static int OPTIONS_MENU_DOWNLOAD_ALL = 1;
    QuickAction mQuickAction = null;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        mView = inflater.inflate(R.layout.list_with_header, container, false);
        Button b = (Button) mView.findViewById(R.id.button_left);
        b.setText(getString(R.string.header_btn_home));
        b.setOnClickListener(mClickListener);
        b = (Button) mView.findViewById(R.id.button_right);
        b.setText(getString(R.string.header_btn_up));
        b.setOnClickListener(mClickListener);
        setHasOptionsMenu(true);
        return mView;
    }

    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        File newFile = (File) l.getItemAtPosition(position);
        if (newFile.isFile()) {
            Intent intent = null;
            MimeInfo mime = MimeUtil.getInfoByFileName(newFile.getAbsolutePath());

            intent = UiUtils.getLaunchFileIntent(newFile.getAbsolutePath(), mime);
            if (intent == null) {
                UiUtils.showToast(getActivity(), "Failed to launch the file - " + newFile.getName());
            } else {
                try {
                    startActivity(intent);
                } catch (Exception ex) {
                    UiUtils.showToast(getActivity(), "Encounter error when launch file (" + newFile.getName()
                            + "). Error(" + ex.getMessage() + ")");
                }
            }
        } else {
            mDirectory = newFile;
            // Update the files list
            refreshFilesList();
        }

        super.onListItemClick(l, v, position, id);

    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        mDirectory = new File(DEFAULT_INITIAL_DIRECTORY);
        mFiles = new ArrayList<File>();
        mAdapter = new FilePickerListAdapter(getActivity(), mFiles);
        setListAdapter(mAdapter);
        mListener = new NewEventListener(getActivity());
        mListener.register();
    }

    private void uploadFile(final File file) {
        KiiSyncClient client = KiiSyncClient.getInstance(getActivity());
        client.upload(file.getAbsolutePath());
        Utils.startSync(getActivity(), BackupService.ACTION_REFRESH);
    }

    private List<File> mUploadFiles = new ArrayList<File>();

    private void uploadFolder(final File file) {
        KiiSyncClient client = KiiSyncClient.getInstance(getActivity());
        getRecursiveFiles(file);
        for (File f : mUploadFiles) {
            client.upload(f.getAbsolutePath());
        }
        mUploadFiles.clear();
        Utils.startSync(getActivity(), BackupService.ACTION_REFRESH);
    }

    private void getRecursiveFiles(File file) {
        File[] list = file.listFiles();
        for (File f : list) {
            if (f.isDirectory()) {
                getRecursiveFiles(f);
            } else {
                mUploadFiles.add(f);
            }
        }
    }

    private void moveToTrash(File file) {
        KiiSyncClient client = KiiSyncClient.getInstance(getActivity());
        client.moveToTrash(file.getAbsolutePath(), null);
        Utils.startSync(getActivity(), BackupService.ACTION_REFRESH);
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        menu.add(0, OPTIONS_MENU_SCAN_CHANGE, 0, R.string.scan_change);
        menu.add(0, OPTIONS_MENU_DOWNLOAD_ALL, 1, R.string.download_all);
        return;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case OPTIONS_MENU_SCAN_CHANGE:
            new ScanTask().execute();
            break;
        case OPTIONS_MENU_DOWNLOAD_ALL:
            Utils.startSync(getActivity(), BackupService.ACTION_REFRESH_QUICK);
            break;
        default:
            break;
        }
        return true;
    }

    @Override
    public void onResume() {
        refreshFilesList();
        super.onResume();
    }

    @Override
    public void onDestroy() {
        if (mListener != null) {
            mListener.unregister();
        }
        super.onDestroy();
    }

    private class FilePickerListAdapter extends BaseAdapter {

        private List<File> mObjects;

        public FilePickerListAdapter(Context context, List<File> objects) {
            super();
            mObjects = objects;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            File file = mObjects.get(position);
            Drawable icon = null;
            if (ICON_CACHE.containsKey(file.getAbsolutePath())) {
                icon = ICON_CACHE.get(file.getAbsolutePath());
            } else {
                icon = Utils.getThumbnailDrawableByFilename(file.getAbsolutePath(), getActivity());
                ICON_CACHE.put(file.getAbsolutePath(), icon);
            }
            KiiListItemView v;
            if (convertView == null) {
                v = new KiiListItemView(getActivity(), file, KiiSyncClient.getInstance(getActivity()), icon,
                        mClickListener);
                return v;
            } else {
                v = (KiiListItemView) convertView;
                v.refreshWithNewFile(file, icon);
                return v;
            }
        }

        @Override
        public int getCount() {
            return mObjects.size();
        }

        @Override
        public Object getItem(int position) {
            return mObjects.get(position);
        }

        @Override
        public long getItemId(int position) {
            return 0;
        }

    }

    private static HashMap<String, Drawable> ICON_CACHE = new HashMap<String, Drawable>();

    private class FileComparator implements Comparator<File> {
        @Override
        public int compare(File f1, File f2) {
            if (f1 == f2) {
                return 0;
            }
            if (f1.isDirectory() && f2.isFile()) {
                // Show directories above files
                return -1;
            }
            if (f1.isFile() && f2.isDirectory()) {
                // Show files below directories
                return 1;
            }
            // Sort the directories alphabetically
            return f1.getName().compareToIgnoreCase(f2.getName());
        }
    }

    private class ExtensionFilenameFilter implements FilenameFilter {
        private String[] mExtensions;

        public ExtensionFilenameFilter(String[] extensions) {
            super();
            mExtensions = extensions;
        }

        @Override
        public boolean accept(File dir, String filename) {
            if (new File(dir, filename).isDirectory()) {
                // Accept all directory names
                return true;
            }
            if ((mExtensions != null) && (mExtensions.length > 0)) {
                for (int i = 0; i < mExtensions.length; i++) {
                    if (filename.endsWith(mExtensions[i])) {
                        // The filename ends with the extension
                        return true;
                    }
                }
                // The filename did not match any of the extensions
                return false;
            }
            // No extensions has been set. Accept all file extensions.
            return true;
        }
    }

    public void refreshFilesList() {
        // Clear the files ArrayList
        mFiles.clear();

        // Set the extension file filter
        ExtensionFilenameFilter filter = new ExtensionFilenameFilter(acceptedFileExtensions);

        // Get the files in the directory
        File[] files = mDirectory.listFiles(filter);
        if ((files != null) && (files.length > 0)) {
            for (File f : files) {
                if (f.isHidden() && !mShowHiddenFiles) {
                    // Don't add the file
                    continue;
                }
                // Add the file the ArrayAdapter
                mFiles.add(f);
            }

            Collections.sort(mFiles, new FileComparator());
        }
        mAdapter.notifyDataSetChanged();
        Button b = (Button) mView.findViewById(R.id.button_right);
        if (isAtSdHome()) {
            // at SD card home, disable Up button
            b.setEnabled(false);
        } else {
            b.setEnabled(true);
        }
        TextView tv = (TextView) mView.findViewById(R.id.header_text);
        tv.setText(getString(R.string.header_text_path) + mDirectory.getPath());
    }

    private boolean isAtSdHome() {
        return mDirectory.compareTo(Environment.getExternalStorageDirectory().getAbsoluteFile()) == 0;
    }

    View.OnClickListener mClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
            case R.id.button_left:
                mDirectory = Environment.getExternalStorageDirectory().getAbsoluteFile();
                refreshFilesList();
                break;
            case R.id.button_right:
                mDirectory = mDirectory.getParentFile();
                refreshFilesList();
                break;
            case R.id.list_complex_more_button:
                View row = (View) v.getTag();
                final File f = (File) row.getTag();
                mQuickAction = new QuickAction(getActivity());
                if (f.isFile()) {
                    mQuickAction.addActionItem(
                            new ActionItem(ACTION_ITEM_UPLOAD, getString(R.string.menu_item_upload_file)));
                    mQuickAction.addActionItem(
                            new ActionItem(ACTION_ITEM_MOVE_TO_TRASH, getString(R.string.menu_item_move_to_trash)));
                } else if (f.isDirectory()) {
                    mQuickAction.addActionItem(
                            new ActionItem(ACTION_ITEM_UPLOAD_FOLDER, getString(R.string.menu_item_upload_folder)));
                }
                mQuickAction.setOnActionItemClickListener(new QuickAction.OnActionItemClickListener() {
                    @Override
                    public void onItemClick(QuickAction source, int pos, int actionId) {
                        switch (actionId) {
                        case ACTION_ITEM_UPLOAD:
                            uploadFile(f);
                            break;
                        case ACTION_ITEM_MOVE_TO_TRASH:
                            moveToTrash(f);
                            break;
                        case ACTION_ITEM_UPLOAD_FOLDER:
                            uploadFolder(f);
                            break;
                        }
                    }
                });
                if (mQuickAction.getActionItem(0) != null) {
                    mQuickAction.show(v);
                }
                break;
            }
        }
    };

    private static final int ACTION_ITEM_MOVE_TO_TRASH = 0;
    private static final int ACTION_ITEM_UPLOAD = 1;
    private static final int ACTION_ITEM_UPLOAD_FOLDER = 2;

    private class NewEventListener extends SyncNewEventListener {

        private NewEventListener(Context context) {
            super(context);
        }

        @Override
        public void onNewSyncDeleteEvent(Uri[] arg0) {
        }

        @Override
        public void onNewSyncInsertEvent(Uri[] arg0) {
        }

        @Override
        public void onNewSyncUpdateEvent(Uri[] arg0) {
        }

        @Override
        public void onSyncComplete(SyncMsg msg) {
            if (needDownload) {
                new DownloadAllTask().execute();
                needDownload = false;
            }
            getListView().post(new Runnable() {
                @Override
                public void run() {
                    mAdapter.notifyDataSetChanged();
                }
            });
        }

        @Override
        public void onSyncStart(String syncMode) {
        }

        @Override
        public void onQuotaExceeded(Uri arg0) {
        }

        @Override
        public void onLocalChangeSyncedEvent(Uri[] uris) {
        }

        @Override
        public void onDownloadComplete(Uri[] arg0) {
        }
    }

    private boolean needDownload = false;

    public class DownloadAllTask extends AsyncTask<Void, Void, Void> {
        @Override
        protected Void doInBackground(Void... params) {
            KiiSyncClient client = KiiSyncClient.getInstance(getActivity());
            if (client != null) {
                KiiFile[] files = client.getBackupFiles();
                if (files != null) {
                    for (KiiFile file : files) {
                        int status = client.getStatus(file);
                        if (!Utils.isKiiFileInTrash(file) && ((status == KiiFile.STATUS_BODY_OUTDATED)
                                || (status == KiiFile.STATUS_NO_BODY))) {
                            client.download(file, Utils.getKiiFileDownloadPath(file));
                        }
                    }
                }
            }
            return null;
        }

    }

    ProgressDialog scanDialog = null;

    public class ScanTask extends AsyncTask<Void, Void, Void> {

        @Override
        protected void onPostExecute(Void result) {
            if (scanDialog != null) {
                scanDialog.dismiss();
                scanDialog = null;
            }
            if (!scanChange.isEmpty()) {
                // TODO: let fragment activity to show dialog;
                getActivity().showDialog(DIALOG_UPDATE);
            } else {
                UiUtils.showToast(getActivity(), "No update is found.");
            }
        }

        @Override
        protected void onPreExecute() {
            if (scanDialog == null) {
                scanDialog = ProgressDialog.show(getActivity(), "", "Scanning for update. Please wait...", true);
            } else {
                if (scanTotalCount > 0) {
                    scanDialog.setMessage(String.format("Scan %d out of %d", scanCurCount, scanTotalCount));
                }
            }
        }

        @Override
        protected Void doInBackground(Void... params) {
            scanFileChange();
            return null;
        }

    }

    static ArrayList<KiiFile> scanChange = null;
    int scanTotalCount = -1;
    int scanCurCount = 0;

    private void scanFileChange() {
        scanChange = new ArrayList<KiiFile>();
        scanTotalCount = -1;
        scanCurCount = 0;
        KiiSyncClient kiiClient = KiiSyncClient.getInstance(getActivity());
        KiiFile[] files = kiiClient.getBackupFiles();
        scanTotalCount = files.length;
        scanCurCount = 0;
        for (; scanCurCount < files.length; scanCurCount++) {
            if (files[scanCurCount].isFile()) {
                if (Utils.bodySameAsLocal(files[scanCurCount])) {
                    scanChange.add(files[scanCurCount]);
                }
            }
        }
    }

    public static List<KiiFile> getLocalChanges() {
        return scanChange;
    }

    public static final int DIALOG_UPDATE = 101;

}