1 package net.osdn.gokigen.gr2control.playback.detail;
3 import java.text.SimpleDateFormat;
6 import java.util.Locale;
9 import android.app.Activity;
10 import android.app.AlertDialog;
11 import android.graphics.Bitmap;
12 import android.os.Bundle;
13 import android.util.Log;
14 import android.util.LruCache;
15 import android.view.LayoutInflater;
16 import android.view.Menu;
17 import android.view.MenuInflater;
18 import android.view.MenuItem;
19 import android.view.View;
20 import android.view.ViewGroup;
21 import android.widget.ImageView;
23 import net.osdn.gokigen.gr2control.R;
24 import net.osdn.gokigen.gr2control.camera.ICameraFileInfo;
25 import net.osdn.gokigen.gr2control.camera.ICameraRunMode;
26 import net.osdn.gokigen.gr2control.camera.playback.IDownloadThumbnailImageCallback;
27 import net.osdn.gokigen.gr2control.camera.playback.IPlaybackControl;
29 import androidx.annotation.NonNull;
30 import androidx.appcompat.app.ActionBar;
31 import androidx.appcompat.app.AppCompatActivity;
32 import androidx.fragment.app.Fragment;
33 import androidx.viewpager.widget.PagerAdapter;
34 import androidx.viewpager.widget.ViewPager;
36 public class ImagePagerViewFragment extends Fragment
38 private final String TAG = this.toString();
39 private static final String JPEG_SUFFIX = ".JPG";
41 private IPlaybackControl playbackControl;
42 private ICameraRunMode runMode;
44 private List<ImageContentInfoEx> contentList = null;
45 private int contentIndex = 0;
47 private LayoutInflater layoutInflater = null;
48 private ViewPager viewPager = null;
49 private LruCache<String, Bitmap> imageCache =null;
52 public static ImagePagerViewFragment newInstance(@NonNull IPlaybackControl playbackControl, @NonNull ICameraRunMode runMode, @NonNull List<ImageContentInfoEx> contentList, int contentIndex)
54 ImagePagerViewFragment fragment = new ImagePagerViewFragment();
55 fragment.setInterface(playbackControl, runMode);
56 fragment.setContentList(contentList, contentIndex);
61 private void setInterface(@NonNull IPlaybackControl playbackControl, @NonNull ICameraRunMode runMode)
63 this.playbackControl = playbackControl;
64 this.runMode = runMode;
68 private void setContentList(@NonNull List<ImageContentInfoEx> contentList, int contentIndex)
70 this.contentList = contentList;
71 this.contentIndex = contentIndex;
75 public void onCreate(Bundle savedInstanceState)
77 super.onCreate(savedInstanceState);
78 imageCache = new LruCache<>(5);
79 setHasOptionsMenu(true);
83 public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
85 layoutInflater = inflater;
86 View view = layoutInflater.inflate(R.layout.fragment_image_pager_view, container, false);
87 viewPager = view.findViewById(R.id.viewPager1);
88 viewPager.setAdapter(new ImagePagerAdapter());
89 viewPager.addOnPageChangeListener(new ImagePageChangeListener());
95 public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
99 ImageContentInfoEx info = contentList.get(contentIndex);
100 ICameraFileInfo file = info.getFileInfo();
101 String path = file.getDirectoryPath() + "/" + file.getFilename();
103 AppCompatActivity activity = (AppCompatActivity) getActivity();
104 if (activity != null)
106 ActionBar bar = activity.getSupportActionBar();
113 String lowerCasePath = path.toUpperCase();
114 if (lowerCasePath.endsWith(JPEG_SUFFIX))
118 inflater.inflate(R.menu.image_view_with_raw, menu);
119 MenuItem downloadMenuItem = menu.findItem(R.id.action_download_with_raw);
120 downloadMenuItem.setEnabled(true);
124 inflater.inflate(R.menu.image_view, menu);
125 MenuItem downloadMenuItem = menu.findItem(R.id.action_download);
126 downloadMenuItem.setEnabled(true);
131 inflater.inflate(R.menu.movie_view, menu);
132 MenuItem downloadMenuItem = menu.findItem(R.id.action_download_movie);
133 downloadMenuItem.setEnabled(true);
143 public boolean onOptionsItemSelected(MenuItem item)
145 boolean doDownload = false;
146 boolean getInformation = false;
147 boolean isSmallSize = false;
148 boolean isRaw = 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)
175 Thread thread = new Thread(new Runnable() {
179 showFileInformation((contentList.get(contentIndex)).getFileInfo());
197 saveImageWithDialog(isRaw, isSmallSize);
204 return (super.onOptionsItemSelected(item));
207 private void showFileInformation(final ICameraFileInfo fileInfo)
209 if (playbackControl != null)
211 playbackControl.updateCameraFileInfo(fileInfo);
214 runOnUiThread(new Runnable() {
219 String model = fileInfo.getModel();
220 String dateTime = "";
221 Date date = fileInfo.getDatetime();
223 dateTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US).format(date);
225 String path = fileInfo.getDirectoryPath() + "/" + fileInfo.getFilename();
226 String shutter = fileInfo.getShutterSpeed();
227 shutter = shutter.replace(".", "/");
228 String aperture = fileInfo.getAperature();
229 String iso = fileInfo.getIsoSensitivity();
230 String expRev = fileInfo.getExpRev();
232 message = path + "\r\n" + dateTime + "\r\n" + "- - - - - - - - - -\r\n " + shutter + " F" + aperture + " (" + expRev + ")" + " ISO" + iso + "\r\n" + "- - - - - - - - - -\r\n" + " model : " + model + "\r\n";
238 presentMessage(getString(R.string.download_control_get_information_title), message);
245 public void onResume()
248 AppCompatActivity activity = (AppCompatActivity)getActivity();
249 if (activity != null)
251 ActionBar bar = activity.getSupportActionBar();
254 bar.setDisplayShowHomeEnabled(true);
259 if (runMode.isRecordingMode())
261 // Threadで呼んではダメみたいだ...
262 runMode.changeRunMode(false);
265 viewPager.setCurrentItem(contentIndex);
269 public void onPause()
272 AppCompatActivity activity = (AppCompatActivity)getActivity();
273 if (activity != null)
275 ActionBar bar = activity.getSupportActionBar();
282 if (!runMode.isRecordingMode())
284 // Threadで呼んではダメみたいだ...
285 runMode.changeRunMode(true);
289 private class ImagePagerAdapter extends PagerAdapter
293 public int getCount()
298 count = contentList.size();
308 public boolean isViewFromObject(@NonNull View view, @NonNull Object object)
310 return (view.equals(object));
314 public @NonNull Object instantiateItem(@NonNull ViewGroup container, int position)
316 ImageView view = (ImageView)layoutInflater.inflate(R.layout.view_image_page, container, false);
317 container.addView(view);
318 downloadImage(position, view);
323 public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object)
325 container.removeView((ImageView)object);
330 private class ImagePageChangeListener implements ViewPager.OnPageChangeListener
334 public void onPageScrollStateChanged(int state)
340 public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
346 public void onPageSelected(int position)
348 contentIndex = position;
351 ICameraFileInfo file = (contentList.get(contentIndex)).getFileInfo();
352 String path = file.getDirectoryPath() + "/" + file.getFilename();
354 AppCompatActivity activity = (AppCompatActivity) getActivity();
355 if (activity != null)
357 ActionBar bar = activity.getSupportActionBar();
362 activity.getSupportActionBar().setTitle(path);
363 activity.getFragmentManager().invalidateOptionsMenu();
377 private void downloadImage(final int position, final ImageView view)
379 Thread thread = new Thread(new Runnable() {
382 downloadImageImpl(position, view);
399 private void downloadImageImpl(int position, final ImageView view)
403 ICameraFileInfo file = (contentList.get(position)).getFileInfo();
404 final String path = file.getDirectoryPath() + "/" + file.getFilename();
406 // Get the cached image.
407 final Bitmap bitmap = imageCache.get(path);
410 if (view != null && viewPager.indexOfChild(view) > -1)
412 runOnUiThread(new Runnable()
417 view.setImageBitmap(bitmap);
424 // Download the image.
425 playbackControl.downloadContentScreennail(path, new IDownloadThumbnailImageCallback() {
427 //public void onCompleted(final byte[] data, final Map<String, Object> metadata) {
428 public void onCompleted(final Bitmap bitmap, final Map<String, Object> metadata) {
429 // Cache the downloaded image.
431 //final Bitmap bitmap = createRotatedBitmap(data, metadata);
438 if (imageCache != null)
440 imageCache.put(path, bitmap);
447 runOnUiThread(new Runnable() {
450 if ((bitmap != null) && (view != null) && (viewPager.indexOfChild(view) > -1))
452 view.setImageBitmap(bitmap);
459 public void onErrorOccurred(Exception e) {
460 final String message = e.getMessage();
461 runOnUiThread(new Runnable() {
464 presentMessage("Load failed", message);
477 * デバイスに画像ファイルをダウンロード(保存)する
479 * @param isRaw RAWファイルをダウンロードするか
480 * @param isSmallSize 小さいサイズの量にするか
482 private void saveImageWithDialog(final boolean isRaw, final boolean isSmallSize)
484 Log.v(TAG, "saveImageWithDialog() : raw : " + isRaw + " (small : " + isSmallSize + ")");
487 final Activity activity = getActivity();
488 if (activity != null)
490 Thread thread = new Thread(new Runnable() {
493 MyContentDownloader contentDownloader = new MyContentDownloader(activity, playbackControl);
494 ImageContentInfoEx infoEx = contentList.get(contentIndex);
497 ICameraFileInfo fileInfo = infoEx.getFileInfo();
498 contentDownloader.startDownload(fileInfo, "", (isRaw) ? infoEx.getRawSuffix() : null, isSmallSize);
511 // -------------------------------------------------------------------------
513 // -------------------------------------------------------------------------
515 private void presentMessage(final String title, final String message)
517 runOnUiThread(new Runnable() {
520 AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
521 builder.setTitle(title).setMessage(message);
527 private void runOnUiThread(Runnable action)
529 if (getActivity() == null)
533 getActivity().runOnUiThread(action);
537 private Bitmap createRotatedBitmap(byte[] data, Map<String, Object> metadata)
542 bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
544 catch (OutOfMemoryError e)
556 int degrees = getRotationDegrees(data, metadata);
559 Matrix m = new Matrix();
560 m.postRotate(degrees);
563 bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), m, true);
565 catch (OutOfMemoryError e)
575 private int getRotationDegrees(byte[] data, Map<String, Object> metadata)
578 int orientation = ExifInterface.ORIENTATION_UNDEFINED;
580 if (metadata != null && metadata.containsKey("Orientation")) {
581 orientation = Integer.parseInt((String)metadata.get("Orientation"));
585 // Gets image orientation to display a picture.
588 File tempFile = File.createTempFile("temp", null);
590 FileOutputStream outStream = new FileOutputStream(tempFile.getAbsolutePath());
591 outStream.write(data);
594 ExifInterface exifInterface = new ExifInterface(tempFile.getAbsolutePath());
595 orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED);
596 if (!tempFile.delete())
598 Log.v(TAG, "temp file delete failure.");
601 catch (IOException e)
609 case ExifInterface.ORIENTATION_NORMAL:
612 case ExifInterface.ORIENTATION_ROTATE_90:
615 case ExifInterface.ORIENTATION_ROTATE_180:
618 case ExifInterface.ORIENTATION_ROTATE_270: