OSDN Git Service

サムネイル表示のところまで作成。
[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.io.File;
4 import java.io.FileOutputStream;
5 import java.io.IOException;
6 import java.text.SimpleDateFormat;
7 import java.util.Calendar;
8 import java.util.Date;
9 import java.util.List;
10 import java.util.Locale;
11 import java.util.Map;
12
13 import android.app.Activity;
14 import android.app.AlertDialog;
15 import android.app.ProgressDialog;
16 import android.content.ContentResolver;
17 import android.content.ContentValues;
18 import android.content.Intent;
19 import android.graphics.Bitmap;
20 import android.graphics.BitmapFactory;
21 import android.graphics.Matrix;
22
23 import android.net.Uri;
24 import android.support.annotation.NonNull;
25 import android.support.media.ExifInterface;
26 import android.os.Bundle;
27 import android.os.Environment;
28 import android.provider.MediaStore;
29 import android.provider.MediaStore.Images;
30 import android.support.v4.app.Fragment;
31 import android.support.v4.app.FragmentActivity;
32 import android.support.v4.view.PagerAdapter;
33 import android.support.v4.view.ViewPager;
34 import android.support.v4.view.ViewPager.OnPageChangeListener;
35 import android.support.v7.app.ActionBar;
36 import android.support.v7.app.AppCompatActivity;
37 import android.util.Log;
38 import android.util.LruCache;
39 import android.view.LayoutInflater;
40 import android.view.Menu;
41 import android.view.MenuInflater;
42 import android.view.MenuItem;
43 import android.view.View;
44 import android.view.ViewGroup;
45 import android.widget.ImageView;
46 import android.widget.Toast;
47
48 import net.osdn.gokigen.gr2control.R;
49 import net.osdn.gokigen.gr2control.camera.ICameraFileInfo;
50 import net.osdn.gokigen.gr2control.camera.playback.IDownloadImageCallback;
51 import net.osdn.gokigen.gr2control.camera.playback.IDownloadLargeContentCallback;
52 import net.osdn.gokigen.gr2control.camera.playback.IDownloadThumbnailImageCallback;
53 import net.osdn.gokigen.gr2control.camera.playback.IPlaybackControl;
54 import net.osdn.gokigen.gr2control.camera.playback.ProgressEvent;
55
56 public class ImagePagerViewFragment extends Fragment
57 {
58     private final String TAG = this.toString();
59     private final String JPEG_SUFFIX = ".jpg";
60     private final String RAW_SUFFIX = ".dng";
61     private IPlaybackControl playbackControl;
62
63         private List<ImageContentInfoEx> contentList = null;
64         private int contentIndex = 0;
65
66         private LayoutInflater layoutInflater = null;
67         private ViewPager viewPager = null;
68         private LruCache<String, Bitmap> imageCache =null;
69
70     public static ImagePagerViewFragment newInstance(@NonNull IPlaybackControl playbackControl, @NonNull List<ImageContentInfoEx> contentList, int contentIndex)
71         {
72                 ImagePagerViewFragment fragment = new ImagePagerViewFragment();
73                 fragment.setInterface(playbackControl);
74                 fragment.setContentList(contentList, contentIndex);
75                 return (fragment);
76         }
77
78         private void setInterface(@NonNull IPlaybackControl playbackControl)
79     {
80         this.playbackControl = playbackControl;
81     }
82
83         private void setContentList(@NonNull List<ImageContentInfoEx> contentList, int contentIndex)
84         {
85                 this.contentList = contentList;
86                 this.contentIndex = contentIndex;
87         }
88
89         @Override
90         public void onCreate(Bundle savedInstanceState)
91         {
92                 super.onCreate(savedInstanceState);
93                 imageCache = new LruCache<>(5);
94                 setHasOptionsMenu(true);
95         }
96
97         @Override
98         public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
99         {
100                 layoutInflater = inflater;
101                 View view = layoutInflater.inflate(R.layout.fragment_image_pager_view, container, false);
102                 viewPager = view.findViewById(R.id.viewPager1);
103                 viewPager.setAdapter(new ImagePagerAdapter());
104                 viewPager.addOnPageChangeListener(new ImagePageChangeListener());
105                 
106                 return (view);
107         }
108
109         @Override
110         public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
111         {
112                 try
113                 {
114                         ImageContentInfoEx info  = contentList.get(contentIndex);
115             ICameraFileInfo file = info.getFileInfo();
116                         String path = file.getDirectoryPath() + "/" + file.getFilename();
117
118                         AppCompatActivity activity = (AppCompatActivity) getActivity();
119                         if (activity != null)
120                         {
121                 ActionBar bar = activity.getSupportActionBar();
122                 if (bar != null)
123                 {
124                     bar.show();
125                     bar.setTitle(path);
126                 }
127             }
128                         String lowerCasePath = path.toLowerCase();
129                         if (lowerCasePath.endsWith(JPEG_SUFFIX))
130             {
131                 if (info.hasRaw())
132                 {
133                     inflater.inflate(R.menu.image_view_with_raw, menu);
134                     MenuItem downloadMenuItem = menu.findItem(R.id.action_download_with_raw);
135                     downloadMenuItem.setEnabled(true);
136                 }
137                 else
138                 {
139                     inflater.inflate(R.menu.image_view, menu);
140                     MenuItem downloadMenuItem = menu.findItem(R.id.action_download);
141                     downloadMenuItem.setEnabled(true);
142                 }
143                         }
144             else
145             {
146                                 inflater.inflate(R.menu.movie_view, menu);
147                                 MenuItem downloadMenuItem = menu.findItem(R.id.action_download_movie);
148                                 downloadMenuItem.setEnabled(true);
149                         }
150                 }
151                 catch (Exception e)
152                 {
153                         e.printStackTrace();
154                 }
155         }
156
157         @Override
158         public boolean onOptionsItemSelected(MenuItem item)
159         {
160                 boolean doDownload = false;
161         boolean getInformation = false;
162                 boolean isSmallSize = false;
163         String specialSuffix = null;
164         if ((item.getItemId() == R.id.action_get_information)||(item.getItemId() == R.id.action_get_information_raw))
165         {
166             getInformation = true;
167         }
168         else if ((item.getItemId() == R.id.action_download_original_size)||(item.getItemId() == R.id.action_download_original_size_raw))
169         {
170                         doDownload = true;
171                 }
172         else if ((item.getItemId() == R.id.action_download_640x480)||(item.getItemId() == R.id.action_download_640x480_raw))
173         {
174             isSmallSize = true;
175             doDownload = true;
176         }
177         else if (item.getItemId() == R.id.action_download_original_movie)
178         {
179             doDownload = true;
180         }
181         else if (item.getItemId() == R.id.action_download_raw)
182         {
183             doDownload = true;
184             specialSuffix = RAW_SUFFIX;
185                 }
186
187                 if (getInformation)
188         {
189             showFileInformation((contentList.get(contentIndex)).getFileInfo());
190         }
191
192         /*
193                 if (doDownload)
194                 {
195                         try
196                         {
197                 ICameraFileInfo file = (contentList.get(contentIndex)).getFileInfo();
198                                 String path = file.getDirectoryPath() + "/" + file.getFilename();
199                                 String lowerCasePath = path.toLowerCase();
200                                 String suffix = (specialSuffix == null) ? lowerCasePath.substring(lowerCasePath.lastIndexOf(".")) : specialSuffix;
201                                 Calendar calendar = Calendar.getInstance();
202                                 String filename = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(calendar.getTime()) + suffix;
203
204                                 //  ダイアログを表示して保存する
205                                 saveImageWithDialog(filename, downloadSize, getInformation);
206                         }
207                         catch (Exception e)
208                         {
209                                 e.printStackTrace();
210                         }
211                 }
212 */
213                 return (super.onOptionsItemSelected(item));
214         }
215
216     private void showFileInformation(final ICameraFileInfo fileInfo)
217     {
218         runOnUiThread(new Runnable() {
219             @Override
220             public void run() {
221                 String message = "";
222                 try {
223                     String model = fileInfo.getModel();
224                     String dateTime = "";
225                     Date date = fileInfo.getDatetime();
226                     if (date != null) {
227                         dateTime = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss", Locale.US).format(date);
228                     }
229                     String path = fileInfo.getDirectoryPath() + "/" + fileInfo.getFilename();
230                     String shutter = fileInfo.getShutterSpeed();
231                     shutter = shutter.replace(".", "/");
232                     String aperture = fileInfo.getAperature();
233                     String iso = fileInfo.getIsoSensitivity();
234                     String expRev = fileInfo.getExpRev();
235
236                     message = path + "\r\n" + dateTime + "\r\n" + "- - - - - - - - - -\r\n  " + shutter + "  F" + aperture + " (" + expRev + ")" + " ISO" + iso + "\r\n" + "- - - - - - - - - -\r\n" + "  model : " + model + "\r\n";
237                 }
238                 catch (Exception e)
239                 {
240                     e.printStackTrace();
241                 }
242                 presentMessage(getString(R.string.download_control_get_information_title), message);
243                 System.gc();
244             }
245         });
246
247     }
248
249     @Override
250         public void onResume()
251     {
252                 super.onResume();
253                 AppCompatActivity activity = (AppCompatActivity)getActivity();
254                 if (activity != null)
255                 {
256             ActionBar bar = activity.getSupportActionBar();
257             if (bar != null)
258             {
259                 bar.setDisplayShowHomeEnabled(true);
260                 bar.show();
261             }
262         }
263                 viewPager.setCurrentItem(contentIndex);
264         }
265
266         @Override
267         public void onPause()
268         {
269                 super.onPause();
270                 AppCompatActivity activity = (AppCompatActivity)getActivity();
271                 if (activity != null)
272                 {
273             ActionBar bar = activity.getSupportActionBar();
274             if (bar != null)
275             {
276                 bar.hide();
277             }
278         }
279         }
280
281         private class ImagePagerAdapter extends PagerAdapter
282     {
283
284                 @Override
285                 public int getCount() {
286                         return contentList.size();
287                 }
288
289                 @Override
290                 public boolean isViewFromObject(@NonNull View view, @NonNull Object object)
291         {
292                         return (view.equals(object));
293                 }
294                 
295                 @Override
296                 public @NonNull Object instantiateItem(@NonNull ViewGroup container, int position)
297         {
298                         ImageView view = (ImageView)layoutInflater.inflate(R.layout.view_image_page, container, false);
299                         container.addView(view);
300                         downloadImage(position, view);
301                         return (view);
302                 }
303                 
304                 @Override
305                 public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object)
306                 {
307                         container.removeView((ImageView)object);
308                 }
309                 
310         }
311
312         private class ImagePageChangeListener implements OnPageChangeListener
313         {
314
315                 @Override
316                 public void onPageScrollStateChanged(int state)
317                 {
318
319                 }
320
321                 @Override
322                 public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
323                 {
324
325                 }
326
327                 @Override
328                 public void onPageSelected(int position)
329                 {
330                         contentIndex = position;
331                         try
332                         {
333                 ICameraFileInfo file = (contentList.get(contentIndex)).getFileInfo();
334                 String path = file.getDirectoryPath() + "/" + file.getFilename();
335
336                 AppCompatActivity activity = (AppCompatActivity) getActivity();
337                 if (activity != null)
338                 {
339                     ActionBar bar = activity.getSupportActionBar();
340                     if (bar != null)
341                     {
342                         bar.setTitle(path);
343                     }
344                     activity.getSupportActionBar().setTitle(path);
345                     activity.getFragmentManager().invalidateOptionsMenu();
346                 }
347                         }
348                         catch (Exception e)
349             {
350                 e.printStackTrace();
351             }
352                 }
353         }
354
355         private void downloadImage(final int position, final ImageView view)
356         {
357                 Thread thread = new Thread(new Runnable() {
358                         @Override
359                         public void run() {
360                                 downloadImageImpl(position, view);
361                         }
362                 });
363                 try
364                 {
365                         thread.start();
366                 }
367                 catch (Exception e)
368                 {
369                         e.printStackTrace();
370                 }
371         }
372
373         private void downloadImageImpl(int position, final ImageView view)
374     {
375         try
376         {
377             ICameraFileInfo file = (contentList.get(position)).getFileInfo();
378             final String path = file.getDirectoryPath() + "/" + file.getFilename();
379
380             // Get the cached image.
381             final Bitmap bitmap = imageCache.get(path);
382             if (bitmap != null)
383             {
384                 if (view != null && viewPager.indexOfChild(view) > -1)
385                 {
386                     runOnUiThread(new Runnable()
387                     {
388                         @Override
389                         public void run()
390                         {
391                             view.setImageBitmap(bitmap);
392                         }
393                     });
394                 }
395                 return;
396             }
397
398             // Download the image.
399             playbackControl.downloadContentScreennail(path, new IDownloadThumbnailImageCallback() {
400                 @Override
401                 public void onProgress(ProgressEvent e) {
402                     // MARK: Do not use to cancel a downloading by progress handler.
403                     //       A communication error may occur by the downloading of the next image when
404                     //       you cancel the downloading of the image by a progress handler in
405                     //       the current version.
406                 }
407
408                 @Override
409                                 //public void onCompleted(final byte[] data, final Map<String, Object> metadata) {
410                 public void onCompleted(final Bitmap bitmap, final Map<String, Object> metadata) {
411                     // Cache the downloaded image.
412
413                     //final Bitmap bitmap = createRotatedBitmap(data, metadata);
414                     try {
415                         if (bitmap == null)
416                         {
417                             System.gc();
418                             return;
419                         }
420                         if (imageCache != null)
421                                                 {
422                             imageCache.put(path, bitmap);
423                         }
424                     }
425                     catch (Exception e)
426                     {
427                         e.printStackTrace();
428                     }
429                     runOnUiThread(new Runnable() {
430                         @Override
431                         public void run() {
432                             if ((bitmap != null) && (view != null) && (viewPager.indexOfChild(view) > -1))
433                             {
434                                 view.setImageBitmap(bitmap);
435                             }
436                         }
437                     });
438                 }
439
440                 @Override
441                 public void onErrorOccurred(Exception e) {
442                     final String message = e.getMessage();
443                     runOnUiThread(new Runnable() {
444                         @Override
445                         public void run() {
446                             presentMessage("Load failed", message);
447                         }
448                     });
449                 }
450             });
451         }
452         catch (Exception e)
453         {
454             e.printStackTrace();
455         }
456         }
457
458         /**
459          *   デバイスに画像ファイルをダウンロード(保存)する
460          *
461          * @param filename       ファイル名(カメラ内の)
462          * @param downloadSize   ダウンロードサイズ
463      * @param isGetInformationMode 情報取得モードか?
464      */
465         public void saveImageWithDialog(final String filename, float downloadSize, boolean isGetInformationMode)
466         {
467             try
468         {
469             if (filename.endsWith(JPEG_SUFFIX)) {
470                 // 静止画の取得
471                 MyImageDownloader imageDownloader = new MyImageDownloader(filename, downloadSize, isGetInformationMode);
472                 imageDownloader.startDownload();
473             } else {
474                 // 動画・RAWファイルの取得
475                 MyMovieDownloader movieDownloader = new MyMovieDownloader(filename);
476                 movieDownloader.startDownload();
477             }
478         }
479         catch (Exception e)
480         {
481             e.printStackTrace();
482         }
483         }
484
485
486         // -------------------------------------------------------------------------
487         // Helpers
488         // -------------------------------------------------------------------------
489         
490         private void presentMessage(String title, String message)
491     {
492                 AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
493                 builder.setTitle(title).setMessage(message);
494                 builder.show();
495         }
496         
497         private void runOnUiThread(Runnable action)
498     {
499                 if (getActivity() == null)
500         {
501                         return;
502                 }
503                 getActivity().runOnUiThread(action);
504         }
505         
506         private Bitmap createRotatedBitmap(byte[] data, Map<String, Object> metadata)
507         {
508                 Bitmap bitmap;
509                 try
510                 {
511                         bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
512                 }
513                 catch (OutOfMemoryError e)
514                 {
515                         e.printStackTrace();
516                         bitmap = null;
517                         System.gc();
518                 }
519                 if (bitmap == null)
520                 {
521                         return (null);
522                 }
523
524                 // ビットマップの回転を行う
525                 int degrees = getRotationDegrees(data, metadata);
526                 if (degrees != 0)
527                 {
528                         Matrix m = new Matrix();
529                         m.postRotate(degrees);
530                         try
531                         {
532                                 bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), m, true);
533                         }
534                         catch (OutOfMemoryError e)
535                         {
536                                 e.printStackTrace();
537                                 bitmap = null;
538                                 System.gc();
539                         }
540                 }
541                 return (bitmap);
542         }
543         
544         private int getRotationDegrees(byte[] data, Map<String, Object> metadata)
545         {
546                 int degrees = 0;
547                 int orientation = ExifInterface.ORIENTATION_UNDEFINED;
548                 
549                 if (metadata != null && metadata.containsKey("Orientation")) {
550                         orientation = Integer.parseInt((String)metadata.get("Orientation"));
551                 }
552                 else
553                 {
554                         // Gets image orientation to display a picture.
555                         try
556             {
557                                 File tempFile = File.createTempFile("temp", null);
558                                 {
559                                         FileOutputStream outStream = new FileOutputStream(tempFile.getAbsolutePath());
560                                         outStream.write(data);
561                                         outStream.close();
562                                 }
563                                 ExifInterface exifInterface = new ExifInterface(tempFile.getAbsolutePath());
564                                 orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED);
565                                 if (!tempFile.delete())
566                 {
567                     Log.v(TAG, "temp file delete failure.");
568                 }
569                         }
570             catch (IOException e)
571             {
572                 e.printStackTrace();
573                         }
574                 }
575
576                 switch (orientation)
577                 {
578             case ExifInterface.ORIENTATION_NORMAL:
579                 degrees = 0;
580                 break;
581             case ExifInterface.ORIENTATION_ROTATE_90:
582                 degrees = 90;
583                 break;
584             case ExifInterface.ORIENTATION_ROTATE_180:
585                 degrees = 180;
586                 break;
587             case ExifInterface.ORIENTATION_ROTATE_270:
588                 degrees = 270;
589                 break;
590             default:
591                 break;
592                 }
593                 return degrees;
594         }
595
596     /**
597      *   静止画のダウンロード(とEXIF情報の取得)
598      *
599      */
600         private class MyImageDownloader implements IDownloadImageCallback
601         {
602         private boolean isGetInformation;
603                 private ProgressDialog downloadDialog = null;
604                 private String filename;
605                 private float downloadImageSize;
606
607                 /**
608                  *   コンストラクタ
609                  *
610                  * @param filename  ファイル名
611                  * @param downloadSize  ダウンロードのサイズ
612          * @param isGetInformation  情報を取得するだけかどうか(trueなら情報を取得するだけ)
613          */
614                 MyImageDownloader(final String filename, float downloadSize, boolean isGetInformation)
615                 {
616                         this.filename = filename;
617                         this.downloadImageSize = downloadSize;
618             this.isGetInformation = isGetInformation;
619                 }
620
621                 /**
622                  *   静止画のダウンロード開始指示
623                  *
624                  */
625                 void startDownload()
626                 {
627                         Log.v(TAG, "startDownload() " + filename);
628                         downloadDialog = new ProgressDialog(getContext());
629             if (isGetInformation)
630             {
631                 downloadDialog.setTitle(getString(R.string.dialog_get_information_title));
632             }
633             else
634             {
635                 downloadDialog.setTitle(getString(R.string.dialog_download_title));
636             }
637                         downloadDialog.setMessage(getString(R.string.dialog_download_message) + " " + filename);
638                         downloadDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
639                         downloadDialog.setCancelable(false);
640                         downloadDialog.show();
641
642                         // Download the image.
643             try
644             {
645                 ICameraFileInfo file = (contentList.get(contentIndex)).getFileInfo();
646                 String path = file.getDirectoryPath() + "/" + file.getFilename();
647                 playbackControl.downloadImage(path, downloadImageSize, this);
648             }
649             catch (Exception e)
650             {
651                 e.printStackTrace();
652             }
653                 }
654
655                 /**
656                  *   進行中の表示 (進捗バーの更新)
657                  *
658                  * @param progressEvent 進捗情報
659          */
660                 @Override
661                 public void onProgress(ProgressEvent progressEvent)
662                 {
663                         //
664                         if (downloadDialog != null)
665                         {
666                                 int percent = (int)(progressEvent.getProgress() * 100.0f);
667                                 downloadDialog.setProgress(percent);
668                                 //downloadDialog.setCancelable(progressEvent.isCancellable()); // キャンセルできるようにしないほうが良さそうなので
669                         }
670                 }
671
672                 /**
673                  *   ファイル受信終了時の処理
674                  *
675                  * @param bytes  受信バイト数
676          * @param map    ファイルの情報
677          */
678                 @Override
679                 public void onCompleted(byte[] bytes, Map<String, Object> map)
680                 {
681 /*
682             if (isGetInformation) {
683                 // Exif情報をダイアログ表示して終わる
684                 showExifInformation(bytes);
685                 System.gc();
686                 return;
687             }
688 */
689             final String directoryPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getPath() + "/" + getString(R.string.app_name2) + "/";
690             final String filepath = new File(directoryPath.toLowerCase(), filename).getPath();
691
692             // ファイルを保存する
693             try {
694                 final File directory = new File(directoryPath);
695                 if (!directory.exists()) {
696                     if (!directory.mkdirs()) {
697                         Log.v(TAG, "MKDIR FAIL. : " + directoryPath);
698                     }
699                 }
700                 FileOutputStream outputStream = new FileOutputStream(filepath);
701                 outputStream.write(bytes);
702                 outputStream.close();
703             } catch (Exception e) {
704                 final String message = e.getMessage();
705                 runOnUiThread(new Runnable() {
706                     @Override
707                     public void run() {
708                         if (downloadDialog != null) {
709                             downloadDialog.dismiss();
710                         }
711                         presentMessage(getString(R.string.download_control_save_failed), message);
712                     }
713                 });
714                 // ダウンロード失敗時には、ギャラリーにデータ登録を行わない。
715                 return;
716             }
717
718             boolean hasGps = false;
719             float[] latLong = new float[2];
720             try
721             {
722                 //
723                 ExifInterface exif = new ExifInterface(filepath);
724                 hasGps = exif.getLatLong(latLong);
725             }
726             catch (Exception e)
727             {
728                 e.printStackTrace();
729             }
730
731                         // ギャラリーに受信したファイルを登録する
732                         try
733                         {
734                                 long now = System.currentTimeMillis();
735                                 ContentValues values = new ContentValues();
736                                 values.put(Images.Media.MIME_TYPE, "image/jpeg");
737                                 values.put(Images.Media.DATA, filepath);
738                                 values.put(Images.Media.DATE_ADDED, now);
739                                 values.put(Images.Media.DATE_TAKEN, now);
740                 values.put(Images.Media.DATE_MODIFIED, now);
741                 values.put(Images.Media.ORIENTATION, getRotationDegrees(bytes, map));
742                 if (hasGps)
743                 {
744                     values.put(MediaStore.Images.Media.LATITUDE, latLong[0]);
745                     values.put(MediaStore.Images.Media.LONGITUDE, latLong[1]);
746                 }
747                 Activity activity = getActivity();
748                 if (activity != null)
749                 {
750                     ContentResolver resolver = getActivity().getContentResolver();
751                     final Uri insertedImage = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
752                 }
753
754                                 runOnUiThread(new Runnable() {
755                                         @Override
756                                         public void run()
757                                         {
758                                                 if (downloadDialog != null)
759                                                 {
760                                                         downloadDialog.dismiss();
761                                                 }
762                                                 Toast.makeText(getActivity(), getString(R.string.download_control_save_success) + " " + filename, Toast.LENGTH_SHORT).show();
763 /*
764                         try
765                         {
766                             SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getContext());
767                             if (preferences.getBoolean(ICameraPropertyAccessor.SHARE_AFTER_SAVE, false))
768                             {
769                                 shareContent(insertedImage);
770                             }
771                         }
772                         catch (Exception e)
773                         {
774                             e.printStackTrace();
775                         }
776 */
777                     }
778                                 });
779                         } catch (Exception e) {
780                                 final String message = e.getMessage();
781                                 runOnUiThread(new Runnable() {
782                                         @Override
783                                         public void run() {
784                                                 if (downloadDialog != null)
785                                                 {
786                                                         downloadDialog.dismiss();
787                                                 }
788                                                 presentMessage(getString(R.string.download_control_save_failed), message);
789                                         }
790                                 });
791                         }
792                         System.gc();
793                 }
794
795         /**
796          *   エラー発生時の処理
797          *
798          * @param e エラーの情報
799          */
800                 @Override
801                 public void onErrorOccurred(Exception e)
802                 {
803                         final String message = e.getMessage();
804                         runOnUiThread(new Runnable()
805                         {
806                                 @Override
807                                 public void run()
808                                 {
809                                         if (downloadDialog != null)
810                                         {
811                                                 downloadDialog.dismiss();
812                                         }
813                     if (isGetInformation)
814                     {
815                         presentMessage(getString(R.string.download_control_get_information_failed), message);
816                     }
817                     else
818                     {
819                         presentMessage(getString(R.string.download_control_download_failed), message);
820                     }
821                                 }
822                         });
823                 }
824
825         /**
826          *   共有の呼び出し
827          *
828          * @param pictureUri  画像ファイル名
829          */
830         private void shareContent(final Uri pictureUri)
831         {
832             Intent intent = new Intent();
833             intent.setAction(Intent.ACTION_SEND);
834             try
835             {
836                 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
837                 intent.setType("image/jpeg");
838                 intent.putExtra(Intent.EXTRA_STREAM, pictureUri);
839                 getActivity().startActivityForResult(intent, 0);
840             }
841             catch (Exception e)
842             {
843                 e.printStackTrace();
844                 Log.v(TAG, " URI : " + pictureUri);
845             }
846         }
847
848
849
850         /**
851          *   EXIF情報の表示 (ExifInterface を作って、表示クラスに渡す)
852          *
853          * @param bytes データ並び
854          */
855         private void showExifInformation(byte[] bytes)
856         {
857             ExifInterface exif = null;
858             try
859             {
860                 Calendar calendar = Calendar.getInstance();
861                 String filename = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(calendar.getTime());
862                 File tempFile = File.createTempFile(filename, null);
863                 {
864                     FileOutputStream outStream = new FileOutputStream(tempFile.getAbsolutePath());
865                     outStream.write(bytes);
866                     outStream.close();
867                 }
868                 exif = new ExifInterface(tempFile.getAbsolutePath());
869                 if (!tempFile.delete())
870                 {
871                     Log.v(TAG, "temp file delete failure.");
872                 }
873             }
874             catch (IOException e)
875             {
876                 e.printStackTrace();
877             }
878             runOnUiThread(new ExifInfoToShow(exif));
879         }
880
881         /**
882          *   EXIF情報を表示する処理
883          *   (クラス生成時に、表示情報を作り出す)
884          */
885         private class ExifInfoToShow implements Runnable
886         {
887             private String message = "";
888
889             /**
890              *   コンストラクタ
891              * @param information メッセージ
892              */
893             ExifInfoToShow(ExifInterface information)
894             {
895                 this.message = formMessage(information);
896             }
897
898             /**
899              *   Exif情報を表示に適した形式に変更し、情報を表示する
900              * @param exifInterface Exif情報
901              * @return 表示に適したExif情報
902              */
903             private String formMessage(ExifInterface exifInterface)
904             {
905                 String msg = "";
906                 if (exifInterface != null) {
907                                         // 撮影時刻
908                                         msg = msg + getString(R.string.exif_datetime_title);
909                                         msg = msg + " " + getExifAttribute(exifInterface, ExifInterface.TAG_DATETIME) + "\r\n"; //(string)
910                                         //msg = msg + "\r\n";
911
912                                         // 焦点距離
913                                         double focalLength = exifInterface.getAttributeDouble(ExifInterface.TAG_FOCAL_LENGTH, 0.0f);
914                                         msg = msg + getString(R.string.exif_focal_length_title);
915                                         msg = msg + " " + String.valueOf(focalLength) + "mm ";
916                                         msg = msg + "(" + getString(R.string.exif_focal_35mm_equiv_title) + " " + String.valueOf(focalLength * 2.0d) + "mm)" + "\r\n";
917                                         msg = msg + "\r\n";
918
919                                         // カスタムイメージプロセッシング利用の有無
920                                         //if (exifInterface.getAttributeInt(ExifInterface.TAG_CUSTOM_RENDERED, 0) != 0)
921                                         //{
922                                         //      msg = msg + getString(R.string.exif_custom_process_title) + "\r\n";
923                                         //}
924
925                                         // 撮影モード
926                                         String[] stringArray = getResources().getStringArray(R.array.exif_exposure_program_value);
927                                         int exposureProgram = exifInterface.getAttributeInt(ExifInterface.TAG_EXPOSURE_PROGRAM, 0);
928                                         msg = msg + getString(R.string.exif_camera_mode_title);
929                                         msg = msg + " " + ((stringArray.length > exposureProgram) ? stringArray[exposureProgram] : ("? (" + exposureProgram + ")")) + "\r\n";
930                                         //msg = msg + "\r\n";
931
932                                         // 測光モードの表示
933                                         String[] meteringStringArray = getResources().getStringArray(R.array.exif_metering_mode_value);
934                                         int metering = exifInterface.getAttributeInt(ExifInterface.TAG_METERING_MODE, 0);
935                                         msg = msg + getString(R.string.exif_metering_mode_title);
936                                         msg = msg + " " + ((meteringStringArray.length > metering) ? meteringStringArray[metering] : ("? (" + metering + ")")) + "\r\n";
937                                         //msg = msg + "\r\n";
938
939                     // 露光時間
940                     msg = msg + getString(R.string.exif_exposure_time_title);
941                                         String expTime =  getExifAttribute(exifInterface, ExifInterface.TAG_EXPOSURE_TIME);
942                                         float val, inv = 0.0f;
943                                         try
944                                         {
945                                                 val = Float.parseFloat(expTime);
946                                                 if (val < 1.0f)
947                                                 {
948                                                         inv = 1.0f / val;
949                                                 }
950                                                 if (inv < 2.0f)  // if (inv < 10.0f)
951                                                 {
952                                                         inv = 0.0f;
953                                                 }
954                                         }
955                                         catch (Exception e)
956                                         {
957                                                 //
958                                                 e.printStackTrace();
959                                         }
960
961                     //msg = msg + " " + expTime + "s "; //(string)
962                                         if (inv > 0.0f)
963                                         {
964                         // シャッター速度を分数で表示する
965                         int intValue = (int) inv;
966                         int modValue = intValue % 10;
967                         if ((modValue == 9)||(modValue == 4))
968                         {
969                             // ちょっと格好が悪いけど...切り上げ
970                             intValue++;
971                         }
972                         msg = msg + " 1/" + intValue + " s ";
973                                         }
974                     else
975                     {
976                         // シャッター速度を数値(秒数)で表示する
977                         msg = msg + " " + expTime + "s "; //(string)
978                     }
979                                         msg = msg + "\r\n";
980
981                     // 絞り値
982                     msg = msg + getString(R.string.exif_aperture_title);
983                     msg = msg + " " + getExifAttribute(exifInterface, ExifInterface.TAG_F_NUMBER) + "\r\n";  // (string)
984
985                     // ISO感度
986                     msg = msg + getString(R.string.exif_iso_title);
987                     msg = msg + " " + getExifAttribute(exifInterface, ExifInterface.TAG_ISO_SPEED_RATINGS) + "\r\n";  // (string)
988
989                     msg = msg + "\r\n";
990
991                     // カメラの製造元
992                     msg = msg + getString(R.string.exif_maker_title);
993                     msg = msg + " " + getExifAttribute(exifInterface, ExifInterface.TAG_MAKE) + "\r\n";
994
995                     // カメラのモデル名
996                     msg = msg + getString(R.string.exif_camera_title);
997                     msg = msg + " " + getExifAttribute(exifInterface, ExifInterface.TAG_MODEL)+ "\r\n";  // (string)
998
999                                         String lat = getExifAttribute(exifInterface, ExifInterface.TAG_GPS_LATITUDE);
1000                                         if ((lat != null)&&(lat.length() > 0))
1001                                         {
1002                         // 「位置情報あり」と表示
1003                                                 msg = msg + "\r\n  " + getString(R.string.exif_with_gps) + "\r\n";
1004                                         }
1005                     //msg = msg + getExifAttribute(exifInterface, ExifInterface.TAG_FLASH);      // フラッシュ (int)
1006                     //msg = msg + getExifAttribute(exifInterface, ExifInterface.TAG_ORIENTATION);  // 画像の向き (int)
1007                     //msg = msg + getExifAttribute(exifInterface, ExifInterface.TAG_WHITE_BALANCE);  // ホワイトバランス (int)
1008
1009                     // その他の情報...EXIFタグで取得できたものをログにダンプする
1010                     msg = msg + ExifInformationDumper.dumpExifInformation(exifInterface, false);
1011                 }
1012                 else
1013                 {
1014                     msg = getString(R.string.download_control_get_information_failed);
1015                 }
1016                 return (msg);
1017             }
1018
1019             private String getExifAttribute(ExifInterface attr, String tag)
1020             {
1021                 String value = attr.getAttribute(tag);
1022                 if (value == null)
1023                 {
1024                     value = "";
1025                 }
1026                 return (value);
1027             }
1028
1029
1030             @Override
1031             public void run()
1032             {
1033                 if (downloadDialog != null)
1034                 {
1035                     downloadDialog.dismiss();
1036                 }
1037                 presentMessage(getString(R.string.download_control_get_information_title), message);
1038                 System.gc();
1039             }
1040         }
1041     }
1042
1043         /**
1044          *   動画(とRAWファイル)のダウンロード
1045          *
1046          */
1047         private class MyMovieDownloader implements IDownloadLargeContentCallback
1048         {
1049                 private ProgressDialog downloadDialog = null;
1050                 private String filename = null;
1051                 private String filepath = null;
1052                 private FileOutputStream outputStream = null;
1053
1054                 /**
1055                  *   コンストラクタ
1056                  *
1057                  * @param filename ファイル名
1058                  */
1059                 MyMovieDownloader(final String filename)
1060                 {
1061                         this.filename = filename;
1062                 }
1063
1064                 /**
1065                  *   ダウンロードの開始
1066                  *
1067                  */
1068                 void startDownload()
1069                 {
1070                         Log.v(TAG, "startDownload() " + filename);
1071                         downloadDialog = new ProgressDialog(getContext());
1072                         downloadDialog.setTitle(getString(R.string.dialog_download_file_title));
1073                         downloadDialog.setMessage(getString(R.string.dialog_download_message) + " " + filename);
1074                         downloadDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
1075                         downloadDialog.setCancelable(false);
1076                         downloadDialog.show();
1077
1078                         // Download the image.
1079             try
1080             {
1081                 ImageContentInfoEx content = contentList.get(contentIndex);
1082                 ICameraFileInfo file = content.getFileInfo();
1083                 String targetFileName = file.getFilename();
1084                 if (content.hasRaw())
1085                 {
1086                     targetFileName = targetFileName.replace(".JPG", ".ORF");
1087                 }
1088                 String path = file.getDirectoryPath() + "/" + targetFileName;
1089                 Log.v(TAG, "downloadLargeContent : " + path);
1090                 playbackControl.downloadLargeContent(path, this);
1091
1092                 final String directoryPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getPath() + "/" + getString(R.string.app_name2) + "/";
1093                 filepath = new File(directoryPath.toLowerCase(), filename).getPath();
1094                 try {
1095                     final File directory = new File(directoryPath);
1096                     if (!directory.exists())
1097                     {
1098                         if (!directory.mkdirs())
1099                         {
1100                             Log.v(TAG, "MKDIR FAIL. : " + directoryPath);
1101                         }
1102                     }
1103                     outputStream = new FileOutputStream(filepath);
1104                 }
1105                 catch (Exception e)
1106                 {
1107                     final String message = e.getMessage();
1108                     runOnUiThread(new Runnable() {
1109                         @Override
1110                         public void run() {
1111                             if (downloadDialog != null) {
1112                                 downloadDialog.dismiss();
1113                             }
1114                             presentMessage(getString(R.string.download_control_save_failed), message);
1115                         }
1116                     });
1117                 }
1118             }
1119             catch (Exception ex)
1120             {
1121                 ex.printStackTrace();
1122             }
1123                 }
1124
1125                 @Override
1126                 public void onProgress(byte[] bytes, ProgressEvent progressEvent)
1127                 {
1128                         if (downloadDialog != null)
1129                         {
1130                                 int percent = (int)(progressEvent.getProgress() * 100.0f);
1131                                 downloadDialog.setProgress(percent);
1132                                 //downloadDialog.setCancelable(progressEvent.isCancellable()); // キャンセルできるようにしないほうが良さそうなので
1133                         }
1134                         try
1135                         {
1136                                 if (outputStream != null)
1137                                 {
1138                                         outputStream.write(bytes);
1139                                 }
1140                         }
1141             catch (Exception e)
1142                         {
1143                 e.printStackTrace();
1144                         }
1145                 }
1146
1147                 @Override
1148                 public void onCompleted()
1149                 {
1150                         try
1151                         {
1152                                 if (outputStream != null)
1153                                 {
1154                                         outputStream.flush();
1155                                         outputStream.close();
1156                     outputStream = null;
1157                                 }
1158                 if (!filename.endsWith(RAW_SUFFIX))
1159                 {
1160                     // ギャラリーに受信したファイルを登録する
1161                     long now = System.currentTimeMillis();
1162                     ContentValues values = new ContentValues();
1163                     ContentResolver resolver = getActivity().getContentResolver();
1164                     values.put(Images.Media.MIME_TYPE, "video/mp4");
1165                     values.put(Images.Media.DATA, filepath);
1166                     values.put(Images.Media.DATE_ADDED, now);
1167                     values.put(Images.Media.DATE_TAKEN, now);
1168                     values.put(Images.Media.DATE_MODIFIED, now);
1169                                         final Uri content = resolver.insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, values);
1170 /*
1171                     try
1172                     {
1173                         SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getContext());
1174                         if (preferences.getBoolean(ICameraPropertyAccessor.SHARE_AFTER_SAVE, false))
1175                         {
1176                             runOnUiThread(new Runnable()
1177                             {
1178                                 @Override
1179                                 public void run()
1180                                 {
1181                                     shareContent(content);
1182                                 }
1183                             });
1184                         }
1185                     }
1186                     catch (Exception e)
1187                     {
1188                         e.printStackTrace();
1189                     }
1190 */
1191                 }
1192                                 runOnUiThread(new Runnable() {
1193                                         @Override
1194                                         public void run()
1195                                         {
1196                                                 if (downloadDialog != null)
1197                                                 {
1198                                                         downloadDialog.dismiss();
1199                                                 }
1200                                                 Toast.makeText(getActivity(), getString(R.string.download_control_save_success) + " " + filename, Toast.LENGTH_SHORT).show();
1201                         System.gc();
1202                                         }
1203                                 });
1204                         }
1205                         catch (Exception e)
1206                         {
1207                                 final String message = e.getMessage();
1208                                 runOnUiThread(new Runnable() {
1209                                         @Override
1210                                         public void run() {
1211                                                 if (downloadDialog != null)
1212                                                 {
1213                                                         downloadDialog.dismiss();
1214                                                 }
1215                                                 presentMessage(getString(R.string.download_control_save_failed), message);
1216                                         }
1217                                 });
1218                         }
1219             System.gc();
1220                 }
1221
1222                 @Override
1223                 public void onErrorOccurred(Exception e)
1224                 {
1225                         final String message = e.getMessage();
1226             try
1227             {
1228                 if (outputStream != null)
1229                 {
1230                     outputStream.flush();
1231                     outputStream.close();
1232                     outputStream = null;
1233                 }
1234             }
1235             catch (Exception ex)
1236             {
1237                 e.printStackTrace();
1238                 ex.printStackTrace();
1239             }
1240                         runOnUiThread(new Runnable()
1241                         {
1242                                 @Override
1243                                 public void run()
1244                                 {
1245                                         if (downloadDialog != null)
1246                                         {
1247                                                 downloadDialog.dismiss();
1248                                         }
1249                                         presentMessage(getString(R.string.download_control_download_failed), message);
1250                     System.gc();
1251                                 }
1252                         });
1253                         System.gc();
1254                 }
1255
1256         /**
1257          *   共有の呼び出し
1258          *
1259          * @param movieFileUri  動画ファイルUri
1260          */
1261         private void shareContent(final Uri movieFileUri)
1262         {
1263             Intent intent = new Intent();
1264             intent.setAction(Intent.ACTION_SEND);
1265             try
1266             {
1267                 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
1268                 intent.setType("video/mp4");
1269                 intent.putExtra(Intent.EXTRA_STREAM, movieFileUri);
1270                 FragmentActivity activity = getActivity();
1271                 if (activity != null)
1272                 {
1273                                         activity.startActivityForResult(intent, 0);
1274                                 }
1275             }
1276             catch (Exception e)
1277             {
1278                 e.printStackTrace();
1279             }
1280         }
1281         }
1282 }