org.wheelmap.android.activity.MainMultiPaneActivity.java Source code

Java tutorial

Introduction

Here is the source code for org.wheelmap.android.activity.MainMultiPaneActivity.java

Source

/*
 * #%L
 * Wheelmap - App
 * %%
 * Copyright (C) 2011 - 2012 Michal Harakal - Michael Kroez - Sozialhelden e.V.
 * %%
 * Wheelmap App based on the Wheelmap Service by Sozialhelden e.V.
 * 
 * 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.
 * #L%
 */
package org.wheelmap.android.activity;

import com.nineoldandroids.animation.Animator;
import com.nineoldandroids.animation.Animator.AnimatorListener;
import com.nineoldandroids.animation.ObjectAnimator;
import org.mapsforge.android.maps.GeoPoint;
import org.wheelmap.android.activity.listeners.Progress;
import org.wheelmap.android.activity.profile.ProfileActivity;
import org.wheelmap.android.analytics.AnalyticsTrackingManager;
import org.wheelmap.android.app.WheelmapApp;
import org.wheelmap.android.fragment.CombinedWorkerFragment;
import org.wheelmap.android.fragment.DisplayFragmentListener;
import org.wheelmap.android.fragment.ErrorDialogFragment;
import org.wheelmap.android.fragment.POIDetailFragment;
import org.wheelmap.android.fragment.POIDetailFragment.OnPOIDetailListener;
import org.wheelmap.android.fragment.POIsListFragment;
import org.wheelmap.android.fragment.POIsOsmdroidFragment;
import org.wheelmap.android.fragment.SearchDialogCombinedFragment;
import org.wheelmap.android.fragment.SearchDialogFragment;
import org.wheelmap.android.fragment.WheelchairAccessibilityStateFragment;
import org.wheelmap.android.fragment.WheelchairToiletStateFragment;
import org.wheelmap.android.fragment.WorkerFragmentListener;
import org.wheelmap.android.manager.MyLocationManager;
import org.wheelmap.android.model.Extra;
import org.wheelmap.android.model.MapModeType;
import org.wheelmap.android.model.PrepareDatabaseHelper;
import org.wheelmap.android.model.Request;
import org.wheelmap.android.model.WheelchairFilterState;
import org.wheelmap.android.model.Wheelmap.POIs;
import org.wheelmap.android.modules.AppProperties;
import org.wheelmap.android.modules.IAppProperties;
import org.wheelmap.android.modules.UserCredentials;
import org.wheelmap.android.online.R;
import org.wheelmap.android.popup.FilterWindow;
import org.wheelmap.android.service.RestServiceException;
import org.wheelmap.android.service.RestServiceHelper;
import org.wheelmap.android.utils.MapActivityUtils;
import org.wheelmap.android.utils.PressSelector;
import org.wheelmap.android.utils.SmoothInterpolator;
import android.animation.LayoutTransition;
import android.annotation.SuppressLint;
import android.content.ContentValues;
import android.content.Intent;
import android.content.res.Configuration;
import android.location.Location;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.Window;
import android.view.animation.Interpolator;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBar.LayoutParams;
import de.akquinet.android.androlog.Log;
import de.keyboardsurfer.android.widget.crouton.Crouton;
import de.keyboardsurfer.android.widget.crouton.Style;
import hotchemi.android.rate.AppRate;

public class MainMultiPaneActivity extends MapActivity implements DisplayFragmentListener, WorkerFragmentListener,
        OnPOIDetailListener, OnClickListener, Progress.Provider {

    private static final String TAG = MainMultiPaneActivity.class.getSimpleName();

    IAppProperties appProperties;

    private POIsListFragment mListFragment;

    private POIsOsmdroidFragment mMapFragment;

    private POIDetailFragment mDetailFragment;

    private CombinedWorkerFragment mWorkerFragment;

    private ViewGroup mMovableLayout;

    private ImageButton mResizeButton;

    private static final Interpolator SMOOTH_INTERPOLATOR = new SmoothInterpolator();

    private static final long MOVABLE_ANIMATION_DURATION = 800;

    private boolean mMovableVisible;

    private boolean mMovableAnimationRunning;

    Long poiIdSelected = Extra.ID_UNKNOWN;

    private MapModeType mapModeType;

    private WheelmapApp app;

    private String address = null;

    private boolean onRefresh = false;

    /**
     * used for testCases
     */
    Progress.Listener mProgressListener;

    @SuppressLint("NewApi")
    @Override
    public void onCreate(Bundle savedInstanceState) {

        requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
        requestWindowFeature(Window.FEATURE_ACTION_BAR);

        super.onCreate(savedInstanceState);

        appProperties = new AppProperties(WheelmapApp.getApp());
        Log.d(TAG, "onCreate");

        setProgressBarIndeterminate(true);
        setSupportProgressBarIndeterminateVisibility(false);

        getSupportActionBar().setDisplayShowTitleEnabled(false);
        getSupportActionBar().setHomeButtonEnabled(false);

        setContentView(R.layout.activity_multipane);
        mMovableLayout = (ViewGroup) findViewById(R.id.movable_layout);
        mResizeButton = (ImageButton) findViewById(R.id.button_movable_resize);

        ViewGroup g = (ViewGroup) findViewById(R.id.layout_multi);
        if (Build.VERSION.SDK_INT > 16) {
            g.getLayoutTransition().disableTransitionType(LayoutTransition.APPEARING);
        }

        if (savedInstanceState != null) {
            executeState(savedInstanceState);
        } else {
            executeDefaultInstanceState();
        }

        Bundle extras = getIntent().getExtras();
        if (extras.containsKey(Extra.MAP_MODE_ENGAGE)) {
            mapModeType = MapModeType.MAP_MODE_ENGAGE;
        } else {
            mapModeType = MapModeType.MAP_MODE_NORMAL;
        }

        ActionBar actionBar = getSupportActionBar();
        actionBar.setDisplayShowTitleEnabled(false);

        mResizeButton.setOnClickListener(this);

        FragmentManager fm = getSupportFragmentManager();
        FragmentTransaction t = fm.beginTransaction();

        mWorkerFragment = (CombinedWorkerFragment) fm.findFragmentByTag(CombinedWorkerFragment.TAG);

        if (mWorkerFragment == null) {
            mWorkerFragment = new CombinedWorkerFragment();
            t.add(mWorkerFragment, CombinedWorkerFragment.TAG);
        }

        mListFragment = (POIsListFragment) fm.findFragmentById(R.id.list_layout);
        if (mListFragment == null) {
            mListFragment = POIsListFragment.newInstance(false, true);
            t.add(R.id.list_layout, mListFragment, POIsListFragment.TAG);
        }

        mMapFragment = (POIsOsmdroidFragment) fm.findFragmentById(R.id.map_layout);
        if (mMapFragment == null) {
            mMapFragment = POIsOsmdroidFragment.newInstance(false, true);
            t.add(R.id.map_layout, mMapFragment, POIsOsmdroidFragment.TAG);
        }

        mDetailFragment = (POIDetailFragment) fm.findFragmentById(R.id.detail_layout);
        if (mDetailFragment == null) {
            mDetailFragment = POIDetailFragment.newInstance();
            t.add(R.id.detail_layout, mDetailFragment);
        }

        t.commit();

        WheelmapApp.checkForUpdates(this);

        app = (WheelmapApp) this.getApplication();
        String uri = null;

        try {
            address = app.getAddressString();
        } catch (Exception ex) {
        }

        if (address != null) {
            showSearch();
        }

        // Show a dialog if meets conditions
        AppRate.showRateDialogIfMeetsConditions(this);

    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        Log.d(TAG, "onNewIntent");
        setIntent(intent);
    }

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

        if (getIntent() != null) {
            executeIntent(getIntent());
            setIntent(null);
        }

        WheelmapApp.checkForCrashes(this);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }

    private void executeIntent(Intent intent) {
        Bundle extras = intent.getExtras();
        if (extras == null) {
            return;
        }

        executeState(extras);
    }

    private void executeState(Bundle state) {
        mMovableVisible = state.getBoolean(Extra.MOVABLE_VISIBLE);
        if (!mMovableVisible) {
            setMovableGone();
        }
    }

    private void executeDefaultInstanceState() {
        setMovableGone();
        AnalyticsTrackingManager.trackScreen(AnalyticsTrackingManager.TrackableScreensName.MAPSCREEN);
        if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
            AnalyticsTrackingManager.trackScreen(AnalyticsTrackingManager.TrackableScreensName.NEARBYSCREEN);
        }
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putBoolean(Extra.MOVABLE_VISIBLE, mMovableVisible);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        ActionBar bar = getSupportActionBar();
        if (bar == null) {
            return true;
        }

        LayoutInflater inflater = LayoutInflater.from(this);
        View customView = inflater.inflate(R.layout.actionbar_tablet, null);
        bar.setCustomView(customView, new ActionBar.LayoutParams(LayoutParams.MATCH_PARENT,
                LayoutParams.MATCH_PARENT, Gravity.CENTER_VERTICAL | Gravity.END));

        boolean isPortraitMode = getResources()
                .getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;
        if (isPortraitMode) {

            ImageView addItem = (ImageView) customView.findViewById(R.id.menu_new_poi);
            addItem.setVisibility(View.VISIBLE);
            OnClickListener addClickListener = new OnClickListener() {
                @Override
                public void onClick(View v) {
                    createNewPoi();
                }
            };
            addItem.setOnClickListener(addClickListener);

            LinearLayout l = (LinearLayout) findViewById(R.id.actionbar_bottom);
            for (int i = 0; i < l.getChildCount(); i++) {
                l.getChildAt(i).setOnTouchListener(new PressSelector());
            }

            bar.setDisplayShowCustomEnabled(true);
            View v = findViewById(R.id.menu_filter);
            MapActivityUtils.setAccessFilterOptionDrawable(this, null, v);

            View filterWc = findViewById(R.id.menu_wc);
            MapActivityUtils.setWcFilterOptionsDrawable(this, null, filterWc);

            UserCredentials credentials = new UserCredentials(getApplicationContext());
            ImageView image = (ImageView) findViewById(R.id.menu_login);
            image.setImageResource(
                    credentials.isLoggedIn() ? R.drawable.start_icon_logged_in : R.drawable.start_icon_login);
        } else {
            MenuInflater inflaterMenu = getMenuInflater();
            inflaterMenu.inflate(R.menu.ab_multi_activity, menu);
            MenuItem item = menu.findItem(R.id.menu_filter);
            MapActivityUtils.setAccessFilterOptionDrawable(this, item, null);
            item = menu.findItem(R.id.menu_wc);
            MapActivityUtils.setWcFilterOptionsDrawable(this, item, null);

        }

        if (mapModeType == MapModeType.MAP_MODE_ENGAGE) {
            MenuItem itemFilterWheelChairs = menu.findItem(R.id.menu_filter);
            itemFilterWheelChairs.setEnabled(false);
            //TODO Disable it - doesn't work yet
        }

        ImageView listMapToggle = (ImageView) findViewById(R.id.switch_view);
        if (listMapToggle != null) {
            listMapToggle.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    toggleMovableResize();
                }
            });
        }

        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        boolean b = onOptionItemClicked(item.getItemId(), item.getActionView(), item);
        return b ? b : super.onOptionsItemSelected(item);
    }

    public void onOptionItemBottomClicked(View v) {
        onOptionItemClicked(v.getId(), v, null);
    }

    /*
     * combined method to handle actionbar menu and custom bottom menu
     */
    public boolean onOptionItemClicked(int id, View v, MenuItem item) {

        switch (id) {
        case R.id.menu_search:
            if (mWorkerFragment.isSearchMode()) {
                mWorkerFragment.setSearchMode(false);
                mWorkerFragment.requestUpdate(null);
            } else {
                showSearch();
            }
            return true;
        case R.id.menu_filter_kategorie:
            showFilterCategories();
            return true;
        case R.id.menu_filter:
        case R.id.menu_wc:
            View anchor = v;
            if (anchor == null) {
                anchor = item.getActionView();
            }
            showFilterSettings(item, v, anchor);
            return true;
        case R.id.menu_about:
            showInfo();
            return true;
        case R.id.menu_new_poi:
            createNewPoi();
            return true;
        case android.R.id.home:
            finish();
            return true;
        case R.id.menu_login:
            showAccount();
            return true;
        case R.id.menu_news:
            showNews();
            return true;
        default:
            return false;
        }
    }

    private void showNews() {
        Intent intent = new Intent(this, WebViewNewsActivity.class);
        startActivity(intent);
    }

    private void showAccount() {
        Intent intent = new Intent(this, ProfileActivity.class);
        startActivityForResult(intent, Request.REQUEST_CODE_LOGIN);
    }

    private void showSearch() {
        FragmentManager fm = getSupportFragmentManager();
        SearchDialogCombinedFragment searchDialog = SearchDialogCombinedFragment.newInstance();

        searchDialog.setTargetFragment(mWorkerFragment, 0);
        searchDialog.show(fm, SearchDialogFragment.TAG);
    }

    private void showInfo() {
        Intent intent = new Intent(this, InfoActivity.class);
        startActivity(intent);
    }

    private void showFilterCategories() {
        Intent intent = new Intent(this, FilterActivity.class);
        intent.putExtra(Extra.FILTER_CATEGORIES, true);
        startActivity(intent);
    }

    private void showFilterSettings(MenuItem menuItem, View menuView, View anchor) {
        FilterWindow filter = new FilterWindow(this, null, menuView);
        filter.showAsDropDown(anchor);
    }

    private long insertNewPoi() {
        Location location = MyLocationManager.getLastLocation();
        String name = getString(R.string.poi_new_default_name);
        long id = PrepareDatabaseHelper.insertNew(getContentResolver(), name, location.getLatitude(),
                location.getLongitude());
        return id;
    }

    private void createNewPoi() {
        long poiId = insertNewPoi();
        Intent i = new Intent(this, POIDetailEditableActivity.class);
        i.putExtra(Extra.POI_ID, poiId);
        startActivity(i);
    }

    @Override
    public void onError(RestServiceException e) {
        if (e.isNetworkError()) {
            String error = getString(R.string.error_network_failure);
            try {
                error = getString(e.getRessourceString());
            } catch (Exception ex) {
            }
            Crouton.makeText(this, error, Style.ALERT).show();
            return;
        }

        FragmentManager fm = getSupportFragmentManager();
        ErrorDialogFragment errorDialog = ErrorDialogFragment.newInstance(e, Extra.UNKNOWN);
        if (errorDialog == null) {
            return;
        }

        errorDialog.show(fm, ErrorDialogFragment.TAG);
    }

    @Override
    public void onShowDetail(Fragment fragment, ContentValues values) {
        long copyId = PrepareDatabaseHelper.createCopyFromContentValues(getContentResolver(), values, true);
        poiIdSelected = copyId;

        if (!mMovableVisible) {
            toggleMovableResize();
        }
        mDetailFragment.showDetail(poiIdSelected);

        if (fragment == mListFragment) {
            mMapFragment.markItem(values, true);
        }

        if (fragment == mMapFragment) {
            mListFragment.markItem(values, false);
        }
    }

    @Override
    public void onRefreshing(boolean isRefreshing) {
        Log.d(TAG, "onRefreshing isRefreshing = " + isRefreshing);

        onRefresh = isRefreshing;

        if (mProgressListener != null && isRefreshing) {
            mProgressListener.onProgressChanged(true);
        }

        if (isRefreshing) {
            if (getSupportActionBar() != null && getSupportActionBar().getCustomView() != null) {
                View progress = getSupportActionBar().getCustomView().findViewById(R.id.progress);
                if (progress.getVisibility() != View.VISIBLE) {
                    progress.setVisibility(View.VISIBLE);
                    checkProgressHide();
                }
            }
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        onRefresh = false;
    }

    private void checkProgressHide() {
        if (!onRefresh) {

            if (getSupportActionBar() != null && getSupportActionBar().getCustomView() != null) {
                getSupportActionBar().getCustomView().findViewById(R.id.progress).setVisibility(View.INVISIBLE);
            }

            if (mProgressListener != null) {
                mProgressListener.onProgressChanged(false);
            }
        } else {
            new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
                @Override
                public void run() {
                    checkProgressHide();
                }
            }, 500);
        }
    }

    @Override
    public void onSearchModeChange(boolean isSearchMode) {
        Log.d(TAG, "onSearchModeChange: showing custom view in actionbar");
        getSupportActionBar().setDisplayShowCustomEnabled(true);
    }

    @Override
    public void onEdit(long poiId, int focus) {
        Intent intent = new Intent(this, POIDetailEditableActivity.class);
        intent.putExtra(Extra.POI_ID, poiId);
        intent.putExtra("Focus", focus);
        startActivity(intent);
    }

    @Override
    public void onEditWheelchairState(WheelchairFilterState wState) {
        Intent intent = new Intent(this, WheelchairStateActivity.class);
        intent.putExtra(Extra.WHEELCHAIR_STATE, wState.getId());
        startActivityForResult(intent, Request.SELECT_WHEELCHAIRSTATE);
    }

    @Override
    public void onEditWheelchairToiletState(WheelchairFilterState wState) {
        Intent intent = new Intent(this, WheelchairStateActivity.class);
        intent.putExtra(Extra.WHEELCHAIR_TOILET_STATE, wState.getId());
        startActivityForResult(intent, Request.SELECT_WHEELCHAIRSTATE);
    }

    @Override
    public void onShowLargeMapAt(GeoPoint point) {
        // noop
    }

    @Override
    public void dismissDetailView() {
        toggleMovableResize();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        Log.d(TAG, "onActivityResult: requestCode = " + requestCode + " resultCode = " + resultCode);
        if (requestCode == Request.SELECT_WHEELCHAIRSTATE && resultCode == RESULT_OK && data != null) {
            if (data.hasExtra(WheelchairAccessibilityStateFragment.TAG)) {
                WheelchairFilterState state = WheelchairFilterState
                        .valueOf(data.getIntExtra(WheelchairAccessibilityStateFragment.TAG, Extra.UNKNOWN));
                if (state != null) {
                    updateDatabase(poiIdSelected, POIs.WHEELCHAIR, state);
                }
            } else if (data.hasExtra(WheelchairToiletStateFragment.TAG)) {
                WheelchairFilterState state = WheelchairFilterState
                        .valueOf(data.getIntExtra(WheelchairToiletStateFragment.TAG, Extra.UNKNOWN));
                if (state != null) {
                    updateDatabase(poiIdSelected, POIs.WHEELCHAIR_TOILET, state);
                }
            } else {
                return;
            }
            Log.d(TAG, "starting RestServiceHelper.executeUpdateServer");
            RestServiceHelper.executeUpdateServer(this, null);

        }
        if (requestCode == Request.REQUEST_CODE_LOGIN) {
            ImageView image = (ImageView) findViewById(R.id.menu_login);
            if (image != null) {
                image.setImageResource(
                        resultCode == RESULT_OK ? R.drawable.start_icon_logged_in : R.drawable.start_icon_login);
            }
        }

        super.onActivityResult(requestCode, resultCode, data);
    }

    private void updateDatabase(long id, String poiColumnName, WheelchairFilterState state) {
        if (id == Extra.ID_UNKNOWN || state == null) {
            return;
        }
        Log.d(TAG, "updating id = " + id + " state = " + state.asRequestParameter());

        ContentValues values = new ContentValues();
        values.put(poiColumnName, state.getId());
        values.put(POIs.DIRTY, POIs.DIRTY_STATE);

        PrepareDatabaseHelper.editCopy(getContentResolver(), id, values);
    }

    @Override
    public void onClick(View v) {
        int id = v.getId();

        switch (id) {
        case R.id.button_movable_resize:
            toggleMovableResize();
        }
    }

    private AnimatorListener mMovableAnimatorListener = new AnimatorListener() {

        @Override
        public void onAnimationStart(Animator animation) {
            mMapFragment.setHeightFull(!mMovableVisible);
            if (mMovableVisible) {
                mMovableLayout.setVisibility(View.VISIBLE);
            }
        }

        @Override
        public void onAnimationEnd(Animator animation) {
            if (!mMovableVisible) {
                mMovableLayout.setVisibility(View.GONE);
            }

            mMovableAnimationRunning = false;
        }

        @Override
        public void onAnimationCancel(Animator animation) {

        }

        @Override
        public void onAnimationRepeat(Animator animation) {

        }

    };

    private void setCollapseButtonImage(boolean toCollapse) {
        int buttonDrawableRes;
        if (toCollapse) {
            buttonDrawableRes = R.drawable.ic_detail_collapse;
        } else {
            buttonDrawableRes = R.drawable.ic_detail_expand;
        }
        mResizeButton.setImageResource(buttonDrawableRes);

    }

    private void setMovableGone() {
        mMovableVisible = false;
        Log.d(TAG, "setMovableGone height = " + (-mMovableLayout.getHeight()));
        mMovableLayout.setVisibility(View.INVISIBLE);
    }

    private void toggleMovableResize() {
        if (mMovableAnimationRunning) {
            return;
        }
        mMovableAnimationRunning = true;
        setCollapseButtonImage(!mMovableVisible);

        boolean land = getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
        String change = land ? "translationX" : "translationY";

        float startValue;
        float endValue;
        if (mMovableVisible) {
            startValue = 0.0f;
            if (land) {
                endValue = -mMovableLayout.getWidth();
            } else {
                endValue = -mMovableLayout.getHeight();
            }
            mMovableVisible = false;
        } else {
            if (land) {
                startValue = -mMovableLayout.getWidth();
            } else {
                startValue = -mMovableLayout.getHeight();
                AnalyticsTrackingManager.trackScreen(AnalyticsTrackingManager.TrackableScreensName.NEARBYSCREEN);
            }
            endValue = 0.0f;
            mMovableVisible = true;
        }

        ObjectAnimator anim = ObjectAnimator.ofFloat(mMovableLayout, change, startValue, endValue);
        anim.setInterpolator(SMOOTH_INTERPOLATOR);
        anim.setDuration(MOVABLE_ANIMATION_DURATION);
        anim.addListener(mMovableAnimatorListener);
        anim.start();
    }

    @Override
    public void onRefreshEnabled(boolean refreshEnabled) {

    }

    @Override
    public void refreshRegisterList(ListView listView) {

    }

    @Override
    public void onBackPressed() {
        WheelmapApp app = (WheelmapApp) this.getApplicationContext();

        if (app.isSaved()) {
            app.setSaved(false);
            mWorkerFragment.setSearchMode(false);
            mWorkerFragment.requestUpdate(null);
        } else {
            if (mMovableVisible && !mMovableAnimationRunning) {
                toggleMovableResize();
                return;
            }
            super.onBackPressed();
        }
    }

    @Override
    public void addProgressListener(Progress.Listener listener) {
        mProgressListener = listener;
    }
}