Statistics
| Branch: | Tag: | Revision:

securesmartcam / app / src / main / java / org / witness / obscuracam / ui / adapters / GalleryCursorRecyclerViewAdapter.java @ 41590feb

History | View | Annotate | Download (12.5 KB)

1
package org.witness.obscuracam.ui.adapters;
2

    
3
import android.content.Context;
4
import android.database.Cursor;
5
import android.database.MergeCursor;
6
import android.database.SQLException;
7
import android.graphics.Color;
8
import android.os.AsyncTask;
9
import android.provider.MediaStore;
10
import android.support.v7.widget.RecyclerView;
11
import android.text.TextUtils;
12
import android.util.Log;
13
import android.view.LayoutInflater;
14
import android.view.View;
15
import android.view.ViewGroup;
16

    
17
import com.squareup.picasso.Picasso;
18

    
19
import org.witness.sscphase1.R;
20

    
21
import java.io.File;
22

    
23
public class GalleryCursorRecyclerViewAdapter extends RecyclerView.Adapter<PhotoViewHolder> {
24
    private static final String LOGTAG = "GalleryCursorRVAdapter";
25
    private static final boolean LOGGING = false;
26

    
27
    private static final int CAMERA_ID = -100;
28
    private static final int ALBUMS_ID = -101;
29

    
30
    public interface GalleryCursorRecyclerViewAdapterListener {
31
        void onPhotoSelected(String photo, View thumbView);
32
        void onVideoSelected(String video, View thumbView);
33
        void onCameraSelected();
34
        void onAlbumsSelected();
35
    }
36

    
37
    private final Context mContext;
38
    private GalleryCursorRecyclerViewAdapterListener mListener;
39

    
40
    private UpdateTask mUpdateTask;
41
    private GalleryCursor mGalleryCursor;
42

    
43
    private final String mAlbum;
44
    private final boolean mShowCamera;
45
    private final boolean mShowAlbums;
46

    
47
    public GalleryCursorRecyclerViewAdapter(Context context, String album, boolean showCamera, boolean showAlbums) {
48
        super();
49
        mContext = context;
50
        setHasStableIds(true);
51
        mAlbum = album;
52
        mShowCamera = showCamera;
53
        mShowAlbums = showAlbums;
54
    }
55

    
56
    @Override
57
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
58
        super.onAttachedToRecyclerView(recyclerView);
59
        updateCursor();
60
    }
61

    
62
    @Override
63
    public void onDetachedFromRecyclerView(RecyclerView recyclerView) {
64
        super.onDetachedFromRecyclerView(recyclerView);
65
        synchronized (this) {
66
            if (mGalleryCursor != null) {
67
                mGalleryCursor.close();
68
                mGalleryCursor = null;
69
            }
70
        }
71
    }
72

    
73
    protected Context getContext() {
74
        return mContext;
75
    }
76

    
77
    public void setListener(GalleryCursorRecyclerViewAdapterListener listener) {
78
        mListener = listener;
79
    }
80

    
81
    public void update() {
82
        updateCursor();
83
    }
84

    
85
    @Override
86
    public int getItemCount() {
87
        int count = (mShowCamera ? 1 : 0) + (mShowAlbums ? 1 : 0);
88
        if (mGalleryCursor != null) {
89
            count += mGalleryCursor.getCount();
90
        }
91
        return count;
92
    }
93

    
94
    @Override
95
    public long getItemId(int position) {
96
        if (mShowCamera) {
97
            if (position == 0) {
98
                return CAMERA_ID;
99
            } else {
100
                position--;
101
            }
102
        }
103
        if (mShowAlbums) {
104
            if (position == 0) {
105
                return ALBUMS_ID;
106
            } else {
107
                position--;
108
            }
109
        }
110
        if (mGalleryCursor != null) {
111
            return mGalleryCursor.getItemId(position);
112
        }
113
        return -1;
114
    }
115

    
116
    @Override
117
    public int getItemViewType(int position) {
118
        long itemId = getItemId(position);
119
        if (itemId == CAMERA_ID) {
120
            return 1;
121
        } else if (itemId == ALBUMS_ID) {
122
            return 2;
123
        }
124
        return 0;
125
    }
126

    
127
    @Override
128
    public PhotoViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
129
        View view = LayoutInflater.from(mContext).inflate(viewType == 0 ? R.layout.photo_item : R.layout.photo_camera_item, parent, false);
130
        return new PhotoViewHolder(view);
131
    }
132

    
133
    @Override
134
    public void onBindViewHolder(PhotoViewHolder holder, int position) {
135
        if (mShowCamera) {
136
            if (position == 0) {
137
                holder.mRootView.setOnClickListener(new View.OnClickListener() {
138
                    @Override
139
                    public void onClick(View view) {
140
                        if (mListener != null) {
141
                            mListener.onCameraSelected();
142
                        }
143
                    }
144
                });
145
                return;
146
            } else {
147
                position--; //Offset by this item
148
            }
149
        }
150
        if (mShowAlbums) {
151
            if (position == 0) {
152
                holder.mPhoto.setImageResource(R.drawable.ic_photo_album_primary_36dp);
153
                holder.mRootView.setOnClickListener(new View.OnClickListener() {
154
                    @Override
155
                    public void onClick(View view) {
156
                        if (mListener != null) {
157
                            mListener.onAlbumsSelected();
158
                        }
159
                    }
160
                });
161
                return;
162
            } else {
163
                position--; //Offset by this item
164
            }
165
        }
166

    
167
        String data = "";
168
        boolean isVideo = false; //TODO
169
        try {
170
            int dataColumn = mGalleryCursor.getColumnIndex(MediaStore.MediaColumns.DATA);
171
            int typeColumn = mGalleryCursor.getColumnIndex(MediaStore.MediaColumns.MIME_TYPE);
172
            if (mGalleryCursor.moveToPosition(position)) {
173
                data = mGalleryCursor.getString(dataColumn);
174
                String type = mGalleryCursor.getString(typeColumn);
175
                isVideo = (type != null && type.toLowerCase().startsWith("video/"));
176
            }
177
        } catch (SQLException | IllegalStateException e) {
178
            if (LOGGING)
179
                e.printStackTrace();
180
        }
181

    
182
        holder.mPhoto.setBackgroundColor(Color.TRANSPARENT);
183
        holder.mRootView.setOnClickListener(new ItemClickListener(data, isVideo, holder.mPhoto));
184
        try {
185
            holder.mVideoIcon.setVisibility(isVideo ? View.VISIBLE : View.GONE);
186
            if (isVideo) {
187
                Picasso.with(mContext)
188
                        .load("video:" + data)
189
                        .placeholder(R.drawable.btn_preview)
190
                        .fit()
191
                        .centerCrop()
192
                        .into(holder.mPhoto);
193
            } else {
194
                Picasso.with(mContext)
195
                        .load(new File(data))
196
                        .fit()
197
                        .centerCrop()
198
                        .into(holder.mPhoto);
199
            }
200
        } catch (Exception ignored) {}
201
    }
202

    
203
    private void updateCursor() {
204
        if (mUpdateTask != null) {
205
            if (LOGGING)
206
                Log.d(LOGTAG, "Cancel update task");
207
            mUpdateTask.cancel(true);
208
        }
209
        mUpdateTask = new UpdateTask();
210
        mUpdateTask.execute();
211
    }
212

    
213
    private class UpdateTask extends AsyncTask<Void, Void, Cursor>
214
    {
215
        private Cursor cursor = null;
216

    
217
        UpdateTask()
218
        {
219
        }
220

    
221
        @Override
222
        protected Cursor doInBackground(Void... values)
223
        {
224
            if (LOGGING)
225
                Log.v(LOGTAG, "UpdateTask: doInBackground");
226

    
227
            cursor = null;
228
            Cursor photos = getMediaCursor(); // getPhotoCursor();
229
            Cursor videos = null; //getVideoCursor();
230
            if (photos != null && videos != null) {
231
                cursor = new MergeCursor(new Cursor[] { photos, videos });
232
            } else if (videos != null) {
233
                cursor = videos;
234
            } else if (photos != null) {
235
                cursor = photos;
236
            }
237
            return cursor;
238
        }
239

    
240
        private Cursor getPhotoCursor() {
241
            try {
242
                final String orderBy = MediaStore.Images.Media.DATE_TAKEN;
243
                String searchParams = null;
244
                if (!TextUtils.isEmpty(mAlbum)) {
245
                    searchParams = MediaStore.Images.Media.BUCKET_ID + " = \"" + mAlbum + "\"";
246
                }
247
                return mContext.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
248
                        null, searchParams, null, orderBy + " DESC");
249
            } catch (Exception e) {
250
                e.printStackTrace();
251
            }
252
            return null;
253
        }
254

    
255
        private Cursor getVideoCursor() {
256
            try {
257
                final String orderBy = MediaStore.Video.Media.DATE_TAKEN;
258
                String searchParams = null;
259
                if (!TextUtils.isEmpty(mAlbum)) {
260
                    searchParams = MediaStore.Video.Media.BUCKET_ID + " = \"" + mAlbum + "\"";
261
                }
262
                return mContext.getContentResolver().query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
263
                        null, searchParams, null, orderBy + " DESC");
264
            } catch (Exception e) {
265
                e.printStackTrace();
266
            }
267
            return null;
268
        }
269

    
270
        private Cursor getMediaCursor() {
271
            try {
272
                final String orderBy = MediaStore.MediaColumns.DATE_ADDED;
273
                String searchParams = "";
274
                boolean hasAlbum = !TextUtils.isEmpty(mAlbum);
275
                if (hasAlbum) {
276
                    searchParams = MediaStore.Video.Media.BUCKET_ID + " = \"" + mAlbum + "\"";
277
                }
278

    
279
                String[] projection = {
280
                        MediaStore.Files.FileColumns._ID,
281
                        MediaStore.Files.FileColumns.DATA,
282
                        MediaStore.Files.FileColumns.DATE_ADDED,
283
                        MediaStore.Files.FileColumns.MEDIA_TYPE,
284
                        MediaStore.Files.FileColumns.MIME_TYPE,
285
                        MediaStore.Files.FileColumns.TITLE
286
                };
287

    
288
                // Return only video and image metadata.
289
                if (hasAlbum) {
290
                    searchParams += " AND (";
291
                }
292
                searchParams += MediaStore.Files.FileColumns.MEDIA_TYPE + "="
293
                        + MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE
294
                        + " OR "
295
                        + MediaStore.Files.FileColumns.MEDIA_TYPE + "="
296
                        + MediaStore.Files.FileColumns.MEDIA_TYPE_VIDEO;
297
                if (hasAlbum) {
298
                    searchParams += ")";
299
                }
300

    
301
                return mContext.getContentResolver().query(MediaStore.Files.getContentUri("external"),
302
                        projection, searchParams, null, orderBy + " DESC");
303
            } catch (Exception e) {
304
                e.printStackTrace();
305
            }
306
            return null;
307
        }
308

    
309
        @Override
310
        protected void onCancelled() {
311
            super.onCancelled();
312
            if (cursor != null) {
313
                if (LOGGING)
314
                    Log.d(LOGTAG, "Cancelled - Close cursor " + cursor.hashCode());
315
                cursor.close();
316
            }
317
        }
318

    
319
        @Override
320
        protected void onPostExecute(Cursor cursor)
321
        {
322
            synchronized (GalleryCursorRecyclerViewAdapter.this) {
323
                if (mUpdateTask == this)
324
                    mUpdateTask = null;
325
                if (LOGGING)
326
                    Log.v(LOGTAG, "UpdateTask: finished");
327
                GalleryCursor newCursor = null;
328
                if (cursor != null) {
329
                    newCursor = new GalleryCursor(cursor);
330
                }
331
                if (getCursor() != null) {
332
                    if (LOGGING)
333
                        Log.v(LOGTAG, "Old cursor set, Close cursor " + getCursor().hashCode());
334
                    getCursor().close();
335
                }
336
                if (LOGGING)
337
                    Log.v(LOGTAG, newCursor == null ? "No cursor" : ("Opened cursor " + newCursor.hashCode()));
338
                mGalleryCursor = newCursor;
339
                //if (newCursor != null)
340
                //    DatabaseUtils.dumpCursor((net.sqlcipher.Cursor) newCursor.getWrappedCursor());
341
                notifyDataSetChanged();
342
//                if (mListener != null) {
343
//                    mListener.onCursorUpdated();
344
//                }
345
            }
346
        }
347
    }
348

    
349
    public GalleryCursor getCursor() {
350
        return mGalleryCursor;
351
    }
352

    
353
    private class ItemClickListener implements View.OnClickListener {
354
        private final String mData;
355
        private final boolean mIsVideo;
356
        private final View mThumbView;
357

    
358
        public ItemClickListener(String data, boolean isVideo, View thumbView) {
359
            mData = data;
360
            mIsVideo = isVideo;
361
            mThumbView = thumbView;
362
        }
363

    
364
        @Override
365
        public void onClick(View view) {
366
            if (mListener != null) {
367
                if (mIsVideo) {
368
                    mListener.onVideoSelected(mData, mThumbView);
369
                } else {
370
                    mListener.onPhotoSelected(mData, mThumbView);
371
                }
372
            }
373
        }
374
    }
375
}