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 boolean isRaw = false;
150 String specialSuffix = null;
151 if ((item.getItemId() == R.id.action_get_information)||(item.getItemId() == R.id.action_get_information_raw))
153 getInformation = true;
155 else if ((item.getItemId() == R.id.action_download_original_size)||(item.getItemId() == R.id.action_download_original_size_raw))
159 else if ((item.getItemId() == R.id.action_download_640x480)||(item.getItemId() == R.id.action_download_640x480_raw))
164 else if (item.getItemId() == R.id.action_download_original_movie)
168 else if (item.getItemId() == R.id.action_download_raw)
176 Thread thread = new Thread(new Runnable() {
180 showFileInformation((contentList.get(contentIndex)).getFileInfo());
198 saveImageWithDialog(isRaw, isSmallSize);
205 return (super.onOptionsItemSelected(item));
208 private void showFileInformation(final ICameraFileInfo fileInfo)
210 if (playbackControl != null)
212 playbackControl.updateCameraFileInfo(fileInfo);
215 runOnUiThread(new Runnable() {
220 String model = fileInfo.getModel();
221 String dateTime = "";
222 Date date = fileInfo.getDatetime();
224 dateTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US).format(date);
226 String path = fileInfo.getDirectoryPath() + "/" + fileInfo.getFilename();
227 String shutter = fileInfo.getShutterSpeed();
228 shutter = shutter.replace(".", "/");
229 String aperture = fileInfo.getAperature();
230 String iso = fileInfo.getIsoSensitivity();
231 String expRev = fileInfo.getExpRev();
233 message = path + "\r\n" + dateTime + "\r\n" + "- - - - - - - - - -\r\n " + shutter + " F" + aperture + " (" + expRev + ")" + " ISO" + iso + "\r\n" + "- - - - - - - - - -\r\n" + " model : " + model + "\r\n";
239 presentMessage(getString(R.string.download_control_get_information_title), message);
246 public void onResume()
249 AppCompatActivity activity = (AppCompatActivity)getActivity();
250 if (activity != null)
252 ActionBar bar = activity.getSupportActionBar();
255 bar.setDisplayShowHomeEnabled(true);
260 if (runMode.isRecordingMode())
262 // Threadで呼んではダメみたいだ...
263 runMode.changeRunMode(false);
266 viewPager.setCurrentItem(contentIndex);
270 public void onPause()
273 AppCompatActivity activity = (AppCompatActivity)getActivity();
274 if (activity != null)
276 ActionBar bar = activity.getSupportActionBar();
283 if (!runMode.isRecordingMode())
285 // Threadで呼んではダメみたいだ...
286 runMode.changeRunMode(true);
290 private class ImagePagerAdapter extends PagerAdapter
294 public int getCount()
299 count = contentList.size();
309 public boolean isViewFromObject(@NonNull View view, @NonNull Object object)
311 return (view.equals(object));
315 public @NonNull Object instantiateItem(@NonNull ViewGroup container, int position)
317 ImageView view = (ImageView)layoutInflater.inflate(R.layout.view_image_page, container, false);
318 container.addView(view);
319 downloadImage(position, view);
324 public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object)
326 container.removeView((ImageView)object);
331 private class ImagePageChangeListener implements OnPageChangeListener
335 public void onPageScrollStateChanged(int state)
341 public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
347 public void onPageSelected(int position)
349 contentIndex = position;
352 ICameraFileInfo file = (contentList.get(contentIndex)).getFileInfo();
353 String path = file.getDirectoryPath() + "/" + file.getFilename();
355 AppCompatActivity activity = (AppCompatActivity) getActivity();
356 if (activity != null)
358 ActionBar bar = activity.getSupportActionBar();
363 activity.getSupportActionBar().setTitle(path);
364 activity.getFragmentManager().invalidateOptionsMenu();
378 private void downloadImage(final int position, final ImageView view)
380 Thread thread = new Thread(new Runnable() {
383 downloadImageImpl(position, view);
400 private void downloadImageImpl(int position, final ImageView view)
404 ICameraFileInfo file = (contentList.get(position)).getFileInfo();
405 final String path = file.getDirectoryPath() + "/" + file.getFilename();
407 // Get the cached image.
408 final Bitmap bitmap = imageCache.get(path);
411 if (view != null && viewPager.indexOfChild(view) > -1)
413 runOnUiThread(new Runnable()
418 view.setImageBitmap(bitmap);
425 // Download the image.
426 playbackControl.downloadContentScreennail(path, new IDownloadThumbnailImageCallback() {
428 //public void onCompleted(final byte[] data, final Map<String, Object> metadata) {
429 public void onCompleted(final Bitmap bitmap, final Map<String, Object> metadata) {
430 // Cache the downloaded image.
432 //final Bitmap bitmap = createRotatedBitmap(data, metadata);
439 if (imageCache != null)
441 imageCache.put(path, bitmap);
448 runOnUiThread(new Runnable() {
451 if ((bitmap != null) && (view != null) && (viewPager.indexOfChild(view) > -1))
453 view.setImageBitmap(bitmap);
460 public void onErrorOccurred(Exception e) {
461 final String message = e.getMessage();
462 runOnUiThread(new Runnable() {
465 presentMessage("Load failed", message);
478 * デバイスに画像ファイルをダウンロード(保存)する
480 * @param isRaw RAWファイルをダウンロードするか
481 * @param isSmallSize 小さいサイズの量にするか
483 public void saveImageWithDialog(final boolean isRaw, final boolean isSmallSize)
485 Log.v(TAG, "saveImageWithDialog() : raw : " + isRaw + " (small : " + isSmallSize + ")");
488 final Activity activity = getActivity();
489 if (activity != null)
491 Thread thread = new Thread(new Runnable() {
494 MyContentDownloader contentDownloader = new MyContentDownloader(activity, playbackControl);
495 ImageContentInfoEx infoEx = contentList.get(contentIndex);
498 ICameraFileInfo fileInfo = infoEx.getFileInfo();
499 contentDownloader.startDownload(fileInfo, (isRaw) ? infoEx.getRawSuffix() : null, isSmallSize);
512 // -------------------------------------------------------------------------
514 // -------------------------------------------------------------------------
516 private void presentMessage(final String title, final String message)
518 runOnUiThread(new Runnable() {
521 AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
522 builder.setTitle(title).setMessage(message);
528 private void runOnUiThread(Runnable action)
530 if (getActivity() == null)
534 getActivity().runOnUiThread(action);
538 private Bitmap createRotatedBitmap(byte[] data, Map<String, Object> metadata)
543 bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
545 catch (OutOfMemoryError e)
557 int degrees = getRotationDegrees(data, metadata);
560 Matrix m = new Matrix();
561 m.postRotate(degrees);
564 bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), m, true);
566 catch (OutOfMemoryError e)
576 private int getRotationDegrees(byte[] data, Map<String, Object> metadata)
579 int orientation = ExifInterface.ORIENTATION_UNDEFINED;
581 if (metadata != null && metadata.containsKey("Orientation")) {
582 orientation = Integer.parseInt((String)metadata.get("Orientation"));
586 // Gets image orientation to display a picture.
589 File tempFile = File.createTempFile("temp", null);
591 FileOutputStream outStream = new FileOutputStream(tempFile.getAbsolutePath());
592 outStream.write(data);
595 ExifInterface exifInterface = new ExifInterface(tempFile.getAbsolutePath());
596 orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED);
597 if (!tempFile.delete())
599 Log.v(TAG, "temp file delete failure.");
602 catch (IOException e)
610 case ExifInterface.ORIENTATION_NORMAL:
613 case ExifInterface.ORIENTATION_ROTATE_90:
616 case ExifInterface.ORIENTATION_ROTATE_180:
619 case ExifInterface.ORIENTATION_ROTATE_270: