OSDN Git Service

e4f3afcff2cde1d00fe717952c4e717d4aa95671
[gokigen/Gr2Control.git] / app / src / main / java / net / osdn / gokigen / gr2control / playback / detail / ImagePagerViewFragment.java
1 package net.osdn.gokigen.gr2control.playback.detail;
2
3 import java.text.SimpleDateFormat;
4 import java.util.Date;
5 import java.util.List;
6 import java.util.Locale;
7 import java.util.Map;
8
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;
22
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;
28
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;
35
36 public class ImagePagerViewFragment extends Fragment
37 {
38     private final String TAG = this.toString();
39     private static final String JPEG_SUFFIX = ".JPG";
40
41     private IPlaybackControl playbackControl;
42     private ICameraRunMode runMode;
43
44         private List<ImageContentInfoEx> contentList = null;
45         private int contentIndex = 0;
46
47         private LayoutInflater layoutInflater = null;
48         private ViewPager viewPager = null;
49         private LruCache<String, Bitmap> imageCache =null;
50
51
52     public static ImagePagerViewFragment newInstance(@NonNull IPlaybackControl playbackControl, @NonNull ICameraRunMode runMode, @NonNull List<ImageContentInfoEx> contentList, int contentIndex)
53         {
54                 ImagePagerViewFragment fragment = new ImagePagerViewFragment();
55                 fragment.setInterface(playbackControl, runMode);
56                 fragment.setContentList(contentList, contentIndex);
57                 return (fragment);
58         }
59
60
61         private void setInterface(@NonNull IPlaybackControl playbackControl, @NonNull ICameraRunMode runMode)
62     {
63         this.playbackControl = playbackControl;
64         this.runMode = runMode;
65     }
66
67
68         private void setContentList(@NonNull List<ImageContentInfoEx> contentList, int contentIndex)
69         {
70                 this.contentList = contentList;
71                 this.contentIndex = contentIndex;
72         }
73
74         @Override
75         public void onCreate(Bundle savedInstanceState)
76         {
77                 super.onCreate(savedInstanceState);
78                 imageCache = new LruCache<>(5);
79                 setHasOptionsMenu(true);
80         }
81
82         @Override
83         public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
84         {
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());
90                 
91                 return (view);
92         }
93
94         @Override
95         public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
96         {
97                 try
98                 {
99                         ImageContentInfoEx info  = contentList.get(contentIndex);
100             ICameraFileInfo file = info.getFileInfo();
101                         String path = file.getDirectoryPath() + "/" + file.getFilename();
102
103                         AppCompatActivity activity = (AppCompatActivity) getActivity();
104                         if (activity != null)
105                         {
106                 ActionBar bar = activity.getSupportActionBar();
107                 if (bar != null)
108                 {
109                     bar.show();
110                     bar.setTitle(path);
111                 }
112             }
113                         String lowerCasePath = path.toUpperCase();
114                         if (lowerCasePath.endsWith(JPEG_SUFFIX))
115             {
116                 if (info.hasRaw())
117                 {
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);
121                 }
122                 else
123                 {
124                     inflater.inflate(R.menu.image_view, menu);
125                     MenuItem downloadMenuItem = menu.findItem(R.id.action_download);
126                     downloadMenuItem.setEnabled(true);
127                 }
128                         }
129             else
130             {
131                                 inflater.inflate(R.menu.movie_view, menu);
132                                 MenuItem downloadMenuItem = menu.findItem(R.id.action_download_movie);
133                                 downloadMenuItem.setEnabled(true);
134                         }
135                 }
136                 catch (Exception e)
137                 {
138                         e.printStackTrace();
139                 }
140         }
141
142         @Override
143         public boolean onOptionsItemSelected(MenuItem item)
144         {
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))
151         {
152             getInformation = true;
153         }
154         else if ((item.getItemId() == R.id.action_download_original_size)||(item.getItemId() == R.id.action_download_original_size_raw))
155         {
156                         doDownload = true;
157                 }
158         else if ((item.getItemId() == R.id.action_download_640x480)||(item.getItemId() == R.id.action_download_640x480_raw))
159         {
160             isSmallSize = true;
161             doDownload = true;
162         }
163         else if (item.getItemId() == R.id.action_download_original_movie)
164         {
165             doDownload = true;
166         }
167         else if (item.getItemId() == R.id.action_download_raw)
168         {
169             doDownload = true;
170             isRaw = true;
171                 }
172
173                 if (getInformation)
174         {
175                 Thread thread = new Thread(new Runnable() {
176                                 @Override
177                                 public void run()
178                 {
179                     showFileInformation((contentList.get(contentIndex)).getFileInfo());
180                 }
181                 });
182                 try
183             {
184                 thread.start();
185             }
186             catch (Exception e)
187             {
188                 e.printStackTrace();
189             }
190         }
191
192                 if (doDownload)
193                 {
194                         try
195                         {
196                                 //  ダイアログを表示して保存する
197                                 saveImageWithDialog(isRaw, isSmallSize);
198                         }
199                         catch (Exception e)
200                         {
201                                 e.printStackTrace();
202                         }
203                 }
204                 return (super.onOptionsItemSelected(item));
205         }
206
207     private void showFileInformation(final ICameraFileInfo fileInfo)
208     {
209         if (playbackControl != null)
210         {
211             playbackControl.updateCameraFileInfo(fileInfo);
212         }
213
214         runOnUiThread(new Runnable() {
215             @Override
216             public void run() {
217                 String message = "";
218                 try {
219                     String model = fileInfo.getModel();
220                     String dateTime = "";
221                     Date date = fileInfo.getDatetime();
222                     if (date != null) {
223                         dateTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US).format(date);
224                     }
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();
231
232                     message = path + "\r\n" + dateTime + "\r\n" + "- - - - - - - - - -\r\n  " + shutter + "  F" + aperture + " (" + expRev + ")" + " ISO" + iso + "\r\n" + "- - - - - - - - - -\r\n" + "  model : " + model + "\r\n";
233                 }
234                 catch (Exception e)
235                 {
236                     e.printStackTrace();
237                 }
238                 presentMessage(getString(R.string.download_control_get_information_title), message);
239                 System.gc();
240             }
241         });
242     }
243
244     @Override
245         public void onResume()
246     {
247                 super.onResume();
248                 AppCompatActivity activity = (AppCompatActivity)getActivity();
249                 if (activity != null)
250                 {
251             ActionBar bar = activity.getSupportActionBar();
252             if (bar != null)
253             {
254                 bar.setDisplayShowHomeEnabled(true);
255                 bar.show();
256             }
257         }
258
259         if (runMode.isRecordingMode())
260         {
261             // Threadで呼んではダメみたいだ...
262             runMode.changeRunMode(false);
263         }
264
265         viewPager.setCurrentItem(contentIndex);
266         }
267
268         @Override
269         public void onPause()
270         {
271                 super.onPause();
272                 AppCompatActivity activity = (AppCompatActivity)getActivity();
273                 if (activity != null)
274                 {
275             ActionBar bar = activity.getSupportActionBar();
276             if (bar != null)
277             {
278                 bar.hide();
279             }
280         }
281
282         if (!runMode.isRecordingMode())
283         {
284             // Threadで呼んではダメみたいだ...
285             runMode.changeRunMode(true);
286         }
287     }
288
289         private class ImagePagerAdapter extends PagerAdapter
290     {
291
292                 @Override
293                 public int getCount()
294         {
295             int count = 0;
296                     try
297             {
298                 count = contentList.size();
299             }
300             catch (Exception e)
301             {
302                 e.printStackTrace();
303             }
304                         return (count);
305                 }
306
307                 @Override
308                 public boolean isViewFromObject(@NonNull View view, @NonNull Object object)
309         {
310                         return (view.equals(object));
311                 }
312                 
313                 @Override
314                 public @NonNull Object instantiateItem(@NonNull ViewGroup container, int position)
315         {
316                         ImageView view = (ImageView)layoutInflater.inflate(R.layout.view_image_page, container, false);
317                         container.addView(view);
318                         downloadImage(position, view);
319                         return (view);
320                 }
321                 
322                 @Override
323                 public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object)
324                 {
325                         container.removeView((ImageView)object);
326                 }
327                 
328         }
329
330         private class ImagePageChangeListener implements ViewPager.OnPageChangeListener
331         {
332
333                 @Override
334                 public void onPageScrollStateChanged(int state)
335                 {
336
337                 }
338
339                 @Override
340                 public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
341                 {
342
343                 }
344
345                 @Override
346                 public void onPageSelected(int position)
347                 {
348                         contentIndex = position;
349                         try
350                         {
351                 ICameraFileInfo file = (contentList.get(contentIndex)).getFileInfo();
352                 String path = file.getDirectoryPath() + "/" + file.getFilename();
353
354                 AppCompatActivity activity = (AppCompatActivity) getActivity();
355                 if (activity != null)
356                 {
357                     ActionBar bar = activity.getSupportActionBar();
358                     if (bar != null)
359                     {
360                         bar.setTitle(path);
361                     }
362                     activity.getSupportActionBar().setTitle(path);
363                     activity.getFragmentManager().invalidateOptionsMenu();
364                 }
365                         }
366                         catch (Exception e)
367             {
368                 e.printStackTrace();
369             }
370                 }
371         }
372
373     /**
374      *
375      *
376      */
377         private void downloadImage(final int position, final ImageView view)
378         {
379                 Thread thread = new Thread(new Runnable() {
380                         @Override
381                         public void run() {
382                                 downloadImageImpl(position, view);
383                         }
384                 });
385                 try
386                 {
387                         thread.start();
388                 }
389                 catch (Exception e)
390                 {
391                         e.printStackTrace();
392                 }
393         }
394
395     /**
396      *
397      *
398      */
399         private void downloadImageImpl(int position, final ImageView view)
400     {
401         try
402         {
403             ICameraFileInfo file = (contentList.get(position)).getFileInfo();
404             final String path = file.getDirectoryPath() + "/" + file.getFilename();
405
406             // Get the cached image.
407             final Bitmap bitmap = imageCache.get(path);
408             if (bitmap != null)
409             {
410                 if (view != null && viewPager.indexOfChild(view) > -1)
411                 {
412                     runOnUiThread(new Runnable()
413                     {
414                         @Override
415                         public void run()
416                         {
417                             view.setImageBitmap(bitmap);
418                         }
419                     });
420                 }
421                 return;
422             }
423
424             // Download the image.
425             playbackControl.downloadContentScreennail(path, new IDownloadThumbnailImageCallback() {
426                 @Override
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.
430
431                     //final Bitmap bitmap = createRotatedBitmap(data, metadata);
432                     try {
433                         if (bitmap == null)
434                         {
435                             System.gc();
436                             return;
437                         }
438                         if (imageCache != null)
439                                                 {
440                             imageCache.put(path, bitmap);
441                         }
442                     }
443                     catch (Exception e)
444                     {
445                         e.printStackTrace();
446                     }
447                     runOnUiThread(new Runnable() {
448                         @Override
449                         public void run() {
450                             if ((bitmap != null) && (view != null) && (viewPager.indexOfChild(view) > -1))
451                             {
452                                 view.setImageBitmap(bitmap);
453                             }
454                         }
455                     });
456                 }
457
458                 @Override
459                 public void onErrorOccurred(Exception e) {
460                     final String message = e.getMessage();
461                     runOnUiThread(new Runnable() {
462                         @Override
463                         public void run() {
464                             presentMessage("Load failed", message);
465                         }
466                     });
467                 }
468             });
469         }
470         catch (Exception e)
471         {
472             e.printStackTrace();
473         }
474         }
475
476         /**
477          *   デバイスに画像ファイルをダウンロード(保存)する
478          *
479          * @param isRaw           RAWファイルをダウンロードするか
480          * @param isSmallSize    小さいサイズの量にするか
481      */
482         private void saveImageWithDialog(final boolean isRaw, final boolean isSmallSize)
483         {
484         Log.v(TAG, "saveImageWithDialog() : raw : " + isRaw + " (small : " + isSmallSize + ")");
485         try
486         {
487             final Activity activity = getActivity();
488             if (activity != null)
489             {
490                 Thread thread = new Thread(new Runnable() {
491                     @Override
492                     public void run() {
493                         MyContentDownloader contentDownloader = new MyContentDownloader(activity, playbackControl);
494                         ImageContentInfoEx infoEx = contentList.get(contentIndex);
495                         if (infoEx != null)
496                         {
497                             ICameraFileInfo fileInfo = infoEx.getFileInfo();
498                             contentDownloader.startDownload(fileInfo, "", (isRaw) ? infoEx.getRawSuffix() : null, isSmallSize);
499                         }
500                     }
501                 });
502                 thread.start();
503             }
504         }
505         catch (Exception e)
506         {
507             e.printStackTrace();
508         }
509         }
510
511         // -------------------------------------------------------------------------
512         // Helpers
513         // -------------------------------------------------------------------------
514         
515         private void presentMessage(final String title, final String message)
516     {
517         runOnUiThread(new Runnable() {
518                 @Override
519                 public void run() {
520                     AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
521                     builder.setTitle(title).setMessage(message);
522                     builder.show();
523                 }
524         });
525         }
526         
527         private void runOnUiThread(Runnable action)
528     {
529                 if (getActivity() == null)
530         {
531                         return;
532                 }
533                 getActivity().runOnUiThread(action);
534         }
535
536 /*
537         private Bitmap createRotatedBitmap(byte[] data, Map<String, Object> metadata)
538         {
539                 Bitmap bitmap;
540                 try
541                 {
542                         bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
543                 }
544                 catch (OutOfMemoryError e)
545                 {
546                         e.printStackTrace();
547                         bitmap = null;
548                         System.gc();
549                 }
550                 if (bitmap == null)
551                 {
552                         return (null);
553                 }
554
555                 // ビットマップの回転を行う
556                 int degrees = getRotationDegrees(data, metadata);
557                 if (degrees != 0)
558                 {
559                         Matrix m = new Matrix();
560                         m.postRotate(degrees);
561                         try
562                         {
563                                 bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), m, true);
564                         }
565                         catch (OutOfMemoryError e)
566                         {
567                                 e.printStackTrace();
568                                 bitmap = null;
569                                 System.gc();
570                         }
571                 }
572                 return (bitmap);
573         }
574         
575         private int getRotationDegrees(byte[] data, Map<String, Object> metadata)
576         {
577                 int degrees = 0;
578                 int orientation = ExifInterface.ORIENTATION_UNDEFINED;
579                 
580                 if (metadata != null && metadata.containsKey("Orientation")) {
581                         orientation = Integer.parseInt((String)metadata.get("Orientation"));
582                 }
583                 else
584                 {
585                         // Gets image orientation to display a picture.
586                         try
587             {
588                                 File tempFile = File.createTempFile("temp", null);
589                                 {
590                                         FileOutputStream outStream = new FileOutputStream(tempFile.getAbsolutePath());
591                                         outStream.write(data);
592                                         outStream.close();
593                                 }
594                                 ExifInterface exifInterface = new ExifInterface(tempFile.getAbsolutePath());
595                                 orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED);
596                                 if (!tempFile.delete())
597                 {
598                     Log.v(TAG, "temp file delete failure.");
599                 }
600                         }
601             catch (IOException e)
602             {
603                 e.printStackTrace();
604                         }
605                 }
606
607                 switch (orientation)
608                 {
609             case ExifInterface.ORIENTATION_NORMAL:
610                 degrees = 0;
611                 break;
612             case ExifInterface.ORIENTATION_ROTATE_90:
613                 degrees = 90;
614                 break;
615             case ExifInterface.ORIENTATION_ROTATE_180:
616                 degrees = 180;
617                 break;
618             case ExifInterface.ORIENTATION_ROTATE_270:
619                 degrees = 270;
620                 break;
621             default:
622                 break;
623                 }
624                 return degrees;
625         }
626 */
627 }