org.huxizhijian.hhcomicviewer.ui.entry.ComicDetailsActivity.java Source code

Java tutorial

Introduction

Here is the source code for org.huxizhijian.hhcomicviewer.ui.entry.ComicDetailsActivity.java

Source

/*
 * Copyright 2017 huxizhijian
 *
 * 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 org.huxizhijian.hhcomicviewer.ui.entry;

import android.Manifest;
import android.animation.Animator;
import android.annotation.TargetApi;
import android.app.SearchManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.res.ColorStateList;
import android.databinding.DataBindingUtil;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.NonNull;
import android.support.design.widget.AppBarLayout;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.transition.ArcMotion;
import android.transition.Fade;
import android.transition.Transition;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewAnimationUtils;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

import com.rey.material.app.BottomSheetDialog;

import org.huxizhijian.hhcomicviewer.app.HHApplication;
import org.huxizhijian.hhcomicviewer.R;
import org.huxizhijian.hhcomicviewer.adapter.VolDownloadSelectorAdapter;
import org.huxizhijian.hhcomicviewer.adapter.VolRecyclerViewAdapter;
import org.huxizhijian.hhcomicviewer.databinding.ActivityComicDetailsBinding;
import org.huxizhijian.hhcomicviewer.db.ComicChapterDBHelper;
import org.huxizhijian.hhcomicviewer.db.ComicDBHelper;
import org.huxizhijian.hhcomicviewer.model.Comic;
import org.huxizhijian.hhcomicviewer.model.ComicChapter;
import org.huxizhijian.hhcomicviewer.presenter.IComicDetailsPresenter;
import org.huxizhijian.hhcomicviewer.presenter.implpersenter.ComicDetailsPresenter;
import org.huxizhijian.hhcomicviewer.presenter.viewinterface.IComicDetailsActivity;
import org.huxizhijian.hhcomicviewer.service.DownloadManagerService;
import org.huxizhijian.hhcomicviewer.ui.search.SearchActivity;
import org.huxizhijian.hhcomicviewer.utils.CommonUtils;
import org.huxizhijian.hhcomicviewer.utils.Constants;
import org.huxizhijian.hhcomicviewer.utils.CustomChangeBounds;
import org.huxizhijian.hhcomicviewer.utils.IMMLeaks;
import org.huxizhijian.hhcomicviewer.view.FullyGridLayoutManager;
import org.huxizhijian.sdk.imageloader.ImageLoaderOptions;
import org.huxizhijian.sdk.imageloader.listener.ImageLoaderManager;
import org.huxizhijian.sdk.imageloader.listener.ImageRequestListener;
import org.huxizhijian.sdk.util.StatusBarUtil;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import cn.sharesdk.onekeyshare.OnekeyShare;

import static org.huxizhijian.sdk.util.TransitionLeakFixUtil.removeActivityFromTransitionManager;

public class ComicDetailsActivity extends AppCompatActivity implements View.OnClickListener, IComicDetailsActivity {

    private static final int CHECK_SD_WRITE_PERMISSION = 0x00;
    private ActivityComicDetailsBinding mBinding = null;

    //??
    private ComicDBHelper mComicDBHelper;
    private ComicChapterDBHelper mComicChapterDBHelper;

    //?
    private List<ComicChapter> mDownloadedComicChapters; //
    private List<String> mFinishedComicChapters; //???
    private Comic mComic;
    private List<String> mSelectedChapters;
    private int mCid;
    private boolean isDescriptionOpen = false;
    private boolean isDescriptionCanOpen = false;
    private int mDetailsHeight;
    private int mBackHeight;

    private static final int MSG_UPDATE_VIEW = 0x02;

    //
    private ImageLoaderManager mImageLoader = ImageLoaderOptions.getImageLoaderManager();

    //adapter
    private VolRecyclerViewAdapter mVolAdapter;

    private IComicDetailsPresenter mPresenter;

    //Handler?
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == Constants.MSG_DOWNLOAD) {
                ComicChapter chapter = (ComicChapter) msg.obj;
                Intent intent = new Intent(ComicDetailsActivity.this, DownloadManagerService.class);
                intent.setAction(DownloadManagerService.ACTION_START);
                intent.putExtra("comicChapter", chapter);
                startService(intent);
            } else if (msg.what == MSG_UPDATE_VIEW) {
                updateViews();
            }
        }
    };

    //
    private ComicChapterDownloadUpdateReceiver mReceiver;
    private LocalBroadcastManager mManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mBinding = DataBindingUtil.setContentView(this, R.layout.activity_comic_details);
        initView();
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
            setupEnterAnimations();
            setupExitAnimations();
            setMotion();
        }
        preLoadingImageAndTitle();
        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            initSlideShapeTheme();
        }
        initDBValues();
        setupAppBarListener();
        initData();
    }

    /**
     * ???
     */
    private void initSlideShapeTheme() {
        // ??toolbar+??*/
        mBinding.ivTitleHeadBg.setVisibility(View.VISIBLE);
        //        ViewGroup.LayoutParams params = mBinding.ivTitleHeadBg.getLayoutParams();
        ViewGroup.MarginLayoutParams ivTitleHeadBgParams = (ViewGroup.MarginLayoutParams) mBinding.ivTitleHeadBg
                .getLayoutParams();
        //        int marginTop = params.height - headerBgHeight;
        ivTitleHeadBgParams.setMargins(0, 0, 0, 0);
        // View????
        StatusBarUtil.setTranslucentImageHeader(this, 59, mBinding.toolbarComicDetails);
    }

    private CollapsingToolbarLayoutState state;

    @Override
    public void onResponse(Comic comic) {
        mComic = comic;
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                updateViews();
            }
        });
    }

    @Override
    public void onException(Throwable e) {
        e.printStackTrace();
        if (CommonUtils.getAPNType(ComicDetailsActivity.this) == CommonUtils.NONEWTWORK) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Toast.makeText(ComicDetailsActivity.this, Constants.NO_NETWORK, Toast.LENGTH_SHORT).show();
                    //???
                    if (mComic != null) {
                        if (mComic.isMark() || mComic.isDownload()) {
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    updateViews();
                                }
                            });
                        }
                    }
                }
            });
        } else {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    mBinding.FABComicDetails.setBackgroundTintList(
                            ColorStateList.valueOf(getResources().getColor(R.color.colorAccent)));
                    Toast.makeText(ComicDetailsActivity.this, "?", Toast.LENGTH_SHORT).show();
                }
            });
        }
    }

    @Override
    public void onFailure(int errorCode, String errorMsg) {
        if (CommonUtils.getAPNType(ComicDetailsActivity.this) == CommonUtils.NONEWTWORK) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Toast.makeText(ComicDetailsActivity.this, Constants.NO_NETWORK, Toast.LENGTH_SHORT).show();
                    //???
                    if (mComic != null) {
                        if (mComic.isMark() || mComic.isDownload()) {
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    updateViews();
                                }
                            });
                        }
                    }
                }
            });
        } else {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    mBinding.FABComicDetails.setBackgroundTintList(
                            ColorStateList.valueOf(getResources().getColor(R.color.colorAccent)));
                    Toast.makeText(ComicDetailsActivity.this, "?", Toast.LENGTH_SHORT).show();
                }
            });
        }
    }

    private enum CollapsingToolbarLayoutState {
        EXPANDED, //
        COLLAPSED, //
        INTERNEDIATE //
    }

    private void setupAppBarListener() {
        //?readButton?
        mBinding.appBarComicDetails.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
            @Override
            public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
                if (verticalOffset == 0) {
                    if (state != CollapsingToolbarLayoutState.EXPANDED) {
                        mBinding.llIvAndDetails.setVisibility(View.VISIBLE);
                        state = CollapsingToolbarLayoutState.EXPANDED;//?
                    }
                } else if (Math.abs(verticalOffset) >= appBarLayout.getTotalScrollRange()) {
                    if (state != CollapsingToolbarLayoutState.COLLAPSED) {
                        mBinding.readButton.setVisibility(View.VISIBLE);//
                        mBinding.llIvAndDetails.setVisibility(View.GONE); //??
                        state = CollapsingToolbarLayoutState.COLLAPSED;//??
                    }
                } else {
                    if (state != CollapsingToolbarLayoutState.INTERNEDIATE) {
                        if (state == CollapsingToolbarLayoutState.COLLAPSED) {
                            mBinding.readButton.setVisibility(View.GONE);//?????
                            mBinding.llIvAndDetails.setVisibility(View.VISIBLE);
                        }
                        state = CollapsingToolbarLayoutState.INTERNEDIATE;//?
                    }
                }
            }
        });
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private void animateRevealShow(View viewRoot) {
        //???
        int cx = (viewRoot.getLeft() + viewRoot.getRight()) / 2;
        int cy = (viewRoot.getTop() + viewRoot.getBottom()) / 2;
        //?
        int finalRadius = Math.max(viewRoot.getWidth(), viewRoot.getHeight());

        Animator anim = ViewAnimationUtils.createCircularReveal(viewRoot, cx, cy, 0, finalRadius);
        viewRoot.setVisibility(View.VISIBLE); //??
        anim.setDuration(getResources().getInteger(R.integer.anim_duration_medium));//
        anim.setInterpolator(new AccelerateInterpolator());//? ??
        anim.start();
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private void setupEnterAnimations() {
        Fade enterTransition = new Fade(); //
        getWindow().setEnterTransition(enterTransition);
        enterTransition.setDuration(getResources().getInteger(R.integer.anim_duration_medium));//
        enterTransition.addListener(new Transition.TransitionListener() {
            @Override
            public void onTransitionStart(Transition transition) {
                transition.removeListener(this);
                animateRevealShow(mBinding.appBarComicDetails);//toolbar
            }

            @Override
            public void onTransitionEnd(Transition transition) {

            }

            @Override
            public void onTransitionCancel(Transition transition) {

            }

            @Override
            public void onTransitionPause(Transition transition) {

            }

            @Override
            public void onTransitionResume(Transition transition) {

            }
        });
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private void setupExitAnimations() {
        Fade returnTransition = new Fade(); //
        getWindow().setReturnTransition(returnTransition);
        returnTransition.setDuration(getResources().getInteger(R.integer.anim_duration_medium));//
        returnTransition.addListener(new Transition.TransitionListener() {
            @Override
            public void onTransitionStart(Transition transition) {
                //?
                transition.removeListener(this);
                mBinding.FABComicDetails.setVisibility(View.INVISIBLE);
            }

            @Override
            public void onTransitionEnd(Transition transition) {
            }

            @Override
            public void onTransitionCancel(Transition transition) {
            }

            @Override
            public void onTransitionPause(Transition transition) {
            }

            @Override
            public void onTransitionResume(Transition transition) {
            }
        });
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private void setMotion() {
        // Activity Shared Element?
        //ArcMotion
        ArcMotion arcMotion = new ArcMotion();
        arcMotion.setMinimumHorizontalAngle(50f);
        arcMotion.setMinimumVerticalAngle(50f);
        //?
        Interpolator interpolator = AnimationUtils.loadInterpolator(this, android.R.interpolator.fast_out_slow_in);
        //ChangeBounds
        CustomChangeBounds changeBounds = new CustomChangeBounds();
        changeBounds.setPathMotion(arcMotion);
        changeBounds.setInterpolator(interpolator);
        changeBounds.addTarget(mBinding.comicThumbnailComicDetails);
        //??Activity
        getWindow().setSharedElementEnterTransition(changeBounds);
        getWindow().setSharedElementReturnTransition(changeBounds);
    }

    private void preLoadingImageAndTitle() {
        Intent intent = getIntent();
        mCid = intent.getIntExtra("cid", 21301);
        String thumbnailUrl = intent.getStringExtra("thumbnailUrl");
        String title = intent.getStringExtra("title");

        //
        mImageLoader.displayThumbnail(this, thumbnailUrl, mBinding.comicThumbnailComicDetails, R.mipmap.blank,
                R.mipmap.blank, 165, 220);

        mBinding.comicTitleComicDetails.setText(title);

        // ??
        mImageLoader.displayBlurImage(this, thumbnailUrl, mBinding.ivTitleHeadBg, 165, 220, 14, 3,
                new ImageRequestListener() {
                    @Override
                    public void onException(Throwable throwable) {
                        throwable.printStackTrace();
                    }

                    @Override
                    public void onResourceReady() {
                        // Toolbar?
                        mBinding.toolbarComicDetails.setBackgroundColor(Color.TRANSPARENT);
                        mBinding.ivTitleHeadBg.setVisibility(View.VISIBLE);
                    }

                });
    }

    private void initData() {
        if (mComic == null) {
            mBinding.FABComicDetails.setBackgroundTintList(ColorStateList.valueOf(Color.GRAY));
        }
        mComic = mComicDBHelper.findByCid(mCid);
        if (CommonUtils.getAPNType(this) == CommonUtils.NONEWTWORK) {
            mBinding.FABComicDetails
                    .setBackgroundTintList(ColorStateList.valueOf(getResources().getColor(R.color.colorAccent)));
            Toast.makeText(this, Constants.NO_NETWORK, Toast.LENGTH_SHORT).show();
            if (mComic.getChapterName() != null) {
                mHandler.sendEmptyMessageDelayed(MSG_UPDATE_VIEW, 600);
            }
        } else {
            mPresenter = new ComicDetailsPresenter(this);
            mPresenter.getComic(mCid, mComic);
        }
        mReceiver = new ComicChapterDownloadUpdateReceiver();
    }

    private void updateViews() {
        //?
        mBinding.comicAuthorComicDetails.setVisibility(View.VISIBLE);
        mBinding.comicAuthorComicDetails.setText(mComic.getAuthor());
        mBinding.comicVolStatusComicDetails.setText(mComic.getComicStatus());
        mBinding.comicFavoriteNumberComicDetails.setText(mComic.getComicFavorite());
        mBinding.comicUpdateTimeComicDetails.setText(mComic.getComicUpdateTime());

        //
        mBinding.comicDescriptionComicDetails.setText(mComic.getDescription());
        //?
        mBinding.comicDescriptionComicDetailsBack.setVisibility(View.VISIBLE);
        mBinding.comicDescriptionComicDetailsBack.setText(mComic.getDescription());
        final ViewTreeObserver vto1 = mBinding.comicDescriptionComicDetails.getViewTreeObserver();
        vto1.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                mDetailsHeight = mBinding.comicDescriptionComicDetails.getHeight();
                //??
                mBinding.comicDescriptionComicDetails.getViewTreeObserver().removeGlobalOnLayoutListener(this);
            }
        });
        //?tv_back 
        ViewTreeObserver vto = mBinding.comicDescriptionComicDetailsBack.getViewTreeObserver();
        vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {

            @Override
            public void onGlobalLayout() {
                mBackHeight = mBinding.comicDescriptionComicDetailsBack.getHeight();
                mBinding.comicDescriptionComicDetailsBack.getViewTreeObserver().removeGlobalOnLayoutListener(this);

                //
                if (mBackHeight > mDetailsHeight) {
                    //
                    mBinding.ivArrow.setVisibility(View.VISIBLE);
                    //?
                    mBinding.comicDescriptionComicDetails.setTag(true);
                    isDescriptionCanOpen = true;
                } else {
                    mBinding.ivArrow.setVisibility(View.GONE);
                    isDescriptionCanOpen = false;
                }

                mBinding.comicDescriptionComicDetailsBack.setVisibility(View.GONE);
            }
        });

        //?
        mBinding.ratingBarComicDetails.setRating((mComic.getRatingNumber() / 10.0f) * 5.0f);
        mBinding.ratingBarDescriptionComicDetails.setText(mComic.getRatingNumber() + "(10), " + ""
                + mComic.getRatingPeopleNum() + "");

        //
        if (mComic.isMark() || mComic.isDownload()) {
            mVolAdapter = new VolRecyclerViewAdapter(ComicDetailsActivity.this, mComic.getChapterName(),
                    mComic.getReadChapter(), mFinishedComicChapters);
        } else {
            mVolAdapter = new VolRecyclerViewAdapter(ComicDetailsActivity.this, mComic.getChapterName(),
                    mFinishedComicChapters);
        }

        //?RecyclerView
        mBinding.recyclerViewComicDetails
                .setLayoutManager(new FullyGridLayoutManager(ComicDetailsActivity.this, 4));
        mBinding.recyclerViewComicDetails.setItemAnimator(new DefaultItemAnimator());
        mBinding.recyclerViewComicDetails.setHasFixedSize(true);
        mBinding.recyclerViewComicDetails.setNestedScrollingEnabled(false);
        mVolAdapter.setOnItemClickListener(new VolRecyclerViewAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(View view, int position) {
                Intent intent = new Intent(ComicDetailsActivity.this, GalleryActivity.class);
                intent.putExtra("comic", mComic);
                intent.putExtra("position", position);
                startActivityForResult(intent, 0);
            }

            @Override
            public void onItemLongClick(View view, int position) {
            }
        });
        mBinding.recyclerViewComicDetails.setAdapter(mVolAdapter);
        mBinding.recyclerViewComicDetails.setFocusable(false);
        mBinding.nestScrollViewComicDetails.setFocusable(true);
        mBinding.nestScrollViewComicDetails.smoothScrollBy(0, 0);

        //??
        if (mComic.isMark()) {
            mBinding.btnFavoriteComicDetails.setImageResource(R.mipmap.my_favorite);
            mBinding.buttonTextFavoriteComicDetails.setText("?");
        }

        //?
        mBinding.FABComicDetails.setOnClickListener(this);
        mBinding.readButton.setOnClickListener(this);
        //
        mBinding.btnFavorite.setOnClickListener(this);
        mBinding.btnShare.setOnClickListener(this);
        mBinding.btnFind.setOnClickListener(this);
        mBinding.btnDownload.setOnClickListener(this);
        //
        mBinding.comicAuthorComicDetails.setOnClickListener(this);
        mBinding.comicDescriptionComicDetailsLl.setOnClickListener(this);

        //??
        mBinding.FABComicDetails
                .setBackgroundTintList(ColorStateList.valueOf(getResources().getColor(R.color.colorAccent)));
        mBinding.linearLayoutComicDetails.setVisibility(View.VISIBLE);
        Animation alpha = AnimationUtils.loadAnimation(this, R.anim.alpha_in);
        //?
        alpha.setInterpolator(new AccelerateInterpolator());
        mBinding.linearLayoutComicDetails.startAnimation(alpha);
    }

    private void initDBValues() {
        mComicDBHelper = ComicDBHelper.getInstance(this);
        mComicChapterDBHelper = ComicChapterDBHelper.getInstance(this);
        //?
        mDownloadedComicChapters = mComicChapterDBHelper.findByComicCid(mCid);
        //??
        if (mDownloadedComicChapters != null) {
            for (int i = 0; i < mDownloadedComicChapters.size(); i++) {
                if (mDownloadedComicChapters.get(i).getDownloadStatus() == Constants.DOWNLOAD_FINISHED) {
                    if (mFinishedComicChapters == null) {
                        mFinishedComicChapters = new ArrayList<>();
                    }
                    mFinishedComicChapters.add(mDownloadedComicChapters.get(i).getChapterName());
                }
            }
        }
    }

    private void initView() {
        //actionBar
        setSupportActionBar(mBinding.toolbarComicDetails);
        ActionBar actionBar = getSupportActionBar();
        if (actionBar != null) {
            actionBar.setDisplayHomeAsUpEnabled(true);
            actionBar.setTitle("");
        }
        mBinding.llIvAndDetails.setPadding(0, StatusBarUtil.getStatusBarHeight(this), 0, 0);

        //        CommonUtils.setStatusBarTint(this, getResources().getColor(R.color.colorPrimaryDark));
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.comic_info, menu);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case android.R.id.home:
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                this.finishAfterTransition();
            } else {
                this.finish();
            }
            return true;
        default:
            return super.onOptionsItemSelected(item);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        //receiver
        IntentFilter filter = new IntentFilter(DownloadManagerService.ACTION_RECEIVER);
        //        registerReceiver(mReceiver, filter);
        if (mManager == null) {
            mManager = LocalBroadcastManager.getInstance(this);
        }
        mManager.registerReceiver(mReceiver, filter);
        //?
        if (mVolAdapter != null && mComicChapterDBHelper != null) {
            mDownloadedComicChapters = mComicChapterDBHelper.findByComicCid(mComic.getCid());
            //??
            if (mDownloadedComicChapters != null && mDownloadedComicChapters.size() != 0) {
                for (int i = 0; i < mDownloadedComicChapters.size(); i++) {
                    if (mDownloadedComicChapters.get(i).getDownloadStatus() == Constants.DOWNLOAD_FINISHED) {
                        if (mFinishedComicChapters == null) {
                            mFinishedComicChapters = new ArrayList<>();
                        }
                        mFinishedComicChapters.add(mDownloadedComicChapters.get(i).getChapterName());
                    }
                }
                mVolAdapter.setFinishedComicChapterList(mFinishedComicChapters);
                //?
                mVolAdapter.notifyDataSetChanged();
            }
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (mComic != null && mComic.getLastReadTime() != 0) {
            mComic.setLastReadTime(System.currentTimeMillis());
            if (mComicDBHelper.findByCid(mComic.getCid()) != null) {
                mComicDBHelper.update(mComic);
                System.out.println("comic update");
            } else {
                mComicDBHelper.add(mComic);
            }
        }

        //receiver
        if (mReceiver != null) {
            if (mManager == null) {
                mManager = LocalBroadcastManager.getInstance(this);
            }
            mManager.unregisterReceiver(mReceiver);
            //            unregisterReceiver(mReceiver);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        IMMLeaks.fixFocusedViewLeak(HHApplication.getInstance());
        if (mPresenter != null)
            mPresenter.removeListener();
        removeActivityFromTransitionManager(this);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        mComic = (Comic) data.getSerializableExtra("comic");
        mComic.setLastReadTime(System.currentTimeMillis());
        if (mVolAdapter != null) {
            mVolAdapter.setReadChapter(mComic.getReadChapter());
        }
    }

    private void read() {
        //?toolbar
        if (mComic == null || mComic.getChapterId() == null || mComic.getChapterId().size() == 0)
            return;
        Intent intent = new Intent(ComicDetailsActivity.this, GalleryActivity.class);
        intent.putExtra("comic", mComic);
        intent.putExtra("position", mComic.getReadChapter() == -1 ? 0 : mComic.getReadChapter());
        startActivityForResult(intent, 0);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.FAB_comic_details:
            read();
            break;
        case R.id.btn_favorite:
            //?
            if (mComic == null)
                return;
            Comic findComic = mComicDBHelper.findByCid(mComic.getCid());
            if (findComic != null) {
                if (findComic.isMark()) {
                    mComic.setMark(false);
                    mComic.setLastReadTime(System.currentTimeMillis());
                    mComicDBHelper.update(mComic);
                    Toast.makeText(ComicDetailsActivity.this, "????", Toast.LENGTH_SHORT).show();
                    mBinding.btnFavoriteComicDetails.setImageResource(R.mipmap.favorite);
                    mBinding.buttonTextFavoriteComicDetails.setText("?");
                } else {
                    mComic.setMark(true);
                    mComic.setLastReadTime(System.currentTimeMillis());
                    mComicDBHelper.update(mComic);
                    Toast.makeText(ComicDetailsActivity.this, "??!", Toast.LENGTH_SHORT).show();
                    mBinding.btnFavoriteComicDetails.setImageResource(R.mipmap.my_favorite);
                    mBinding.buttonTextFavoriteComicDetails.setText("?");
                }
            } else if (mComic != null) {
                mComic.setMark(true);
                mComic.setLastReadTime(System.currentTimeMillis());
                mComicDBHelper.add(mComic);
                mComic.setId(mComicDBHelper.findByCid(mComic.getCid()).getId());
                Toast.makeText(ComicDetailsActivity.this, "??!", Toast.LENGTH_SHORT).show();
                mBinding.btnFavoriteComicDetails.setImageResource(R.mipmap.my_favorite);
                mBinding.buttonTextFavoriteComicDetails.setText("?");
            } else if (mComic == null) {
                Toast.makeText(ComicDetailsActivity.this, "??~",
                        Toast.LENGTH_SHORT).show();
            }
            break;
        case R.id.btn_share:
            //
            if (mComic == null)
                break;

            OnekeyShare oks = new OnekeyShare();
            //sso?
            oks.disableSSOWhenAuthorize();

            // Notification  2.5.9??
            //oks.setNotification(R.drawable.ic_launcher, getString(R.string.app_name));
            // title??????QQ
            oks.setTitle(mComic.getTitle());
            // titleUrlLinked-in,QQQQ
            oks.setTitleUrl(CommonUtils.getComicUrl(mCid));
            // text??
            oks.setText("" + mComic.getTitle()
                    + "???");
            //??????
            oks.setImageUrl(mComic.getThumbnailUrl());
            // imagePathLinked-In???
            //oks.setImagePath("/sdcard/test.jpg");//?SDcard?
            // url??
            oks.setUrl(CommonUtils.getComicUrl(mCid));
            // comment?QQ
            // oks.setComment("");
            // site??QQ
            oks.setSite(getResources().getString(R.string.app_name_short));
            // siteUrl?QQ
            oks.setSiteUrl(Constants.HHCOMIC_URL);

            // ?GUI
            oks.show(this);
            break;
        case R.id.btn_find:
            //???
            searchAuthor();
            break;
        case R.id.btn_download:
            //
            if (mComic == null) {
                Toast.makeText(ComicDetailsActivity.this, "?~", Toast.LENGTH_SHORT).show();
            } else {
                BottomSheetDialog bottomSheetDialog = new BottomSheetDialog(this);
                View view = LayoutInflater.from(this).inflate(R.layout.fragment_download_selector, null);
                //??
                setupContentViewListener(view, bottomSheetDialog);
                bottomSheetDialog.contentView(view);
                bottomSheetDialog.heightParam(ViewGroup.LayoutParams.WRAP_CONTENT);
                bottomSheetDialog.cancelable(true);
                bottomSheetDialog.show();
            }
            break;
        case R.id.comic_author_comic_details:
            //???
            searchAuthor();
            break;
        case R.id.comic_description_comic_details_ll:
            //???
            if (!isDescriptionCanOpen)
                break;

            if (!isDescriptionOpen) {
                mBinding.ivArrow.setImageResource(R.mipmap.arrow_up_black_24dp);
                mBinding.comicDescriptionComicDetails.setMaxLines(1024);
                isDescriptionOpen = !isDescriptionOpen;
            } else {
                mBinding.ivArrow.setImageResource(R.mipmap.arrow_down_black_24dp);
                mBinding.comicDescriptionComicDetails.setMaxLines(4);
                isDescriptionOpen = !isDescriptionOpen;
            }
            break;
        case R.id.readButton:
            //FAB
            read();
            break;
        }
    }

    private void searchAuthor() {
        Intent intent;
        if (mComic == null)
            return;
        intent = new Intent(this, SearchActivity.class);
        intent.setAction(Intent.ACTION_SEARCH);
        intent.putExtra(SearchManager.QUERY, mComic.getAuthor());
        startActivity(intent);
    }

    private void setupContentViewListener(View view, final BottomSheetDialog dialog) {
        Button startDownload = (Button) view.findViewById(R.id.button_start_download_ds_fragment);
        final Button allSelect = (Button) view.findViewById(R.id.button_select_all_ds_fragment);
        ImageView cancel = (ImageView) view.findViewById(R.id.image_cancel_ds_fragment);
        RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.recycler_view_download_selector);
        recyclerView.setLayoutManager(new GridLayoutManager(this, 4));
        recyclerView.setItemAnimator(new DefaultItemAnimator());
        final VolDownloadSelectorAdapter adapter = new VolDownloadSelectorAdapter(this, mComic.getChapterName(),
                getDownloadedComicChapters(), mFinishedComicChapters);
        adapter.setOnItemClickListener(new VolDownloadSelectorAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(View view, int position) {
                adapter.chapterClick(position);
            }

            @Override
            public void onItemLongClick(View view, int position) {
            }
        });
        adapter.setOnAllSelectedChangedListener(new VolDownloadSelectorAdapter.OnAllSelectedChangedListener() {
            @Override
            public void onAllSelected() {
                allSelect.setText("?");
            }

            @Override
            public void onNoAllSelected() {
                allSelect.setText("");
            }
        });
        recyclerView.setAdapter(adapter);

        startDownload.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //
                if (adapter.getSelectedChapterNames().size() == 0) {
                    Toast.makeText(ComicDetailsActivity.this, "", Toast.LENGTH_SHORT)
                            .show();
                } else {
                    //?Activity
                    sendSelectedChapters(adapter.getSelectedChapterNames());
                    //
                    dialog.dismiss();
                }
            }
        });
        allSelect.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                adapter.allSelect();
            }
        });
        cancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dialog.dismiss();
            }
        });
    }

    public List<String> getDownloadedComicChapters() {
        if (mDownloadedComicChapters != null) {
            List<String> downloadedComicChapter = new ArrayList<>();
            for (int i = 0; i < mDownloadedComicChapters.size(); i++) {
                downloadedComicChapter.add(mDownloadedComicChapters.get(i).getChapterName());
            }
            return downloadedComicChapter;
        } else {
            return null;
        }
    }

    public void sendSelectedChapters(List<String> selectedChapters) {
        //?
        Comic findComic = mComicDBHelper.findByCid(mComic.getCid());
        //true
        mComic.setDownload(true);
        if (findComic != null) {
            //?
            mComic.setLastReadTime(System.currentTimeMillis());
            mComicDBHelper.update(mComic);
        } else if (mComic == null) {
            Toast.makeText(ComicDetailsActivity.this, "??~",
                    Toast.LENGTH_SHORT).show();
            return;
        } else {
            //??
            mComic.setLastReadTime(System.currentTimeMillis());
            //?
            mComicDBHelper.add(mComic);
            mComic.setId(mComicDBHelper.findByCid(mComic.getCid()).getId());
        }

        //
        if (selectedChapters.size() != 0) {
            //??
            if (ContextCompat.checkSelfPermission(this,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                        Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                    Toast.makeText(this, "???", Toast.LENGTH_SHORT).show();
                    mSelectedChapters = selectedChapters;
                    ActivityCompat.requestPermissions(this,
                            new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE }, CHECK_SD_WRITE_PERMISSION);
                } else {
                    mSelectedChapters = selectedChapters;
                    ActivityCompat.requestPermissions(this,
                            new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE }, CHECK_SD_WRITE_PERMISSION);
                }
                return;
            }

            int position = -1;
            List<Integer> positionList = new ArrayList<>();
            ComicChapter Chapter = null;
            for (String volName : selectedChapters) {
                position = mComic.getChapterName().indexOf(volName);
                positionList.add(position);
            }
            //?
            Collections.sort(positionList);
            for (int i = 0; i < positionList.size(); i++) {
                position = positionList.get(i);
                Chapter = new ComicChapter(mComic.getTitle(), mComic.getCid(), mComic.getChapterId().get(position),
                        mComic.getChapterName().get(position), mComic.getServerId());
                Message msg = new Message();
                msg.what = Constants.MSG_DOWNLOAD;
                msg.obj = Chapter;
                //??1000ms
                mHandler.sendMessageDelayed(msg, 10 * i);
            }
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
            @NonNull int[] grantResults) {
        switch (requestCode) {
        case CHECK_SD_WRITE_PERMISSION:
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // permission was granted, yay! Do the contacts-related task you need to do.
                if (mSelectedChapters != null && mSelectedChapters.size() != 0) {
                    int position = -1;
                    List<Integer> positionList = new ArrayList<>();
                    ComicChapter Chapter = null;
                    for (String volName : mSelectedChapters) {
                        position = mComic.getChapterName().indexOf(volName);
                        positionList.add(position);
                    }
                    //?
                    Collections.sort(positionList);
                    for (int i = 0; i < positionList.size(); i++) {
                        position = positionList.get(i);
                        Chapter = new ComicChapter(mComic.getTitle(), mComic.getCid(),
                                mComic.getChapterId().get(position), mComic.getChapterName().get(position),
                                mComic.getServerId());
                        Message msg = new Message();
                        msg.what = Constants.MSG_DOWNLOAD;
                        msg.obj = Chapter;
                        //??10ms
                        mHandler.sendMessageDelayed(msg, 10 * i);
                    }
                    mSelectedChapters = null;
                }
                //.nomedia
                try {
                    CommonUtils.createNomediaIfAllow(getApplicationContext());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            } else {
                // permission denied, boo! Disable the functionality that depends on this permission.
                return;
            }
            break;
        }
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

    class ComicChapterDownloadUpdateReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (!intent.getAction().equals(DownloadManagerService.ACTION_RECEIVER))
                return;
            if (mComic == null || mComicChapterDBHelper == null)
                return;
            ComicChapter comicChapter = (ComicChapter) intent.getSerializableExtra("comicChapter");
            if (comicChapter == null)
                return;
            if (comicChapter.getCid() != mComic.getCid())
                return;

            if (comicChapter.getDownloadStatus() != Constants.DOWNLOAD_DOWNLOADING
                    || comicChapter.getDownloadStatus() != Constants.DOWNLOAD_ERROR
                    || comicChapter.getDownloadStatus() != Constants.DOWNLOAD_PAUSE) {
                mDownloadedComicChapters = mComicChapterDBHelper.findByComicCid(mComic.getCid());
                if (comicChapter.getDownloadStatus() == Constants.DOWNLOAD_FINISHED) {
                    //?
                    if (mVolAdapter == null)
                        return;
                    //??
                    for (int i = 0; i < mDownloadedComicChapters.size(); i++) {
                        if (mDownloadedComicChapters.get(i).getDownloadStatus() == Constants.DOWNLOAD_FINISHED) {
                            if (mFinishedComicChapters == null) {
                                mFinishedComicChapters = new ArrayList<>();
                            }
                            mFinishedComicChapters.add(mDownloadedComicChapters.get(i).getChapterName());
                        }
                    }
                    mVolAdapter.setFinishedComicChapterList(mFinishedComicChapters);
                    //?
                    mVolAdapter.notifyDataSetChanged();
                }
            }
        }
    }
}