1 package net.osdn.gokigen.gr2control.playback.detail;
3 import java.text.SimpleDateFormat;
4 import java.util.Calendar;
7 import java.util.Locale;
10 import android.app.Activity;
11 import android.app.AlertDialog;
12 import android.graphics.Bitmap;
13 import android.support.annotation.NonNull;
14 import android.os.Bundle;
15 import android.support.v4.app.Fragment;
16 import android.support.v4.view.PagerAdapter;
17 import android.support.v4.view.ViewPager;
18 import android.support.v4.view.ViewPager.OnPageChangeListener;
19 import android.support.v7.app.ActionBar;
20 import android.support.v7.app.AppCompatActivity;
21 import android.util.Log;
22 import android.util.LruCache;
23 import android.view.LayoutInflater;
24 import android.view.Menu;
25 import android.view.MenuInflater;
26 import android.view.MenuItem;
27 import android.view.View;
28 import android.view.ViewGroup;
29 import android.widget.ImageView;
31 import net.osdn.gokigen.gr2control.R;
32 import net.osdn.gokigen.gr2control.camera.ICameraFileInfo;
33 import net.osdn.gokigen.gr2control.camera.ICameraRunMode;
34 import net.osdn.gokigen.gr2control.camera.playback.IDownloadThumbnailImageCallback;
35 import net.osdn.gokigen.gr2control.camera.playback.IPlaybackControl;
37 public class ImagePagerViewFragment extends Fragment
39 private final String TAG = this.toString();
40 private static final String JPEG_SUFFIX = ".JPG";
42 private IPlaybackControl playbackControl;
43 private ICameraRunMode runMode;
45 private List<ImageContentInfoEx> contentList = null;
46 private int contentIndex = 0;
48 private LayoutInflater layoutInflater = null;
49 private ViewPager viewPager = null;
50 private LruCache<String, Bitmap> imageCache =null;
53 public static ImagePagerViewFragment newInstance(@NonNull IPlaybackControl playbackControl, @NonNull ICameraRunMode runMode, @NonNull List<ImageContentInfoEx> contentList, int contentIndex)
55 ImagePagerViewFragment fragment = new ImagePagerViewFragment();
56 fragment.setInterface(playbackControl, runMode);
57 fragment.setContentList(contentList, contentIndex);
62 private void setInterface(@NonNull IPlaybackControl playbackControl, @NonNull ICameraRunMode runMode)
64 this.playbackControl = playbackControl;
65 this.runMode = runMode;
69 private void setContentList(@NonNull List<ImageContentInfoEx> contentList, int contentIndex)
71 this.contentList = contentList;
72 this.contentIndex = contentIndex;
76 public void onCreate(Bundle savedInstanceState)
78 super.onCreate(savedInstanceState);
79 imageCache = new LruCache<>(5);
80 setHasOptionsMenu(true);
84 public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
86 layoutInflater = inflater;
87 View view = layoutInflater.inflate(R.layout.fragment_image_pager_view, container, false);
88 viewPager = view.findViewById(R.id.viewPager1);
89 viewPager.setAdapter(new ImagePagerAdapter());
90 viewPager.addOnPageChangeListener(new ImagePageChangeListener());
96 public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
100 ImageContentInfoEx info = contentList.get(contentIndex);
101 ICameraFileInfo file = info.getFileInfo();
102 String path = file.getDirectoryPath() + "/" + file.getFilename();
104 AppCompatActivity activity = (AppCompatActivity) getActivity();
105 if (activity != null)
107 ActionBar bar = activity.getSupportActionBar();
114 String lowerCasePath = path.toUpperCase();
115 if (lowerCasePath.endsWith(JPEG_SUFFIX))
119 inflater.inflate(R.menu.image_view_with_raw, menu);
120 MenuItem downloadMenuItem = menu.findItem(R.id.action_download_with_raw);
121 downloadMenuItem.setEnabled(true);
125 inflater.inflate(R.menu.image_view, menu);
126 MenuItem downloadMenuItem = menu.findItem(R.id.action_download);
127 downloadMenuItem.setEnabled(true);
132 inflater.inflate(R.menu.movie_view, menu);
133 MenuItem downloadMenuItem = menu.findItem(R.id.action_download_movie);
134 downloadMenuItem.setEnabled(true);
144 public boolean onOptionsItemSelected(MenuItem item)
146 boolean doDownload = false;
147 boolean getInformation = false;
148 boolean isSmallSize = false;
149 String specialSuffix = null;
150 if ((item.getItemId() == R.id.action_get_information)||(item.getItemId() == R.id.action_get_information_raw))
152 getInformation = true;
154 else if ((item.getItemId() == R.id.action_download_original_size)||(item.getItemId() == R.id.action_download_original_size_raw))
158 else if ((item.getItemId() == R.id.action_download_640x480)||(item.getItemId() == R.id.action_download_640x480_raw))
163 else if (item.getItemId() == R.id.action_download_original_movie)
167 else if (item.getItemId() == R.id.action_download_raw)
170 specialSuffix = playbackControl.getRawFileSuffix();
175 Thread thread = new Thread(new Runnable() {
179 showFileInformation((contentList.get(contentIndex)).getFileInfo());
196 ICameraFileInfo file = (contentList.get(contentIndex)).getFileInfo();
197 String path = file.getDirectoryPath() + "/" + file.getFilename();
198 String upperCasePath = path.toUpperCase();
199 String suffix = (specialSuffix == null) ? upperCasePath.substring(upperCasePath.lastIndexOf(".")) : specialSuffix;
200 Calendar calendar = Calendar.getInstance();
201 String filename = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(calendar.getTime()) + suffix;
204 saveImageWithDialog(filename, isSmallSize);
212 return (super.onOptionsItemSelected(item));
215 private void showFileInformation(final ICameraFileInfo fileInfo)
217 if (playbackControl != null)
219 playbackControl.updateCameraFileInfo(fileInfo);
222 runOnUiThread(new Runnable() {
227 String model = fileInfo.getModel();
228 String dateTime = "";
229 Date date = fileInfo.getDatetime();
231 dateTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US).format(date);
233 String path = fileInfo.getDirectoryPath() + "/" + fileInfo.getFilename();
234 String shutter = fileInfo.getShutterSpeed();
235 shutter = shutter.replace(".", "/");
236 String aperture = fileInfo.getAperature();
237 String iso = fileInfo.getIsoSensitivity();
238 String expRev = fileInfo.getExpRev();
240 message = path + "\r\n" + dateTime + "\r\n" + "- - - - - - - - - -\r\n " + shutter + " F" + aperture + " (" + expRev + ")" + " ISO" + iso + "\r\n" + "- - - - - - - - - -\r\n" + " model : " + model + "\r\n";
246 presentMessage(getString(R.string.download_control_get_information_title), message);
253 public void onResume()
256 AppCompatActivity activity = (AppCompatActivity)getActivity();
257 if (activity != null)
259 ActionBar bar = activity.getSupportActionBar();
262 bar.setDisplayShowHomeEnabled(true);
267 if (runMode.isRecordingMode())
269 // Threadで呼んではダメみたいだ...
270 runMode.changeRunMode(false);
273 viewPager.setCurrentItem(contentIndex);
277 public void onPause()
280 AppCompatActivity activity = (AppCompatActivity)getActivity();
281 if (activity != null)
283 ActionBar bar = activity.getSupportActionBar();
290 if (!runMode.isRecordingMode())
292 // Threadで呼んではダメみたいだ...
293 runMode.changeRunMode(true);
297 private class ImagePagerAdapter extends PagerAdapter
301 public int getCount()
306 count = contentList.size();
316 public boolean isViewFromObject(@NonNull View view, @NonNull Object object)
318 return (view.equals(object));
322 public @NonNull Object instantiateItem(@NonNull ViewGroup container, int position)
324 ImageView view = (ImageView)layoutInflater.inflate(R.layout.view_image_page, container, false);
325 container.addView(view);
326 downloadImage(position, view);
331 public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object)
333 container.removeView((ImageView)object);
338 private class ImagePageChangeListener implements OnPageChangeListener
342 public void onPageScrollStateChanged(int state)
348 public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
354 public void onPageSelected(int position)
356 contentIndex = position;
359 ICameraFileInfo file = (contentList.get(contentIndex)).getFileInfo();
360 String path = file.getDirectoryPath() + "/" + file.getFilename();
362 AppCompatActivity activity = (AppCompatActivity) getActivity();
363 if (activity != null)
365 ActionBar bar = activity.getSupportActionBar();
370 activity.getSupportActionBar().setTitle(path);
371 activity.getFragmentManager().invalidateOptionsMenu();
385 private void downloadImage(final int position, final ImageView view)
387 Thread thread = new Thread(new Runnable() {
390 downloadImageImpl(position, view);
407 private void downloadImageImpl(int position, final ImageView view)
411 ICameraFileInfo file = (contentList.get(position)).getFileInfo();
412 final String path = file.getDirectoryPath() + "/" + file.getFilename();
414 // Get the cached image.
415 final Bitmap bitmap = imageCache.get(path);
418 if (view != null && viewPager.indexOfChild(view) > -1)
420 runOnUiThread(new Runnable()
425 view.setImageBitmap(bitmap);
432 // Download the image.
433 playbackControl.downloadContentScreennail(path, new IDownloadThumbnailImageCallback() {
435 //public void onCompleted(final byte[] data, final Map<String, Object> metadata) {
436 public void onCompleted(final Bitmap bitmap, final Map<String, Object> metadata) {
437 // Cache the downloaded image.
439 //final Bitmap bitmap = createRotatedBitmap(data, metadata);
446 if (imageCache != null)
448 imageCache.put(path, bitmap);
455 runOnUiThread(new Runnable() {
458 if ((bitmap != null) && (view != null) && (viewPager.indexOfChild(view) > -1))
460 view.setImageBitmap(bitmap);
467 public void onErrorOccurred(Exception e) {
468 final String message = e.getMessage();
469 runOnUiThread(new Runnable() {
472 presentMessage("Load failed", message);
485 * デバイスに画像ファイルをダウンロード(保存)する
487 * @param filename ファイル名(カメラ内の)
488 * @param isSmallSize 小さいサイズの量にするか
490 public void saveImageWithDialog(final String filename, final boolean isSmallSize)
492 Log.v(TAG, "saveImageWithDialog() : " + filename + " (small : " + isSmallSize + ")");
495 final Activity activity = getActivity();
496 if (activity != null)
498 Thread thread = new Thread(new Runnable() {
501 MyContentDownloader contentDownloader = new MyContentDownloader(activity, playbackControl);
502 ICameraFileInfo fileInfo = (contentList.get(contentIndex)).getFileInfo();
503 contentDownloader.startDownload(fileInfo, (filename.endsWith(playbackControl.getRawFileSuffix())) ? playbackControl.getRawFileSuffix() : null, isSmallSize);
515 // -------------------------------------------------------------------------
517 // -------------------------------------------------------------------------
519 private void presentMessage(final String title, final String message)
521 runOnUiThread(new Runnable() {
524 AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
525 builder.setTitle(title).setMessage(message);
531 private void runOnUiThread(Runnable action)
533 if (getActivity() == null)
537 getActivity().runOnUiThread(action);
541 private Bitmap createRotatedBitmap(byte[] data, Map<String, Object> metadata)
546 bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
548 catch (OutOfMemoryError e)
560 int degrees = getRotationDegrees(data, metadata);
563 Matrix m = new Matrix();
564 m.postRotate(degrees);
567 bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), m, true);
569 catch (OutOfMemoryError e)
579 private int getRotationDegrees(byte[] data, Map<String, Object> metadata)
582 int orientation = ExifInterface.ORIENTATION_UNDEFINED;
584 if (metadata != null && metadata.containsKey("Orientation")) {
585 orientation = Integer.parseInt((String)metadata.get("Orientation"));
589 // Gets image orientation to display a picture.
592 File tempFile = File.createTempFile("temp", null);
594 FileOutputStream outStream = new FileOutputStream(tempFile.getAbsolutePath());
595 outStream.write(data);
598 ExifInterface exifInterface = new ExifInterface(tempFile.getAbsolutePath());
599 orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED);
600 if (!tempFile.delete())
602 Log.v(TAG, "temp file delete failure.");
605 catch (IOException e)
613 case ExifInterface.ORIENTATION_NORMAL:
616 case ExifInterface.ORIENTATION_ROTATE_90:
619 case ExifInterface.ORIENTATION_ROTATE_180:
622 case ExifInterface.ORIENTATION_ROTATE_270: