/* * Copyright 2013 Chris Banes * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.zhaojian.jolly.fragment; import java.io.File; import java.util.ArrayList; import java.util.List; import android.app.Activity; import android.app.Fragment; import android.app.LoaderManager; import android.content.CursorLoader; import android.content.Intent; import android.content.Loader; import android.content.SharedPreferences; import android.database.Cursor; import android.media.MediaScannerConnection.OnScanCompletedListener; import android.net.Uri; import android.os.Build.VERSION; import android.os.Bundle; import android.preference.PreferenceManager; import android.provider.MediaStore; import android.provider.MediaStore.Images; import android.support.v4.app.ActivityCompat; import android.support.v4.app.ActivityOptionsCompat; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.AdapterView.OnItemSelectedListener; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.GridView; import android.widget.LinearLayout; import android.widget.Spinner; import com.commonsware.cwac.merge.MergeAdapter; import com.zhaojian.jolly.adapter.CameraBaseAdapter; import com.zhaojian.jolly.adapter.UsersPhotosCursorAdapter; import com.zhaojian.jolly.constant.PreferenceConstants; import com.zhaojian.jolly.controller.PhotoUploadController; import com.zhaojian.jolly.listener.OnNumChangeListener; import com.zhaojian.jolly.model.MediaStoreBucket; import com.zhaojian.jolly.model.PhotoUpload; import com.zhaojian.jolly.selectphotos.PhotoViewerActivity; import com.zhaojian.jolly.tasks.MediaStoreBucketsAsyncTask; import com.zhaojian.jolly.tasks.MediaStoreBucketsAsyncTask.MediaStoreBucketsResultListener; import com.zhaojian.jolly.utils.MediaStoreCursorHelper; import com.zhaojian.jolly.utils.PhotupCursorLoader; import com.zhaojian.jolly.utils.Utils; import com.zhaojian.select_photo_library.R; public class UserPhotosFragment extends Fragment implements OnItemClickListener, LoaderManager.LoaderCallbacks<Cursor>, MediaStoreBucketsResultListener, OnItemSelectedListener, OnScanCompletedListener, OnNumChangeListener { static final int RESULT_CAMERA = 101; static final int RESULT_PHOTOVIEW = 102; static final String PHOTO_URIS="photo_uris"; static final String SAVE_PHOTO_URI = "camera_photo_uri"; static final String LOADER_PHOTOS_BUCKETS_PARAM = "bucket_id"; static final int LOADER_USER_PHOTOS_EXTERNAL = 0x01; private MergeAdapter mAdapter; private UsersPhotosCursorAdapter mPhotoAdapter; private GridView mPhotoGrid; private LinearLayout back_btn; private Button finish_btn; private ArrayAdapter<MediaStoreBucket> mBucketAdapter; private Spinner mBucketSpinner; private final ArrayList<MediaStoreBucket> mBuckets = new ArrayList<MediaStoreBucket>(); private PhotoUploadController mPhotoSelectionController; private File mPhotoFile; private SharedPreferences mPrefs; @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); if (null != savedInstanceState) { if (savedInstanceState.containsKey(SAVE_PHOTO_URI)) { mPhotoFile = new File( savedInstanceState.getString(SAVE_PHOTO_URI)); } } } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case RESULT_CAMERA: if (null != mPhotoFile) { if (resultCode == Activity.RESULT_OK) { Utils.scanMediaJpegFile(getActivity(), mPhotoFile, this); } else { mPhotoFile.delete(); } mPhotoFile = null; } return; } switch(resultCode){ case RESULT_PHOTOVIEW: excuteFinish(); break; } super.onActivityResult(requestCode, resultCode, data); } @Override public void onAttach(Activity activity) { mPhotoSelectionController = PhotoUploadController .getFromContext(activity); mPhotoSelectionController.addMyEventListener(this); super.onAttach(activity); } @Override public void onResume() { // TODO Auto-generated method stub super.onResume(); if (mPhotoAdapter != null) { mPhotoAdapter.notifyDataSetChanged(); } } public void onBucketsLoaded(final List<MediaStoreBucket> buckets) { if (null != buckets && !buckets.isEmpty()) { mBuckets.clear(); mBuckets.addAll(buckets); mBucketAdapter.notifyDataSetChanged(); // setSelectedBucketFromPrefs(); } } public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mAdapter = new MergeAdapter(); if (Utils.hasCamera(getActivity())) { mAdapter.addAdapter(new CameraBaseAdapter(getActivity())); } mPhotoAdapter = new UsersPhotosCursorAdapter(getActivity(), null); mAdapter.addAdapter(mPhotoAdapter); mPrefs = PreferenceManager.getDefaultSharedPreferences(getActivity()); mBucketAdapter = new ArrayAdapter<MediaStoreBucket>(getActivity(), Utils.getSpinnerItemResId(), mBuckets); mBucketAdapter .setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); } public Loader<Cursor> onCreateLoader(final int id, Bundle bundle) { CursorLoader cursorLoader = null; switch (id) { case LOADER_USER_PHOTOS_EXTERNAL: String selection = null; String[] selectionArgs = null; if (null != bundle && bundle.containsKey(LOADER_PHOTOS_BUCKETS_PARAM)) { selection = Images.Media.BUCKET_ID + " = ?"; selectionArgs = new String[] { bundle .getString(LOADER_PHOTOS_BUCKETS_PARAM) }; } cursorLoader = new PhotupCursorLoader(getActivity(), MediaStoreCursorHelper.MEDIA_STORE_CONTENT_URI, MediaStoreCursorHelper.PHOTOS_PROJECTION, selection, selectionArgs, MediaStoreCursorHelper.PHOTOS_ORDER_BY, false); break; } return cursorLoader; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_user_photos, null); mPhotoGrid = (GridView) view.findViewById(R.id.gv_photos); mPhotoGrid.setAdapter(mAdapter); mPhotoGrid.setOnItemClickListener(this); mBucketSpinner = (Spinner) view.findViewById(R.id.sp_buckets); mBucketSpinner.setOnItemSelectedListener(this); mBucketSpinner.setAdapter(mBucketAdapter); back_btn = (LinearLayout) view.findViewById(R.id.back_btn); back_btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { getActivity().finish(); } }); finish_btn = (Button) view.findViewById(R.id.finish_btn); finish_btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { excuteFinish(); } }); OnChangeNum(); return view; } @Override public void onDestroy() { super.onDestroy(); saveSelectedBucketToPrefs(); } public void onItemClick(AdapterView<?> gridView, View view, int position, long id) { if (view.getId() == R.id.iv_camera_button) { takePhoto(); } else { Bundle b = null; if (VERSION.SDK_INT >= 16) { ActivityOptionsCompat options = ActivityOptionsCompat .makeThumbnailScaleUpAnimation(view, Utils.drawViewOntoBitmap(view), 0, 0); b = options.toBundle(); } Intent intent = new Intent(getActivity(), PhotoViewerActivity.class); // Need take Camera icon into account so minus 1 intent.putExtra(PhotoViewerActivity.EXTRA_POSITION, position - 1); intent.putExtra(PhotoViewerActivity.EXTRA_MODE, PhotoViewerActivity.MODE_ALL_VALUE); MediaStoreBucket bucket = (MediaStoreBucket) mBucketSpinner .getSelectedItem(); intent.putExtra(PhotoViewerActivity.EXTRA_BUCKET_ID, bucket.getId()); ActivityCompat.startActivityForResult(getActivity(), intent, RESULT_PHOTOVIEW, b); } } public void onItemSelected(AdapterView<?> adapterView, View view, int position, long id) { MediaStoreBucket item = (MediaStoreBucket) adapterView .getItemAtPosition(position); if (null != item) { loadBucketId(item.getId()); } } public void onLoaderReset(Loader<Cursor> loader) { } public void onLoadFinished(Loader<Cursor> loader, Cursor data) { switch (loader.getId()) { case LOADER_USER_PHOTOS_EXTERNAL: mPhotoAdapter.swapCursor(data); mPhotoGrid.setSelection(0); break; } } public void onNothingSelected(AdapterView<?> view) { // NO-OP } @Override public void onSaveInstanceState(Bundle outState) { if (null != mPhotoFile) { outState.putString(SAVE_PHOTO_URI, mPhotoFile.getAbsolutePath()); } super.onSaveInstanceState(outState); } public void onScanCompleted(String path, Uri uri) { getActivity().runOnUiThread(new Runnable() { public void run() { MediaStoreBucket bucket = getSelectedBucket(); if (null != bucket) { loadBucketId(bucket.getId()); } } }); } @Override public void onStart() { super.onStart(); // Load buckets MediaStoreBucketsAsyncTask.execute(getActivity(), this); } public void selectAll() { Cursor cursor = mPhotoAdapter.getCursor(); if (null != cursor) { ArrayList<PhotoUpload> selections = MediaStoreCursorHelper .photosCursorToSelectionList( MediaStoreCursorHelper.MEDIA_STORE_CONTENT_URI, cursor); mPhotoSelectionController.addSelections(selections); } } private MediaStoreBucket getSelectedBucket() { if (null != mBucketSpinner) { return (MediaStoreBucket) mBucketSpinner.getSelectedItem(); } return null; } private void loadBucketId(String id) { if (isAdded()) { Bundle bundle = new Bundle(); if (null != id) { bundle.putString(LOADER_PHOTOS_BUCKETS_PARAM, id); } try { getLoaderManager().restartLoader(LOADER_USER_PHOTOS_EXTERNAL, bundle, this); } catch (IllegalStateException e) { e.printStackTrace(); // Can sometimes catch with: Fragment not attached to Activity. // Not much we can do to recover } } } private void saveSelectedBucketToPrefs() { MediaStoreBucket bucket = getSelectedBucket(); if (null != bucket && null != mPrefs) { mPrefs.edit() .putString( PreferenceConstants.PREF_SELECTED_MEDIA_BUCKET_ID, bucket.getId()).commit(); } } private void setSelectedBucketFromPrefs() { if (null != mBucketSpinner) { int newSelection = 0; if (null != mPrefs) { final String lastBucketId = mPrefs .getString( PreferenceConstants.PREF_SELECTED_MEDIA_BUCKET_ID, null); if (null != lastBucketId) { for (int i = 0, z = mBuckets.size(); i < z; i++) { if (lastBucketId.equals(mBuckets.get(i).getId())) { newSelection = i; break; } } } } // If we have a new position, then just set it. If it's our current // position, then call onItemSelected manually if (newSelection != mBucketSpinner.getSelectedItemPosition()) { mBucketSpinner.setSelection(newSelection); } else { onItemSelected(mBucketSpinner, null, newSelection, 0); } } } private void takePhoto() { if (null == mPhotoFile) { Intent takePictureIntent = new Intent( MediaStore.ACTION_IMAGE_CAPTURE); mPhotoFile = Utils.getCameraPhotoFile(); takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mPhotoFile)); startActivityForResult(takePictureIntent, RESULT_CAMERA); } } @Override public void OnChangeNum() { finish_btn.setText("完成(" + mPhotoSelectionController.getSelectedCount() + ")"); } private void excuteFinish() { if (mPhotoSelectionController.getSelectedCount() > 0) { Intent intent = new Intent(); ArrayList<String> uri = new ArrayList<String>(); for(PhotoUpload photoUpload:mPhotoSelectionController.getSelected()){ String filePath = Utils.getPathFromContentUri( getActivity().getContentResolver(), photoUpload.getOriginalPhotoUri()); uri.add(filePath); } intent.putStringArrayListExtra(PHOTO_URIS,uri); getActivity().setResult(Activity.RESULT_OK,intent); mPhotoSelectionController.clearSelected(); getActivity().finish(); } } }