/*
* Copyright (C) 2013 YROM.NET
*
* 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 tv.acfun.a63;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.util.ArrayList;
import pl.droidsonroids.gif.GifDrawable;
import tv.acfun.a63.api.ArticleApi;
import tv.acfun.a63.base.BaseActivity;
import tv.acfun.a63.util.ActionBarUtil;
import tv.acfun.a63.util.BaseAnimationListener;
import tv.acfun.a63.util.Connectivity;
import tv.acfun.a63.util.FileUtil;
import tv.acfun.a63.view.MyViewPager;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.MenuItemCompat;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.support.v4.view.WindowCompat;
import android.support.v7.widget.ShareActionProvider;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewGroup.MarginLayoutParams;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationUtils;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.alibaba.fastjson.util.IOUtils;
import com.diegocarloslima.byakugallery.lib.TileBitmapDrawable;
import com.diegocarloslima.byakugallery.lib.TouchImageView;
import com.umeng.analytics.MobclickAgent;
/**
* @author Yrom
*
*/
public class ImagePagerActivity extends BaseActivity implements OnPageChangeListener {
private static final String EXTRA_IMAGES = "images";
private static final String EXTRA_INDEX = "index";
private MyViewPager pager;
private TextView indexText;
public static void startCacheImage(Context context, ArrayList<File> flist, int index, int aid, String title){
ArrayList<String> list = new ArrayList<>(flist.size());
for(File file : flist){
list.add(Uri.fromFile(file).toString());
}
startNetworkImage(context, list, index, aid, title);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
ActionBarUtil.compatibleDeviceWithSB(this);
requestWindowFeature(WindowCompat.FEATURE_ACTION_BAR_OVERLAY);
super.onCreate(savedInstanceState);
ActionBarUtil.setXiaomiFilterDisplayOptions(getSupportActionBar(), false);
getSupportActionBar().setBackgroundDrawable(getResources().getDrawable(R.drawable.ab_bg_trans));
Bundle extras = getIntent().getExtras();
title = extras.getString("title");
getSupportActionBar().setTitle(title);
aid = extras.getInt("aid");
mList = extras.getStringArrayList(EXTRA_IMAGES);
int index = extras.getInt(EXTRA_INDEX,0);
if(index < 0) index = 0;
MobclickAgent.onEvent(this, "view_big_pic");
setContentView(R.layout.activity_images);
indexText = (TextView) findViewById(R.id.index);
if(ActionBarUtil.hasSB() && getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE){
setInfoBottomMargin(getResources().getDimensionPixelSize(R.dimen.abc_action_bar_default_height));
}
pager = (MyViewPager) findViewById(R.id.pager);
pager.setAdapter(new ImageAdapter(getSupportFragmentManager(),mList));
pager.setOffscreenPageLimit(1);
pager.setOnPageChangeListener(this);
pager.setCurrentItem(index);
onPageSelected(index);
}
private void setInfoBottomMargin(int height) {
MarginLayoutParams params = (MarginLayoutParams) indexText.getLayoutParams();
params.bottomMargin = height;
indexText.setLayoutParams(params);
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if(ActionBarUtil.hasSB() ){
if(newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE){
setInfoBottomMargin(0);
}else if(newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
setInfoBottomMargin(getResources().getDimensionPixelSize(R.dimen.abc_action_bar_default_height));
}
}
}
static class ImageAdapter extends FragmentStatePagerAdapter{
ArrayList<String> list;
ImageAdapter(FragmentManager fm, ArrayList<String> imgUrls) {
super(fm);
this.list = imgUrls;
}
@Override
public int getCount() {
return list.size();
}
@Override
public Fragment getItem(int position) {
Fragment fragment = new ImageFragment();
Bundle args = new Bundle();
args.putString(ImageFragment.ARG_IMAGE_URL, list.get(position));
fragment.setArguments(args);
return fragment;
}
}
AnimationListener mHideListener = new BaseAnimationListener(){
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void onAnimationEnd(Animation animation) {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
indexText.setTranslationY(indexText.getHeight());
indexText.setVisibility(View.GONE);
}
};
AnimationListener mShowListener = new BaseAnimationListener(){
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void onAnimationStart(Animation animation) {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
indexText.setTranslationY(0);
indexText.setVisibility(View.VISIBLE);
}
};
void hideInfo(){
Animation anim = AnimationUtils.loadAnimation(this, R.anim.slide_out);
anim.setAnimationListener(mHideListener);
indexText.startAnimation(anim);
}
void showInfo(){
Animation anim = AnimationUtils.loadAnimation(this, R.anim.slide_in);
anim.setAnimationListener(mShowListener);
indexText.startAnimation(anim);
}
public static class ImageFragment extends Fragment{
public static final String ARG_IMAGE_URL = "image_url";
public static final String TAG = "ImagePaer.ImageFragment";
private Uri mUri;
private DownloadImageTask task;
ProgressBar progress;
TextView timeOut;
ImagePagerActivity mContext;
TouchImageView imageView;
View.OnClickListener clicked = new View.OnClickListener() {
@Override
public void onClick(View view) {
if(mContext.getSupportActionBar().isShowing()){
mContext.getSupportActionBar().hide();
mContext.hideInfo();
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
view.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE);
}else{
mContext.getSupportActionBar().show();
mContext.showInfo();
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
view.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
}
}
};
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mContext = (ImagePagerActivity) activity;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String url = getArguments().getString(ARG_IMAGE_URL);
Uri uri = Uri.parse(url);
if(uri.getHost() == null){
uri = Uri.parse("http://"+ArticleApi.getDomainRoot(mContext)+url);
}
mUri = uri;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_image, container,false);
imageView = (TouchImageView)rootView.findViewById(R.id.image);
// imageView.setMaxScale(3.0f);
timeOut = (TextView)rootView.findViewById(R.id.time_out_text);
progress = (ProgressBar) rootView.findViewById(R.id.loading);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB &&
!mContext.getSupportActionBar().isShowing()){
imageView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE);
}
return rootView;
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
getImage();
}
private void getImage() {
if("file".equals(mUri.getScheme())){
File img = new File(mUri.getPath());
if(img.exists()){
loadImage(img.getAbsolutePath());
}else{
timeOut.setVisibility(View.VISIBLE);
timeOut.setText(R.string.no_data_need_retry);
}
}else{
task = new DownloadImageTask();
task.execute(mUri);
}
}
private void loadImage(String path) {
if(path.endsWith(".gif")){
try {
GifDrawable drawable = new GifDrawable(path);
imageView.setImageDrawable(drawable);
drawable.start();
} catch (IOException e) {
e.printStackTrace();
}
}
if(imageView.getDrawable() == null){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD_MR1){
usingTileBitmap(path);
}else{
imageView.setImageDrawable(Drawable.createFromPath(path));
}
}
imageView.setOnClickListener(clicked);
}
private void usingTileBitmap(final String path) {
TileBitmapDrawable.attachTileBitmapDrawable(imageView, path, null, new TileBitmapDrawable.OnInitializeListener() {
@Override
public void onStartInitialization() {
progress.setVisibility(View.VISIBLE);
}
@Override
public void onEndInitialization() {
progress.setVisibility(View.GONE);
task = null;
}
@Override
public void onErrorInitialization() {
onEndInitialization();
imageView.setImageDrawable(Drawable.createFromPath(path));
}
});
}
private void onError() {
progress.setVisibility(View.GONE);
timeOut.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
v.setVisibility(View.GONE);
getImage();
}
});
timeOut.setVisibility(View.VISIBLE);
}
@Override
public void onDestroyView() {
Drawable drawable = imageView.getDrawable();
if(drawable != null){
if(drawable instanceof GifDrawable){
((GifDrawable) drawable).recycle();
}else {
drawable.setCallback(null);
}
imageView.setImageDrawable(null);
}
super.onDestroyView();
if(task != null && task.loading && !task.isCancelled()){
task.cancel(true);
}
}
class DownloadImageTask extends AsyncTask<Uri, Void, String>{
boolean loading;
@Override
protected void onPreExecute() {
progress.setVisibility(View.VISIBLE);
}
@Override
protected String doInBackground(Uri... params) {
loading = true;
Uri uri = params[0];
if(uri == null || mUri.getHost() == null) return null;
File cache = FileUtil.generateImageCacheFile(uri.toString());
if (cache.exists() && cache.canRead()) {
return cache.getAbsolutePath();
} else {
cache.getParentFile().mkdirs();
}
File temp = new File(cache.getAbsolutePath()+".tmp");
InputStream in = null;
OutputStream out = null;
try {
URL parsedUrl = new URL(uri.toString());
for (int i = 0; i < 3 && !isCancelled(); i++) {
HttpURLConnection connection = Connectivity.openDefaultConnection(parsedUrl, 3000 + i * 1500, (3000 * (2 + i)));
if(temp.exists()){
connection.addRequestProperty("Range", "bytes="+temp.length()+"-");
out = new FileOutputStream(temp,true);
}else
out = new FileOutputStream(temp);
try {
int responseCode = connection.getResponseCode();
if (responseCode == 200 || responseCode == 206) {
in = connection.getInputStream();
FileUtil.copyStream(in, out);
cache.delete();
if(!temp.renameTo(cache)){
Log.w(TAG, "重命名失败"+temp.getName());
}
return cache.getAbsolutePath();
}
} catch (SocketTimeoutException e) {
Log.w(TAG, "retry", e);
}
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
IOUtils.close(in);
IOUtils.close(out);
}
return null;
}
@Override
protected void onPostExecute(String result) {
loading = false;
if(result == null)
onError();
else
loadImage(result);
}
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_item_comment:
CommentsActivity.start(this, aid);
return true;
case R.id.menu_item_save_image:
saveImage(mCurrentImage);
return true;
}
return super.onOptionsItemSelected(item);
}
private void saveImage(int index) {
String dest = AcApp.getPreferenceImageSaveDir();
String path = mList.get(index);
Uri uri = Uri.parse(path);
File saveFile;
if (uri.getScheme().equals("http")) {
// FIXME: volley 的缓存任务还没有被执行的时候是会获取不到数据的
byte[] diskCache = AcApp.getDataInDiskCache(path);
if (diskCache != null) {
saveFile = new File(dest + "/" + FileUtil.getHashName(path));
if (!FileUtil.save(diskCache, saveFile.getAbsolutePath())) {
saveFile = null;
}
} else {
File cache = FileUtil.generateImageCacheFile(path);
saveFile = FileUtil.copy(cache, dest);
}
} else {
File cache = new File(uri.getPath());
saveFile = FileUtil.copy(cache, dest);
}
if (saveFile != null && saveFile.exists()) {
MobclickAgent.onEvent(this, "save_pic");
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(saveFile));
sendBroadcast(intent);
AcApp.showToast(getString(R.string.save_success)+":"+saveFile.getAbsolutePath());
} else
AcApp.showToast(getString(R.string.save_failed));
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.image, menu);
MenuItem actionItem = menu.findItem(R.id.menu_item_share_action_provider_action_bar);
if(ActionBarUtil.hasSB()){
MenuItemCompat.setShowAsAction(actionItem, MenuItemCompat.SHOW_AS_ACTION_NEVER);
}
ShareActionProvider actionProvider = (ShareActionProvider)MenuItemCompat.getActionProvider(actionItem);
actionProvider.setShareHistoryFileName(ShareActionProvider.DEFAULT_SHARE_HISTORY_FILE_NAME);
actionProvider.setShareIntent(createShareIntent());
return super.onCreateOptionsMenu(menu);
}
private Intent createShareIntent() {
Intent shareIntent = new Intent(Intent.ACTION_SEND);
String path = mList.get(mCurrentImage);
Uri uri = Uri.parse(path);
shareIntent.setType("image/*");
shareIntent.putExtra(Intent.EXTRA_TEXT, String.format("#Acfun文章区# 分享图片,%s - http://%s/a/ac%d",
title, ArticleApi.getDomainRoot(getApplicationContext()), aid));
shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
return shareIntent;
}
public static void startNetworkImage(Context context, ArrayList<String> list, int index, int aid, String title) {
Intent intent = new Intent(context, ImagePagerActivity.class);
intent.putStringArrayListExtra(EXTRA_IMAGES, list);
intent.putExtra(EXTRA_INDEX, index);
intent.putExtra("aid", aid);
intent.putExtra("title", title);
context.startActivity(intent);
}
@Override
public void onPageScrollStateChanged(int arg0) {
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
private int mCurrentImage;
private ArrayList<String> mList;
private String title;
private int aid;
@Override
public void onPageSelected(int arg0) {
mCurrentImage = arg0;
indexText.setText(String.format("%d/%d",mCurrentImage+1,mList.size()));
}
}