package com.athena.asm;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.commons.io.FileUtils;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.media.ExifInterface;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import com.actionbarsherlock.view.Menu;
import com.athena.asm.Adapter.ViewPagerAdapter;
import com.athena.asm.util.StringUtility;
import com.athena.asm.view.MyViewPager;
import com.koushikdutta.urlimageviewhelper.UrlImageViewHelper;
import com.viewpagerindicator.CirclePageIndicator;
public class FullImageActivity extends Activity
implements OnLongClickListener {
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
mViewPager.setCurrentItem(mViewPager.getCurrentItem() + 1, true);
return true;
} else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
mViewPager.setCurrentItem(mViewPager.getCurrentItem() - 1, true);
return true;
}
return super.onKeyDown(keyCode, event);
}
// http://stackoverflow.com/questions/4500354/control-volume-keys
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
// disable the beep sound when volume up/down is pressed
if ((keyCode == KeyEvent.KEYCODE_VOLUME_UP) || (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN)) {
return true;
}
return super.onKeyUp(keyCode, event);
}
private MyViewPager mViewPager;
private ViewPagerAdapter vpAdapter;
// pagination navigator current position
CirclePageIndicator mIndicator;
private int m_imageIdx;
private ArrayList<String> m_imageNames;
private ArrayList<String> m_imageUrls;
private String m_imageName;
private String m_imageUrl;
@Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(android.R.style.Theme_Black_NoTitleBar_Fullscreen);
super.onCreate(savedInstanceState);
setContentView(R.layout.full_image);
m_imageNames = getIntent().getStringArrayListExtra (StringUtility.IMAGE_NAME);
m_imageUrls = getIntent().getStringArrayListExtra (StringUtility.IMAGE_URL);
m_imageIdx = getIntent().getIntExtra(StringUtility.IMAGE_INDEX, 0);
mViewPager = (MyViewPager) findViewById(R.id.myviewpager);
vpAdapter = new ViewPagerAdapter(m_imageUrls, this);
mViewPager.setAdapter(vpAdapter);
mViewPager.setCurrentItem(m_imageIdx);
mIndicator = (CirclePageIndicator)findViewById(R.id.indicator);
mIndicator.setViewPager(mViewPager);
mIndicator.setCurrentItem(m_imageIdx);
setRequestedOrientation(aSMApplication.IMAGE_ORIENTATION);
}
public static final int MENU_EXIF = Menu.FIRST;
public static final int MENU_SAVE = Menu.FIRST + 1;
public static final int MENU_BACK = Menu.FIRST + 2;
// get image attribute from exif
private void setImageAttributeFromExif(View layout, int tv_id, ExifInterface exif, String attr){
if (layout == null || exif == null)
return;
TextView tv = (TextView) layout.findViewById(tv_id);
if (tv == null){
Log.d("setImageAttributeFromExif", "Invalid resource ID: " + tv_id);
return;
}
String attribute = exif.getAttribute(attr);
if (attribute != null){
// there are some special treatment
// http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/EXIF.html
if(attr.equals(ExifInterface.TAG_APERTURE)){
attribute = "F/" + attribute;
} else if(attr.equals(ExifInterface.TAG_EXPOSURE_TIME)){
try{
float f = Float.parseFloat(attribute);
if(f >= 1.0){
attribute = attribute + " s";
} else if ( f >= 0.1 ){
f = 1/f;
BigDecimal exposure = new BigDecimal(f).setScale(0, BigDecimal.ROUND_HALF_UP);
attribute = "1/" + exposure.toString() + " s";
} else {
f = 1/f/10;
BigDecimal exposure = new BigDecimal(f).setScale(0, BigDecimal.ROUND_HALF_UP);
exposure = exposure.multiply(new BigDecimal(10));
attribute = "1/" + exposure.toString() + " s";
}
} catch(NumberFormatException e){
Log.d("Can't convert exposure:", attribute);
}
} else if(attr.equals(ExifInterface.TAG_FLASH)){
int flash = Integer.parseInt(attribute);
switch(flash){
case 0x0:
attribute += " (No Flash)";
break;
case 0x1:
attribute += " (Fired)";
break;
case 0x5:
attribute += " (Fired, Return not detected)";
break;
case 0x7:
attribute += " (Fired, Return detected)";
break;
case 0x8:
attribute += " (On, Did not fire)";
break;
case 0x9:
attribute += " (On, Fired)";
break;
case 0xd:
attribute += " (On, Return not detected)";
break;
case 0xf:
attribute += " (On, Return detected)";
break;
case 0x10:
attribute += " (Off, Did not fire)";
break;
case 0x14:
attribute += " (Off, Did not fire, Return not detected)";
break;
case 0x18:
attribute += " (Auto, Did not fire)";
break;
case 0x19:
attribute += " (Auto, Fired)";
break;
case 0x1d:
attribute += " (Auto, Fired, Return not detected)";
break;
case 0x1f:
attribute += " (Auto, Fired, Return detected)";
break;
case 0x20:
attribute += " (No flash function)";
break;
case 0x30:
attribute += " (Off, No flash function)";
break;
case 0x41:
attribute += " (Fired, Red-eye reduction)";
break;
case 0x45:
attribute += " (Fired, Red-eye reduction, Return not detected)";
break;
case 0x47:
attribute += " (Fired, Red-eye reduction, Return detected)";
break;
case 0x49:
attribute += " (On, Red-eye reduction)";
break;
case 0x4d:
attribute += " (On, Red-eye reduction, Return not detected)";
break;
case 0x4f:
attribute += " (On, Red-eye reduction, Return detected)";
break;
case 0x50:
attribute += " (Off, Red-eye reduction)";
break;
case 0x58:
attribute += " (Auto, Did not fire, Red-eye reduction)";
break;
case 0x59:
attribute += " (Auto, Fired, Red-eye reduction)";
break;
case 0x5d:
attribute += " (Auto, Fired, Red-eye reduction, Return not detected)";
break;
case 0x5f:
attribute += " (Auto, Fired, Red-eye reduction, Return detected)";
break;
default:
break;
}
} else if(attr.equals(ExifInterface.TAG_WHITE_BALANCE)){
int wb = Integer.parseInt(attribute);
switch(wb){
case 0:
attribute += " (Auto)";
break;
case 1:
attribute += " (Manual)";
break;
}
}
tv.setText(attribute);
}
}
void showExifDialog(){
// show exif information dialog
LayoutInflater inflater = getLayoutInflater();
View layout = inflater.inflate(R.layout.image_info, (ViewGroup)findViewById(R.id.image_info_layout));
try {
String filename = UrlImageViewHelper.getFilenameForUrl(m_imageUrl);
File file = new File(getExternalFilesDir(null), filename);
String sFileName = file.getAbsolutePath();
ExifInterface exif = new ExifInterface(sFileName);
// basic information
TextView tvFilename = (TextView) layout.findViewById(R.id.ii_filename);
tvFilename.setText(m_imageName);
setImageAttributeFromExif(layout, R.id.ii_datetime, exif, ExifInterface.TAG_DATETIME);
setImageAttributeFromExif(layout, R.id.ii_width, exif, ExifInterface.TAG_IMAGE_WIDTH);
setImageAttributeFromExif(layout, R.id.ii_height, exif, ExifInterface.TAG_IMAGE_LENGTH);
// get filesize
FileInputStream fis = new FileInputStream(file);
int filesize = fis.available();
fis.close();
TextView tv = (TextView) layout.findViewById(R.id.ii_size);
if(tv != null) {
tv.setText(FileUtils.byteCountToDisplaySize(filesize));
}
// capture information
setImageAttributeFromExif(layout, R.id.ii_make, exif, ExifInterface.TAG_MAKE);
setImageAttributeFromExif(layout, R.id.ii_model, exif, ExifInterface.TAG_MODEL);
setImageAttributeFromExif(layout, R.id.ii_focal_length, exif, ExifInterface.TAG_FOCAL_LENGTH);
setImageAttributeFromExif(layout, R.id.ii_aperture, exif, ExifInterface.TAG_APERTURE);
setImageAttributeFromExif(layout, R.id.ii_exposure_time, exif, ExifInterface.TAG_EXPOSURE_TIME);
setImageAttributeFromExif(layout, R.id.ii_flash, exif, ExifInterface.TAG_FLASH);
setImageAttributeFromExif(layout, R.id.ii_iso, exif, ExifInterface.TAG_ISO);
setImageAttributeFromExif(layout, R.id.ii_white_balance, exif, ExifInterface.TAG_WHITE_BALANCE);
} catch (IOException e){
Log.d("read ExifInfo", "can't read Exif information");
}
new AlertDialog.Builder(FullImageActivity.this).setTitle("图片信息").setView(layout)
.setPositiveButton("确定", null)
.show();
}
void saveImage(){
// save image to sdcard
try {
String fileName;
if (m_imageName.equals("未命名")) {
String time = StringUtility.getFormattedString(new Date());
fileName = time + m_imageName + ".png";
} else {
fileName = m_imageName;
}
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
String path = Environment.getExternalStorageDirectory().getPath() + "/aSM/images/";
File dir = new File(path);
if (!dir.exists()) {
dir.mkdirs();
}
File file = new File(getExternalFilesDir(null),
UrlImageViewHelper.getFilenameForUrl(m_imageUrl));
FileInputStream fis = new FileInputStream(file);
FileOutputStream fos = new FileOutputStream(path + fileName);
BufferedInputStream bufr = new BufferedInputStream(fis);
BufferedOutputStream bufw = new BufferedOutputStream(fos);
int len = 0;
byte[] buf = new byte[1024];
while ((len = bufr.read(buf)) != -1) {
bufw.write(buf, 0, len);
bufw.flush();
}
bufw.close();
bufr.close();
Toast.makeText(FullImageActivity.this, "图片已存为SD卡下aSM/images/" + fileName,
Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
Toast.makeText(FullImageActivity.this, "保存时出现未知错误.", Toast.LENGTH_SHORT).show();
}
}
void updateImageInfoByIndex(){
// update imageName and imageURL
m_imageIdx = mViewPager.getCurrentItem();
m_imageName = m_imageNames.get(m_imageIdx);
if (m_imageName.trim().length() == 0) {
m_imageName = "未命名";
}
m_imageUrl = m_imageUrls.get(m_imageIdx);
}
@Override
public boolean onLongClick(View arg0) {
updateImageInfoByIndex();
// build menu for long click
List<String> itemList = new ArrayList<String>();
itemList.add(getString(R.string.full_image_information));
itemList.add(getString(R.string.full_image_save));
itemList.add(getString(R.string.full_image_back));
final String[] items = new String[itemList.size()];
itemList.toArray(items);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(String.format("图片: %s", m_imageName));
builder.setItems(items, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
switch (item) {
case 0:
showExifDialog();
break;
case 1:
saveImage();
break;
case 2:
onBackPressed();
break;
default:
break;
}
dialog.dismiss();
}
});
AlertDialog menuDialog = builder.create();
menuDialog.show();
return true;
}
@Override
public void onBackPressed() {
// expect post refresh
// setResult(PostListActivity.RETURN_FROM_FULL_IMAGE, getIntent());
// TODO Auto-generated method stub
super.onBackPressed();
}
@Override
public boolean onCreateOptionsMenu(android.view.Menu menu) {
menu.add(0, MENU_EXIF, Menu.NONE, getString(R.string.full_image_information));
menu.add(0, MENU_SAVE, Menu.NONE, getString(R.string.full_image_save));
menu.add(0, MENU_BACK, Menu.NONE, getString(R.string.full_image_back));
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
updateImageInfoByIndex();
switch (item.getItemId()) {
case MENU_EXIF:
showExifDialog();
break;
case MENU_SAVE:
saveImage();
break;
case MENU_BACK:
onBackPressed();
break;
}
return true;
}
}