├── .gitignore ├── res ├── drawable-hdpi │ ├── icon.png │ ├── ic_action_share.png │ └── ic_options_menu_info.png ├── drawable-ldpi │ └── icon.png ├── drawable-mdpi │ ├── icon.png │ ├── ic_action_share.png │ └── ic_options_menu_info.png ├── layout │ ├── gallery_listing_activity.xml │ ├── grid_view_activity.xml │ ├── image_view_activity.xml │ ├── gallery_image_view.xml │ ├── comment_entry.xml │ ├── create_gallery_activity.xml │ └── image_information_view.xml ├── values │ ├── styles.xml │ └── strings.xml ├── menu │ ├── gallery_menu.xml │ ├── gallery_context_menu.xml │ ├── grid_view_context_menu.xml │ └── image_view_options_menu.xml └── values-de │ └── strings.xml ├── src └── de │ └── raptor2101 │ └── GalDroid │ ├── WebGallery │ ├── Interfaces │ │ ├── GalleryDownloadObject.java │ │ ├── GalleryObjectComment.java │ │ ├── GalleryProgressListener.java │ │ ├── GalleryObject.java │ │ └── WebGallery.java │ ├── Tasks │ │ ├── CacheTaskListener.java │ │ ├── TaskInterface.java │ │ ├── ImageInformationLoaderTaskListener.java │ │ ├── Progress.java │ │ ├── GalleryLoaderTaskListener.java │ │ ├── ImageLoaderTaskListener.java │ │ ├── SyncronizeCacheTask.java │ │ ├── CleanUpCacheTask.java │ │ ├── GalleryVerifyTask.java │ │ ├── GalleryLoaderTask.java │ │ ├── ImageInformationLoaderTask.java │ │ ├── RepeatingTask.java │ │ └── ImageLoaderTask.java │ ├── DegMinSec.java │ ├── ImageInformation.java │ ├── Gallery3 │ │ ├── ProgressListener.java │ │ ├── JSON │ │ │ ├── EntityFactory.java │ │ │ ├── PictureEntity.java │ │ │ ├── CommentEntity.java │ │ │ ├── AlbumEntity.java │ │ │ └── Entity.java │ │ ├── Tasks │ │ │ └── JSONArrayLoaderTask.java │ │ ├── DownloadObject.java │ │ ├── RestCall.java │ │ └── Gallery3Imp.java │ ├── TitleConfig.java │ ├── GalleryFactory.java │ ├── Stream.java │ └── ImageCache.java │ ├── Activities │ ├── Views │ │ ├── GalleryImageViewListener.java │ │ └── GalleryImageView.java │ ├── Helpers │ │ ├── ActionBarHider.java │ │ └── ImageAdapter.java │ ├── Listeners │ │ └── ImageViewOnTouchListener.java │ ├── GalDroidApp.java │ ├── EditGalleryActivity.java │ ├── GalleryListingActivitiy.java │ ├── GalleryActivity.java │ ├── GridViewActivity.java │ └── ImageViewActivity.java │ └── Config │ ├── GalleryConfig.java │ └── GalDroidPreference.java ├── project.properties ├── .classpath ├── proguard.cfg ├── AndroidManifest.xml └── .project /.gitignore: -------------------------------------------------------------------------------- 1 | bin 2 | gen 3 | .settings -------------------------------------------------------------------------------- /res/drawable-hdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raptor2101/GalDroid/master/res/drawable-hdpi/icon.png -------------------------------------------------------------------------------- /res/drawable-ldpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raptor2101/GalDroid/master/res/drawable-ldpi/icon.png -------------------------------------------------------------------------------- /res/drawable-mdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raptor2101/GalDroid/master/res/drawable-mdpi/icon.png -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_action_share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raptor2101/GalDroid/master/res/drawable-hdpi/ic_action_share.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_action_share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raptor2101/GalDroid/master/res/drawable-mdpi/ic_action_share.png -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_options_menu_info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raptor2101/GalDroid/master/res/drawable-hdpi/ic_options_menu_info.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_options_menu_info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raptor2101/GalDroid/master/res/drawable-mdpi/ic_options_menu_info.png -------------------------------------------------------------------------------- /src/de/raptor2101/GalDroid/WebGallery/Interfaces/GalleryDownloadObject.java: -------------------------------------------------------------------------------- 1 | package de.raptor2101.GalDroid.WebGallery.Interfaces; 2 | 3 | public interface GalleryDownloadObject { 4 | public String getUniqueId(); 5 | } 6 | -------------------------------------------------------------------------------- /res/layout/gallery_listing_activity.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/de/raptor2101/GalDroid/WebGallery/Tasks/CacheTaskListener.java: -------------------------------------------------------------------------------- 1 | package de.raptor2101.GalDroid.WebGallery.Tasks; 2 | 3 | public interface CacheTaskListener { 4 | void onCacheOperationStart(int elementCount); 5 | 6 | void onCacheOperationProgress(int elementCount); 7 | 8 | void onCacheOperationDone(); 9 | } 10 | -------------------------------------------------------------------------------- /src/de/raptor2101/GalDroid/WebGallery/DegMinSec.java: -------------------------------------------------------------------------------- 1 | package de.raptor2101.GalDroid.WebGallery; 2 | 3 | public class DegMinSec { 4 | public final float mDeg; 5 | public final float mMin; 6 | public final float mSec; 7 | 8 | public DegMinSec(float deg, float min, float sec) { 9 | mDeg = deg; 10 | mMin = min; 11 | mSec = sec; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /res/layout/grid_view_activity.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/de/raptor2101/GalDroid/WebGallery/Interfaces/GalleryObjectComment.java: -------------------------------------------------------------------------------- 1 | package de.raptor2101.GalDroid.WebGallery.Interfaces; 2 | 3 | import java.util.Date; 4 | 5 | public interface GalleryObjectComment { 6 | public Date getCreateDate(); 7 | 8 | public Date getUpdateDate(); 9 | 10 | public String getMessage(); 11 | 12 | public String getAuthorEmail(); 13 | 14 | public String getAuthorName(); 15 | 16 | public String getAuthorUrl(); 17 | } 18 | -------------------------------------------------------------------------------- /src/de/raptor2101/GalDroid/WebGallery/Tasks/TaskInterface.java: -------------------------------------------------------------------------------- 1 | package de.raptor2101.GalDroid.WebGallery.Tasks; 2 | 3 | public interface TaskInterface { 4 | public enum Status { 5 | PENDING, RUNNING, SLEEPING, FINISHED, STOPPING 6 | } 7 | 8 | public Status getStatus(); 9 | 10 | public void start(); 11 | 12 | public void stop(boolean waitForStopped) throws InterruptedException; 13 | 14 | public void cancel(boolean waitForCancel) throws InterruptedException; 15 | } 16 | -------------------------------------------------------------------------------- /res/menu/gallery_menu.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /res/menu/gallery_context_menu.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/de/raptor2101/GalDroid/Activities/Views/GalleryImageViewListener.java: -------------------------------------------------------------------------------- 1 | package de.raptor2101.GalDroid.Activities.Views; 2 | 3 | import de.raptor2101.GalDroid.WebGallery.Interfaces.GalleryObject; 4 | 5 | public interface GalleryImageViewListener { 6 | public void onLoadingStarted(GalleryObject galleryObject); 7 | 8 | public void onLoadingProgress(GalleryObject galleryObject, int currentValue, int maxValue); 9 | 10 | public void onLoadingCompleted(GalleryObject galleryObject); 11 | 12 | public void onLoadingCancelled(GalleryObject galleryObject); 13 | } 14 | -------------------------------------------------------------------------------- /project.properties: -------------------------------------------------------------------------------- 1 | # This file is automatically generated by Android Tools. 2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED! 3 | # 4 | # This file must be checked in Version Control Systems. 5 | # 6 | # To customize properties used by the Ant build system edit 7 | # "ant.properties", and override values to adapt the script to your 8 | # project structure. 9 | # 10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): 11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt 12 | 13 | # Project target. 14 | target=android-11 15 | -------------------------------------------------------------------------------- /src/de/raptor2101/GalDroid/WebGallery/Tasks/ImageInformationLoaderTaskListener.java: -------------------------------------------------------------------------------- 1 | package de.raptor2101.GalDroid.WebGallery.Tasks; 2 | 3 | import java.util.List; 4 | 5 | import de.raptor2101.GalDroid.WebGallery.ImageInformation; 6 | import de.raptor2101.GalDroid.WebGallery.Interfaces.GalleryObject; 7 | import de.raptor2101.GalDroid.WebGallery.Interfaces.GalleryObjectComment; 8 | 9 | public interface ImageInformationLoaderTaskListener { 10 | public void onImageInformationLoaded(GalleryObject galleryObject, ImageInformation imageInformation); 11 | 12 | public void onImageTagsLoaded(GalleryObject galleryObject, List tags); 13 | 14 | public void onImageCommetsLoaded(GalleryObject galleryObject, List comments); 15 | } 16 | -------------------------------------------------------------------------------- /src/de/raptor2101/GalDroid/WebGallery/ImageInformation.java: -------------------------------------------------------------------------------- 1 | package de.raptor2101.GalDroid.WebGallery; 2 | 3 | import java.util.Date; 4 | 5 | public class ImageInformation { 6 | public enum WhiteBalance { 7 | Auto, Manual 8 | } 9 | 10 | public String mTitle; 11 | public Date mUploadDate; 12 | 13 | public String mExifCreateDate; 14 | public String mExifAperture; 15 | public float mExifExposure; 16 | public int mExifFlash; 17 | public WhiteBalance mExifWhiteBalance; 18 | public String mExifIso; 19 | public String mExifModel; 20 | public String mExifMake; 21 | public double mExifFocalLength; 22 | 23 | public boolean mExifGpsAvailable; 24 | public DegMinSec mExifGpsLat; 25 | public DegMinSec mExifGpsLong; 26 | public float mExifHeight; 27 | } 28 | -------------------------------------------------------------------------------- /src/de/raptor2101/GalDroid/Activities/Helpers/ActionBarHider.java: -------------------------------------------------------------------------------- 1 | package de.raptor2101.GalDroid.Activities.Helpers; 2 | 3 | import android.app.ActionBar; 4 | import android.os.Handler; 5 | 6 | public class ActionBarHider implements Runnable { 7 | 8 | private final ActionBar mActionBar; 9 | private final Handler mHandler; 10 | 11 | public ActionBarHider(ActionBar actionBar) { 12 | mActionBar = actionBar; 13 | mHandler = new Handler(); 14 | } 15 | 16 | public boolean isShowing() { 17 | return mActionBar.isShowing(); 18 | } 19 | 20 | public void show() { 21 | mActionBar.show(); 22 | mHandler.postDelayed(this, 10000); 23 | } 24 | 25 | public void hide() { 26 | mActionBar.hide(); 27 | mHandler.removeCallbacks(this); 28 | } 29 | 30 | public void run() { 31 | mActionBar.hide(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /res/menu/grid_view_context_menu.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 19 | 20 | -------------------------------------------------------------------------------- /res/menu/image_view_options_menu.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 19 | 20 | -------------------------------------------------------------------------------- /src/de/raptor2101/GalDroid/WebGallery/Gallery3/ProgressListener.java: -------------------------------------------------------------------------------- 1 | package de.raptor2101.GalDroid.WebGallery.Gallery3; 2 | 3 | import java.lang.ref.WeakReference; 4 | 5 | import de.raptor2101.GalDroid.WebGallery.Interfaces.GalleryProgressListener; 6 | 7 | public class ProgressListener { 8 | private final int mMaxCount; 9 | private int mObjectCount; 10 | private WeakReference mListener; 11 | 12 | public ProgressListener(GalleryProgressListener listener, int maxCount) { 13 | mMaxCount = maxCount; 14 | mObjectCount = 0; 15 | mListener = new WeakReference(listener); 16 | } 17 | 18 | public void progress() { 19 | mObjectCount++; 20 | GalleryProgressListener listener = mListener.get(); 21 | if (listener != null) { 22 | listener.handleProgress(mObjectCount, mMaxCount); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/de/raptor2101/GalDroid/WebGallery/Gallery3/JSON/EntityFactory.java: -------------------------------------------------------------------------------- 1 | package de.raptor2101.GalDroid.WebGallery.Gallery3.JSON; 2 | 3 | import org.json.JSONException; 4 | import org.json.JSONObject; 5 | 6 | import de.raptor2101.GalDroid.WebGallery.Gallery3.Gallery3Imp; 7 | 8 | public class EntityFactory { 9 | public static Entity parseJSON(JSONObject jsonObject, Gallery3Imp gallery3) throws JSONException { 10 | String type = jsonObject.getJSONObject("entity").getString("type"); 11 | if (type.equals("album")) { 12 | return new AlbumEntity(jsonObject, gallery3); 13 | } else { 14 | return new PictureEntity(jsonObject, gallery3); 15 | } 16 | } 17 | 18 | public static String parseTag(JSONObject jsonObject) throws JSONException { 19 | return jsonObject.getJSONObject("entity").getString("name"); 20 | } 21 | 22 | public static CommentEntity parseComment(JSONObject jsonObject) throws JSONException { 23 | return new CommentEntity(jsonObject); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/de/raptor2101/GalDroid/WebGallery/TitleConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * GalDroid - a webgallery frontend for android 3 | * Copyright (C) 2011 Raptor 2101 [raptor2101@gmx.de] 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package de.raptor2101.GalDroid.WebGallery; 20 | 21 | public class TitleConfig { 22 | public boolean ShowTitle; 23 | } 24 | -------------------------------------------------------------------------------- /src/de/raptor2101/GalDroid/WebGallery/Interfaces/GalleryProgressListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * GalDroid - a webgallery frontend for android 3 | * Copyright (C) 2011 Raptor 2101 [raptor2101@gmx.de] 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package de.raptor2101.GalDroid.WebGallery.Interfaces; 20 | 21 | public interface GalleryProgressListener { 22 | public void handleProgress(int curValue, int maxValue); 23 | } 24 | -------------------------------------------------------------------------------- /src/de/raptor2101/GalDroid/WebGallery/Gallery3/Tasks/JSONArrayLoaderTask.java: -------------------------------------------------------------------------------- 1 | package de.raptor2101.GalDroid.WebGallery.Gallery3.Tasks; 2 | 3 | import java.io.IOException; 4 | 5 | import org.apache.http.client.ClientProtocolException; 6 | import org.json.JSONArray; 7 | import org.json.JSONException; 8 | 9 | import de.raptor2101.GalDroid.WebGallery.Gallery3.RestCall; 10 | import android.os.AsyncTask; 11 | 12 | public class JSONArrayLoaderTask extends AsyncTask { 13 | 14 | @Override 15 | protected JSONArray doInBackground(RestCall... params) { 16 | JSONArray jsonArray = null; 17 | try { 18 | RestCall restCall = params[0]; 19 | jsonArray = restCall.loadJSONArray(); 20 | 21 | } catch (ClientProtocolException e) { 22 | // TODO Auto-generated catch block 23 | e.printStackTrace(); 24 | } catch (IOException e) { 25 | // TODO Auto-generated catch block 26 | e.printStackTrace(); 27 | } catch (JSONException e) { 28 | // TODO Auto-generated catch block 29 | e.printStackTrace(); 30 | } 31 | return jsonArray; 32 | } 33 | } -------------------------------------------------------------------------------- /src/de/raptor2101/GalDroid/WebGallery/Tasks/Progress.java: -------------------------------------------------------------------------------- 1 | /* 2 | * GalDroid - a webgallery frontend for android 3 | * Copyright (C) 2011 Raptor 2101 [raptor2101@gmx.de] 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package de.raptor2101.GalDroid.WebGallery.Tasks; 20 | 21 | public class Progress { 22 | 23 | public final int curValue; 24 | public final int maxValue; 25 | 26 | public Progress(int curValue, int maxValue) { 27 | this.curValue = curValue; 28 | this.maxValue = maxValue; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/de/raptor2101/GalDroid/WebGallery/Tasks/GalleryLoaderTaskListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * GalDroid - a webgallery frontend for android 3 | * Copyright (C) 2011 Raptor 2101 [raptor2101@gmx.de] 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package de.raptor2101.GalDroid.WebGallery.Tasks; 20 | 21 | import java.util.List; 22 | 23 | import de.raptor2101.GalDroid.WebGallery.Interfaces.GalleryObject; 24 | 25 | public interface GalleryLoaderTaskListener { 26 | void onDownloadStarted(); 27 | 28 | void onDownloadProgress(int elementCount, int maxCount); 29 | 30 | void onDownloadCompleted(List galleryObjects); 31 | } 32 | -------------------------------------------------------------------------------- /src/de/raptor2101/GalDroid/WebGallery/Tasks/ImageLoaderTaskListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * GalDroid - a webgallery frontend for android 3 | * Copyright (C) 2011 Raptor 2101 [raptor2101@gmx.de] 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package de.raptor2101.GalDroid.WebGallery.Tasks; 20 | 21 | import android.graphics.Bitmap; 22 | 23 | public interface ImageLoaderTaskListener { 24 | void onLoadingStarted(String uniqueId); 25 | 26 | void onLoadingProgress(String uniqueId, int currentValue, int maxValue); 27 | 28 | void onLoadingCompleted(String uniqueId, Bitmap bitmap); 29 | 30 | void onLoadingCancelled(String uniqueId); 31 | } -------------------------------------------------------------------------------- /res/layout/image_view_activity.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 13 | 14 | 19 | 20 | 25 | 26 | 27 | 34 | 35 | -------------------------------------------------------------------------------- /src/de/raptor2101/GalDroid/WebGallery/Interfaces/GalleryObject.java: -------------------------------------------------------------------------------- 1 | /* 2 | * GalDroid - a webgallery frontend for android 3 | * Copyright (C) 2011 Raptor 2101 [raptor2101@gmx.de] 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package de.raptor2101.GalDroid.WebGallery.Interfaces; 20 | 21 | import java.io.Serializable; 22 | import java.util.Date; 23 | 24 | public interface GalleryObject extends Serializable { 25 | public String getTitle(); 26 | 27 | public Date getDateUploaded(); 28 | 29 | public boolean hasChildren(); 30 | 31 | public String getObjectId(); 32 | 33 | public GalleryDownloadObject getImage(); 34 | 35 | public GalleryDownloadObject getThumbnail(); 36 | } 37 | -------------------------------------------------------------------------------- /src/de/raptor2101/GalDroid/WebGallery/GalleryFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * GalDroid - a webgallery frontend for android 3 | * Copyright (C) 2011 Raptor 2101 [raptor2101@gmx.de] 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package de.raptor2101.GalDroid.WebGallery; 20 | 21 | import org.apache.http.client.HttpClient; 22 | 23 | import de.raptor2101.GalDroid.WebGallery.Gallery3.Gallery3Imp; 24 | import de.raptor2101.GalDroid.WebGallery.Interfaces.WebGallery; 25 | 26 | public class GalleryFactory { 27 | public static WebGallery createFromName(String name, String serverUrl, HttpClient client) { 28 | Gallery3Imp gallery = new Gallery3Imp(serverUrl); 29 | gallery.setHttpClient(client); 30 | return gallery; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/de/raptor2101/GalDroid/Config/GalleryConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * GalDroid - a webgallery frontend for android 3 | * Copyright (C) 2011 Raptor 2101 [raptor2101@gmx.de] 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package de.raptor2101.GalDroid.Config; 20 | 21 | public class GalleryConfig { 22 | 23 | public final int Id; 24 | public final String Name; 25 | public final String TypeName; 26 | public final String RootLink; 27 | public final String SecurityToken; 28 | 29 | public GalleryConfig(int id, String name, String typeName, String rootLink, String securityToken) { 30 | Id = id; 31 | Name = name; 32 | TypeName = typeName; 33 | RootLink = rootLink; 34 | SecurityToken = securityToken; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /proguard.cfg: -------------------------------------------------------------------------------- 1 | -optimizationpasses 5 2 | -dontusemixedcaseclassnames 3 | -dontskipnonpubliclibraryclasses 4 | -dontpreverify 5 | -verbose 6 | -optimizations !code/simplification/arithmetic,!field/*,!class/merging/* 7 | 8 | -keep public class * extends android.app.Activity 9 | -keep public class * extends android.app.Application 10 | -keep public class * extends android.app.Service 11 | -keep public class * extends android.content.BroadcastReceiver 12 | -keep public class * extends android.content.ContentProvider 13 | -keep public class * extends android.app.backup.BackupAgentHelper 14 | -keep public class * extends android.preference.Preference 15 | -keep public class com.android.vending.licensing.ILicensingService 16 | 17 | -keepclasseswithmembernames class * { 18 | native ; 19 | } 20 | 21 | -keepclasseswithmembers class * { 22 | public (android.content.Context, android.util.AttributeSet); 23 | } 24 | 25 | -keepclasseswithmembers class * { 26 | public (android.content.Context, android.util.AttributeSet, int); 27 | } 28 | 29 | -keepclassmembers class * extends android.app.Activity { 30 | public void *(android.view.View); 31 | } 32 | 33 | -keepclassmembers enum * { 34 | public static **[] values(); 35 | public static ** valueOf(java.lang.String); 36 | } 37 | 38 | -keep class * implements android.os.Parcelable { 39 | public static final android.os.Parcelable$Creator *; 40 | } 41 | -------------------------------------------------------------------------------- /AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /res/layout/gallery_image_view.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 14 | 15 | 21 | 22 | 28 | 37 | 38 | -------------------------------------------------------------------------------- /src/de/raptor2101/GalDroid/WebGallery/Stream.java: -------------------------------------------------------------------------------- 1 | package de.raptor2101.GalDroid.WebGallery; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | 6 | public class Stream extends InputStream { 7 | private final InputStream mStream; 8 | private final long mLength; 9 | 10 | public Stream(InputStream inputSream, long length) { 11 | mStream = inputSream; 12 | mLength = length; 13 | } 14 | 15 | @Override 16 | public int available() throws IOException { 17 | return mStream.available(); 18 | } 19 | 20 | @Override 21 | public void close() throws IOException { 22 | mStream.close(); 23 | } 24 | 25 | @Override 26 | public void mark(int readlimit) { 27 | mStream.mark(readlimit); 28 | } 29 | 30 | @Override 31 | public boolean markSupported() { 32 | return mStream.markSupported(); 33 | } 34 | 35 | @Override 36 | public int read() throws IOException { 37 | return mStream.read(); 38 | } 39 | 40 | @Override 41 | public int read(byte[] buffer, int offset, int length) throws IOException { 42 | return mStream.read(buffer, offset, length); 43 | } 44 | 45 | @Override 46 | public int read(byte[] buffer) throws IOException { 47 | return mStream.read(buffer); 48 | } 49 | 50 | @Override 51 | public synchronized void reset() throws IOException { 52 | mStream.reset(); 53 | } 54 | 55 | @Override 56 | public long skip(long byteCount) throws IOException { 57 | return mStream.skip(byteCount); 58 | } 59 | 60 | public long getContentLength() { 61 | return mLength; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/de/raptor2101/GalDroid/WebGallery/Tasks/SyncronizeCacheTask.java: -------------------------------------------------------------------------------- 1 | package de.raptor2101.GalDroid.WebGallery.Tasks; 2 | 3 | import java.io.File; 4 | import java.lang.ref.WeakReference; 5 | 6 | import de.raptor2101.GalDroid.Config.GalDroidPreference; 7 | import de.raptor2101.GalDroid.WebGallery.ImageCache; 8 | import android.os.AsyncTask; 9 | 10 | public class SyncronizeCacheTask extends AsyncTask { 11 | private WeakReference mListener; 12 | private File[] mFiles; 13 | 14 | public SyncronizeCacheTask(ImageCache cache, CacheTaskListener listener) { 15 | mListener = new WeakReference(listener); 16 | mFiles = cache.ListCachedFiles(); 17 | } 18 | 19 | @Override 20 | protected void onPreExecute() { 21 | CacheTaskListener listener = mListener.get(); 22 | if (listener != null) { 23 | listener.onCacheOperationStart(mFiles.length); 24 | } 25 | } 26 | 27 | @Override 28 | protected Void doInBackground(Void... params) { 29 | GalDroidPreference preference = GalDroidPreference.GetAsyncAccess(); 30 | try { 31 | preference.clearCacheTable(); 32 | int length = mFiles.length; 33 | for (int i = 0; i < length; i++) { 34 | preference.insertCacheObject(mFiles[i]); 35 | publishProgress(i); 36 | } 37 | } finally { 38 | preference.close(); 39 | } 40 | return null; 41 | } 42 | 43 | @Override 44 | protected void onProgressUpdate(Integer... values) { 45 | CacheTaskListener listener = mListener.get(); 46 | if (listener != null) { 47 | listener.onCacheOperationProgress(values[0]); 48 | } 49 | } 50 | 51 | @Override 52 | protected void onPostExecute(Void result) { 53 | CacheTaskListener listener = mListener.get(); 54 | if (listener != null) { 55 | listener.onCacheOperationDone(); 56 | } 57 | } 58 | } -------------------------------------------------------------------------------- /res/layout/comment_entry.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 12 | 13 | 19 | 20 | 25 | 26 | 31 | 32 | 36 | 37 | 38 | 42 | 43 | 44 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | GalDroid 4 | 5 | 6 | 7 | 8 | 9 | com.android.ide.eclipse.adt.ResourceManagerBuilder 10 | 11 | 12 | 13 | 14 | com.android.ide.eclipse.adt.PreCompilerBuilder 15 | 16 | 17 | 18 | 19 | org.eclipse.jdt.core.javabuilder 20 | 21 | 22 | 23 | 24 | com.android.ide.eclipse.adt.ApkBuilder 25 | 26 | 27 | 28 | 29 | 30 | com.android.ide.eclipse.adt.AndroidNature 31 | org.eclipse.jdt.core.javanature 32 | 33 | 34 | 35 | libs/commons-codec-1.4.jar 36 | 1 37 | /media/Workspace/eclipse_workspace/Libraries/httpcomponents-client-4.1.1/lib/commons-codec-1.4.jar 38 | 39 | 40 | libs/commons-logging-1.1.1.jar 41 | 1 42 | /media/Workspace/eclipse_workspace/Libraries/httpcomponents-client-4.1.1/lib/commons-logging-1.1.1.jar 43 | 44 | 45 | libs/httpclient-4.1.1.jar 46 | 1 47 | /media/Workspace/eclipse_workspace/Libraries/httpcomponents-client-4.1.1/lib/httpclient-4.1.1.jar 48 | 49 | 50 | libs/httpclient-cache-4.1.1.jar 51 | 1 52 | /media/Workspace/eclipse_workspace/Libraries/httpcomponents-client-4.1.1/lib/httpclient-cache-4.1.1.jar 53 | 54 | 55 | libs/httpcore-4.1.jar 56 | 1 57 | /media/Workspace/eclipse_workspace/Libraries/httpcomponents-client-4.1.1/lib/httpcore-4.1.jar 58 | 59 | 60 | libs/httpmime-4.1.1.jar 61 | 1 62 | /media/Workspace/eclipse_workspace/Libraries/httpcomponents-client-4.1.1/lib/httpmime-4.1.1.jar 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /src/de/raptor2101/GalDroid/WebGallery/Gallery3/JSON/PictureEntity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * GalDroid - a webgallery frontend for android 3 | * Copyright (C) 2011 Raptor 2101 [raptor2101@gmx.de] 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package de.raptor2101.GalDroid.WebGallery.Gallery3.JSON; 20 | 21 | import org.json.JSONException; 22 | import org.json.JSONObject; 23 | 24 | import de.raptor2101.GalDroid.WebGallery.Gallery3.Gallery3Imp; 25 | 26 | import android.util.FloatMath; 27 | 28 | public class PictureEntity extends Entity { 29 | private static final long serialVersionUID = -7313965114397469045L; 30 | 31 | public PictureEntity(JSONObject jsonObject, Gallery3Imp gallery3) throws JSONException { 32 | super(jsonObject, gallery3); 33 | jsonObject = jsonObject.getJSONObject("entity"); 34 | int resizeHeight = jsonObject.getInt("resize_height"); 35 | int resizeWidth = jsonObject.getInt("resize_width"); 36 | 37 | float imageDiag = FloatMath.sqrt(resizeHeight * resizeHeight + resizeWidth * resizeWidth); 38 | if (imageDiag > gallery3.getMaxImageDiag()) { 39 | mLink_Full = String.format(gallery3.LinkRest_LoadPicture, getId(), "full"); 40 | mFileSize_Full = jsonObject.getInt("file_size"); 41 | } else { 42 | mLink_Full = String.format(gallery3.LinkRest_LoadPicture, getId(), "resize"); 43 | mFileSize_Full = jsonObject.getInt("resize_size"); 44 | } 45 | 46 | mLink_Thumb = String.format(gallery3.LinkRest_LoadPicture, getId(), "thumb"); 47 | mFileSize_Thumb = jsonObject.getInt("thumb_size"); 48 | } 49 | 50 | public boolean hasChildren() { 51 | // A Image never have childs 52 | return false; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/de/raptor2101/GalDroid/WebGallery/Gallery3/DownloadObject.java: -------------------------------------------------------------------------------- 1 | /* 2 | * GalDroid - a webgallery frontend for android 3 | * Copyright (C) 2011 Raptor 2101 [raptor2101@gmx.de] 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package de.raptor2101.GalDroid.WebGallery.Gallery3; 20 | 21 | import de.raptor2101.GalDroid.WebGallery.Interfaces.GalleryDownloadObject; 22 | 23 | public class DownloadObject implements GalleryDownloadObject { 24 | 25 | @Override 26 | public int hashCode() { 27 | final int prime = 31; 28 | int result = 1; 29 | result = prime * result + ((mSourceLink == null) ? 0 : mSourceLink.hashCode()); 30 | return mSourceLink.hashCode(); 31 | } 32 | 33 | @Override 34 | public boolean equals(Object obj) { 35 | if (this == obj) 36 | return true; 37 | if (obj == null) 38 | return false; 39 | if (getClass() != obj.getClass()) 40 | return false; 41 | DownloadObject other = (DownloadObject) obj; 42 | if (mSourceLink == null) { 43 | if (other.mSourceLink != null) 44 | return false; 45 | } else if (!mSourceLink.equals(other.mSourceLink)) 46 | return false; 47 | return true; 48 | } 49 | 50 | private final String mSourceLink; 51 | private final String mRootLink; 52 | private final int mFileSize; 53 | 54 | public DownloadObject(String rootLink, String sourceLink, int fileSize) { 55 | mSourceLink = sourceLink; 56 | mRootLink = rootLink; 57 | mFileSize = fileSize; 58 | } 59 | 60 | public String getRootLink() { 61 | return mRootLink; 62 | } 63 | 64 | public String getUniqueId() { 65 | return mSourceLink; 66 | } 67 | 68 | public int getFileSize() { 69 | return mFileSize; 70 | } 71 | 72 | @Override 73 | public String toString() { 74 | return mSourceLink; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/de/raptor2101/GalDroid/WebGallery/Tasks/CleanUpCacheTask.java: -------------------------------------------------------------------------------- 1 | package de.raptor2101.GalDroid.WebGallery.Tasks; 2 | 3 | import java.io.File; 4 | import java.lang.ref.WeakReference; 5 | import java.util.List; 6 | 7 | import de.raptor2101.GalDroid.Config.GalDroidPreference; 8 | import de.raptor2101.GalDroid.WebGallery.ImageCache; 9 | import android.os.AsyncTask; 10 | 11 | public class CleanUpCacheTask extends AsyncTask { 12 | private WeakReference mListener; 13 | private List mCachedObjects; 14 | private File mCacheDir; 15 | private long mCleanUpSize; 16 | 17 | public CleanUpCacheTask(ImageCache cache, CacheTaskListener listener) { 18 | mListener = new WeakReference(listener); 19 | mCachedObjects = GalDroidPreference.getCacheOjectsOrderedByAccessTime(); 20 | 21 | mCacheDir = cache.getCacheDir(); 22 | long maxCacheSize = cache.getMaxCacheSize(); 23 | long cleanUpToSize = maxCacheSize - (maxCacheSize / 3); 24 | long currentCacheSize = GalDroidPreference.getCacheSpaceNeeded(); 25 | mCleanUpSize = currentCacheSize - cleanUpToSize; 26 | } 27 | 28 | @Override 29 | protected void onPreExecute() { 30 | CacheTaskListener listener = mListener.get(); 31 | if (listener != null) { 32 | listener.onCacheOperationStart(100); 33 | } 34 | } 35 | 36 | @Override 37 | protected Void doInBackground(Void... params) { 38 | long currentCleanUp = 0; 39 | if (mCleanUpSize > 0) { 40 | for (int i = 0; currentCleanUp < mCleanUpSize && i < mCachedObjects.size(); i++) { 41 | String hash = mCachedObjects.get(i); 42 | File cacheFile = new File(mCacheDir, hash); 43 | if (cacheFile.exists()) { 44 | currentCleanUp += cacheFile.length(); 45 | cacheFile.delete(); 46 | } 47 | GalDroidPreference.deleteCacheObject(hash); 48 | 49 | publishProgress(currentCleanUp); 50 | } 51 | } 52 | return null; 53 | } 54 | 55 | @Override 56 | protected void onProgressUpdate(Long... values) { 57 | CacheTaskListener listener = mListener.get(); 58 | if (listener != null) { 59 | long calculatedValue = values[0] * 100 / mCleanUpSize; 60 | listener.onCacheOperationProgress((int) calculatedValue); 61 | } 62 | } 63 | 64 | @Override 65 | protected void onPostExecute(Void result) { 66 | CacheTaskListener listener = mListener.get(); 67 | if (listener != null) { 68 | listener.onCacheOperationDone(); 69 | } 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /src/de/raptor2101/GalDroid/WebGallery/Gallery3/JSON/CommentEntity.java: -------------------------------------------------------------------------------- 1 | package de.raptor2101.GalDroid.WebGallery.Gallery3.JSON; 2 | 3 | import java.util.Date; 4 | 5 | import org.json.JSONException; 6 | import org.json.JSONObject; 7 | 8 | import de.raptor2101.GalDroid.WebGallery.Interfaces.GalleryObjectComment; 9 | 10 | public class CommentEntity implements GalleryObjectComment { 11 | public enum CommentState { 12 | Published; 13 | } 14 | 15 | private final String mId; 16 | 17 | private final Date mCreateDate; 18 | private final Date mUpdateDate; 19 | private final String mMessage; 20 | private final CommentState mCommentState; 21 | 22 | private final String mAuthorId; 23 | private String mAuthorEmail = null; 24 | private String mAuthorName = null; 25 | private String mAuthorUrl = null; 26 | 27 | public CommentEntity(JSONObject jsonObject) throws JSONException { 28 | jsonObject = jsonObject.getJSONObject("entity"); 29 | mId = jsonObject.getString("id"); 30 | mMessage = jsonObject.getString("text"); 31 | 32 | long msElapsed = jsonObject.getLong("created") * 1000; 33 | mCreateDate = new Date(msElapsed); 34 | 35 | msElapsed = jsonObject.getLong("updated") * 1000; 36 | mUpdateDate = new Date(msElapsed); 37 | 38 | String state = jsonObject.getString("state"); 39 | if (state.equals("published")) { 40 | mCommentState = CommentState.Published; 41 | } else { 42 | // TODO weitere states auslesen 43 | mCommentState = CommentState.Published; 44 | } 45 | 46 | mAuthorId = jsonObject.getString("author_id"); 47 | // TODO prüfen ob das wirklich null wird 48 | if (mAuthorId == null) { 49 | mAuthorEmail = jsonObject.getString("guest_email"); 50 | mAuthorName = jsonObject.getString("guest_name"); 51 | mAuthorUrl = jsonObject.getString("guest_url"); 52 | } 53 | } 54 | 55 | public String getId() { 56 | return mId; 57 | } 58 | 59 | public Date getCreateDate() { 60 | return mCreateDate; 61 | } 62 | 63 | public Date getUpdateDate() { 64 | return mUpdateDate; 65 | } 66 | 67 | public String getMessage() { 68 | return mMessage; 69 | } 70 | 71 | public CommentState getState() { 72 | return mCommentState; 73 | } 74 | 75 | public String getAuthorId() { 76 | return mAuthorId; 77 | } 78 | 79 | public String getAuthorEmail() { 80 | return mAuthorEmail; 81 | } 82 | 83 | public String getAuthorName() { 84 | return mAuthorName; 85 | } 86 | 87 | public String getAuthorUrl() { 88 | return mAuthorUrl; 89 | } 90 | 91 | public boolean isAuthorInformationLoaded() { 92 | return mAuthorName != null; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/de/raptor2101/GalDroid/WebGallery/Tasks/GalleryVerifyTask.java: -------------------------------------------------------------------------------- 1 | /* 2 | * GalDroid - a webgallery frontend for android 3 | * Copyright (C) 2011 Raptor 2101 [raptor2101@gmx.de] 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package de.raptor2101.GalDroid.WebGallery.Tasks; 20 | 21 | import de.raptor2101.GalDroid.Activities.EditGalleryActivity; 22 | import de.raptor2101.GalDroid.Config.GalDroidPreference; 23 | import de.raptor2101.GalDroid.Config.GalleryConfig; 24 | import de.raptor2101.GalDroid.WebGallery.GalleryFactory; 25 | import de.raptor2101.GalDroid.WebGallery.Interfaces.WebGallery; 26 | import android.net.http.AndroidHttpClient; 27 | import android.os.AsyncTask; 28 | 29 | public class GalleryVerifyTask extends AsyncTask { 30 | 31 | private WebGallery mWebGallery; 32 | private GalleryConfig mGalleryConfig; 33 | private String mUsername; 34 | private String mPassword; 35 | private EditGalleryActivity mOwner; 36 | 37 | public GalleryVerifyTask(GalleryConfig galleryConfig, String username, String password, EditGalleryActivity owner) { 38 | mGalleryConfig = galleryConfig; 39 | mUsername = username; 40 | mPassword = password; 41 | mOwner = owner; 42 | } 43 | 44 | @Override 45 | protected String doInBackground(Void... params) { 46 | AndroidHttpClient client = AndroidHttpClient.newInstance("GalDroid"); 47 | try { 48 | mWebGallery = GalleryFactory.createFromName(mGalleryConfig.TypeName, mGalleryConfig.RootLink, client); 49 | 50 | return mWebGallery.getSecurityToken(mUsername, mPassword); 51 | } catch (SecurityException e) { 52 | return null; 53 | } finally { 54 | client.close(); 55 | } 56 | } 57 | 58 | @Override 59 | protected void onPostExecute(String result) { 60 | if (result != null) { 61 | GalDroidPreference.StoreGallery(mGalleryConfig.Id, mGalleryConfig.Name, mGalleryConfig.TypeName, mGalleryConfig.RootLink, result); 62 | mOwner.onGalleryVerified(true); 63 | } else { 64 | mOwner.onGalleryVerified(false); 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/de/raptor2101/GalDroid/WebGallery/Interfaces/WebGallery.java: -------------------------------------------------------------------------------- 1 | /* 2 | * GalDroid - a webgallery frontend for android 3 | * Copyright (C) 2011 Raptor 2101 [raptor2101@gmx.de] 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package de.raptor2101.GalDroid.WebGallery.Interfaces; 20 | 21 | import java.io.IOException; 22 | import java.util.List; 23 | 24 | import org.apache.http.client.ClientProtocolException; 25 | import org.apache.http.client.HttpClient; 26 | import org.json.JSONException; 27 | 28 | import de.raptor2101.GalDroid.WebGallery.Stream; 29 | 30 | public interface WebGallery { 31 | public enum ImageSize { 32 | Thumbnail, Full 33 | } 34 | 35 | public GalleryObject getDisplayObject(String path) throws ClientProtocolException, IOException, JSONException; 36 | 37 | public List getDisplayObjects(); 38 | 39 | public List getDisplayObjects(GalleryProgressListener progressListener); 40 | 41 | public List getDisplayObjects(String path); 42 | 43 | public List getDisplayObjects(String path, GalleryProgressListener progressListener); 44 | 45 | public List getDisplayObjects(GalleryObject galleryObject); 46 | 47 | public List getDisplayObjects(GalleryObject galleryObject, GalleryProgressListener progressListener); 48 | 49 | public List getDisplayObjectTags(GalleryObject galleryObject, GalleryProgressListener progressListener) throws IOException; 50 | 51 | public List getDisplayObjectComments(GalleryObject galleryObject, GalleryProgressListener progressListener) throws IOException, ClientProtocolException, JSONException; 52 | 53 | public void setPreferedDimensions(int height, int width); 54 | 55 | public String getSecurityToken(String user, String password) throws SecurityException; 56 | 57 | public Stream getFileStream(GalleryDownloadObject downloadObject) throws IOException, ClientProtocolException; 58 | 59 | public void setSecurityToken(String token); 60 | 61 | public void setHttpClient(HttpClient httpClient); 62 | } 63 | -------------------------------------------------------------------------------- /res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | GalDroid 4 | Add Gallery 5 | Edit Gallery 6 | Delete Gallery 7 | Synchronize Cache 8 | Cleanup Cache 9 | Create 10 | Edit 11 | Verify Usercredentials 12 | Load Gallery 13 | Load Image 14 | Gallery Type 15 | Server 16 | User 17 | Password 18 | 19 | Gallery 3 20 | 21 | Choose a gallery type 22 | Gallery nameTitle 23 | Tags 24 | Created 25 | Released 26 | Comments 27 | Additional Info 28 | Share … 29 | Gallery Informations 30 | EXIF Informationen 31 | Createdate 32 | Aperture 33 | Exposure 34 | Flash 35 | Focallength 36 | ISO 37 | Make 38 | Model 39 | Whitebalance 40 | automatic 41 | manual 42 | Geo Informations 43 | Latitude 44 | Longitude 45 | Height 46 | wrote at 47 | 48 | -------------------------------------------------------------------------------- /src/de/raptor2101/GalDroid/WebGallery/Gallery3/JSON/AlbumEntity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * GalDroid - a webgallery frontend for android 3 | * Copyright (C) 2011 Raptor 2101 [raptor2101@gmx.de] 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package de.raptor2101.GalDroid.WebGallery.Gallery3.JSON; 20 | 21 | import java.util.ArrayList; 22 | import java.util.List; 23 | 24 | import org.json.JSONArray; 25 | import org.json.JSONException; 26 | import org.json.JSONObject; 27 | 28 | import de.raptor2101.GalDroid.WebGallery.Gallery3.Gallery3Imp; 29 | 30 | public class AlbumEntity extends Entity { 31 | private static final long serialVersionUID = 1118284867802421954L; 32 | 33 | private final List mMembers; 34 | 35 | public AlbumEntity(JSONObject jsonObject, Gallery3Imp gallery3) throws JSONException { 36 | super(jsonObject, gallery3); 37 | JSONArray memberArray = jsonObject.getJSONArray("members"); 38 | 39 | try { 40 | jsonObject = jsonObject.getJSONObject("entity"); 41 | String albumCover_RestLink = jsonObject.getString("album_cover"); 42 | albumCover_RestLink = albumCover_RestLink.substring(gallery3.LinkRest_LoadItem.length() - 2); 43 | 44 | int coverId = Integer.parseInt(albumCover_RestLink); 45 | 46 | mLink_Full = String.format(gallery3.LinkRest_LoadPicture, coverId, "full"); 47 | mLink_Thumb = String.format(gallery3.LinkRest_LoadPicture, getId(), "thumb"); 48 | mFileSize_Full = 100000; // For some wired reason no FileSize is 49 | // reported by Gallery3 and a second 50 | // request cost to much io... 51 | mFileSize_Thumb = jsonObject.getInt("thumb_size"); 52 | } catch (JSONException e) { 53 | mLink_Full = ""; 54 | mLink_Thumb = ""; 55 | mFileSize_Full = 0; 56 | mFileSize_Thumb = 0; 57 | } 58 | 59 | mMembers = new ArrayList(memberArray.length()); 60 | 61 | for (int i = 0; i < memberArray.length(); i++) { 62 | mMembers.add(memberArray.getString(i)); 63 | } 64 | } 65 | 66 | public List getMembers() { 67 | return mMembers; 68 | } 69 | 70 | public boolean hasChildren() { 71 | return mMembers.size() > 0; 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /res/values-de/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | GalDroid 4 | Galerie hinzufügen 5 | Galerie Bearbeiten 6 | Galerie Löschen 7 | Cache synchronisieren 8 | Cache aufräumen 9 | hinzufügen 10 | bearbeiten 11 | Überprüfe Sicherheitsangaben 12 | Lade Galerie 13 | Lade Bild 14 | Galerie Typ 15 | Server 16 | Benutzer 17 | Passwort 18 | 19 | Gallery 3 20 | 21 | Wähle einen Galerie Typen 22 | Galerie - Name 23 | Titel 24 | Schlagwörter 25 | Erzeugt 26 | Veröffentlicht 27 | Kommentare 28 | Bildinformationen 29 | Teilen … 30 | Gallery Informationen 31 | EXIF Informationen 32 | Aufnahmezeit 33 | Blende 34 | Belichtung 35 | Blitz 36 | Brennweite 37 | ISO 38 | Make 39 | Model 40 | Weißabgleich 41 | Automatisch 42 | Manuell 43 | Geo Informationen 44 | Breitengrad 45 | Längengrad 46 | Höhe 47 | schrieb 48 | 49 | -------------------------------------------------------------------------------- /res/layout/create_gallery_activity.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 12 | 16 | 17 | 22 | 27 | 32 | 36 | 37 | 42 | 47 | 52 | 57 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /src/de/raptor2101/GalDroid/WebGallery/Tasks/GalleryLoaderTask.java: -------------------------------------------------------------------------------- 1 | /* 2 | * GalDroid - a webgallery frontend for android 3 | * Copyright (C) 2011 Raptor 2101 [raptor2101@gmx.de] 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package de.raptor2101.GalDroid.WebGallery.Tasks; 20 | 21 | import java.lang.ref.WeakReference; 22 | import java.util.ArrayList; 23 | import java.util.List; 24 | 25 | import android.os.AsyncTask; 26 | import android.util.Log; 27 | import de.raptor2101.GalDroid.WebGallery.Interfaces.GalleryObject; 28 | import de.raptor2101.GalDroid.WebGallery.Interfaces.GalleryProgressListener; 29 | import de.raptor2101.GalDroid.WebGallery.Interfaces.WebGallery; 30 | 31 | public class GalleryLoaderTask extends AsyncTask> implements GalleryProgressListener { 32 | 33 | private WeakReference mListener; 34 | private WebGallery mWebGallery; 35 | 36 | public GalleryLoaderTask(WebGallery webGallery, GalleryLoaderTaskListener listener) { 37 | mListener = new WeakReference(listener); 38 | mWebGallery = webGallery; 39 | } 40 | 41 | @Override 42 | protected List doInBackground(GalleryObject... params) { 43 | List objects; 44 | 45 | if (mWebGallery != null) { 46 | if (params.length == 0 || params[0] == null) { 47 | Thread.currentThread().setName(String.format("GalleryLoaderTask")); 48 | objects = mWebGallery.getDisplayObjects(this); 49 | } else { 50 | Thread.currentThread().setName(String.format("GalleryLoaderTask for %s", params[0])); 51 | objects = mWebGallery.getDisplayObjects(params[0], this); 52 | } 53 | } else { 54 | objects = new ArrayList(0); 55 | } 56 | return objects; 57 | } 58 | 59 | @Override 60 | protected void onPreExecute() { 61 | GalleryLoaderTaskListener listener = mListener.get(); 62 | if (listener != null) { 63 | listener.onDownloadStarted(); 64 | } 65 | }; 66 | 67 | @Override 68 | protected void onProgressUpdate(Progress... values) { 69 | GalleryLoaderTaskListener listener = mListener.get(); 70 | if (values.length > 0 && listener != null) { 71 | listener.onDownloadProgress(values[0].curValue, values[0].maxValue); 72 | } 73 | } 74 | 75 | @Override 76 | protected void onPostExecute(List galleryObjects) { 77 | GalleryLoaderTaskListener listener = mListener.get(); 78 | Log.d("GalleryLoaderTask", String.format("onPostExecute isCanceled: %s isListenerAvaible: %s", isCancelled(), listener != null)); 79 | if (!isCancelled() && listener != null) { 80 | listener.onDownloadCompleted(galleryObjects); 81 | } 82 | } 83 | 84 | public void handleProgress(int curValue, int maxValue) { 85 | publishProgress(new Progress(curValue, maxValue)); 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /src/de/raptor2101/GalDroid/WebGallery/Gallery3/RestCall.java: -------------------------------------------------------------------------------- 1 | package de.raptor2101.GalDroid.WebGallery.Gallery3; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.IOException; 5 | import java.io.InputStream; 6 | import java.io.InputStreamReader; 7 | 8 | import org.apache.http.Header; 9 | import org.apache.http.HttpResponse; 10 | import org.apache.http.client.ClientProtocolException; 11 | import org.apache.http.client.HttpClient; 12 | import org.apache.http.client.methods.HttpUriRequest; 13 | import org.json.JSONArray; 14 | import org.json.JSONException; 15 | import org.json.JSONObject; 16 | 17 | import android.util.Log; 18 | 19 | import de.raptor2101.GalDroid.WebGallery.Stream; 20 | 21 | public class RestCall { 22 | private static final String ClassTag = "RestCall"; 23 | private final HttpUriRequest mRequest; 24 | private final long mSuggestedLength; 25 | private final Gallery3Imp mWebGallery; 26 | 27 | public RestCall(Gallery3Imp webGallery, HttpUriRequest request, long suggestedLength) { 28 | mRequest = request; 29 | mSuggestedLength = suggestedLength; 30 | mWebGallery = webGallery; 31 | } 32 | 33 | public Stream open() throws IOException, ClientProtocolException { 34 | HttpClient client = mWebGallery.getHttpClient(); 35 | synchronized (client) { 36 | Log.i(ClassTag, String.format("Open HttpRequest to %s", mRequest.getURI().toURL())); 37 | HttpResponse response = mWebGallery.getHttpClient().execute(mRequest); 38 | Log.d(ClassTag, String.format("Response to %s opened", mRequest.getURI().toURL())); 39 | if (response.getStatusLine().getStatusCode() > 200) { 40 | throw new IOException("Something goes wrong!"); 41 | } 42 | Header[] headers = response.getHeaders("Content-Length"); 43 | if (headers.length > 0) { 44 | long contentLength = Long.parseLong(headers[0].getValue()); 45 | return new Stream(response.getEntity().getContent(), contentLength); 46 | } else { 47 | return new Stream(response.getEntity().getContent(), mSuggestedLength); 48 | } 49 | } 50 | } 51 | 52 | public JSONObject loadJSONObject() throws ClientProtocolException, IOException, JSONException { 53 | InputStream inputStream = open(); 54 | return parseJSON(inputStream); 55 | } 56 | 57 | public JSONArray loadJSONArray() throws ClientProtocolException, IOException, JSONException { 58 | InputStream inputStream = open(); 59 | return parseJSONArray(inputStream); 60 | } 61 | 62 | private JSONObject parseJSON(InputStream inputStream) throws IOException, JSONException { 63 | String content = loadContent(inputStream); 64 | return new JSONObject(content); 65 | } 66 | 67 | private JSONArray parseJSONArray(InputStream inputStream) throws IOException, JSONException { 68 | String content = loadContent(inputStream); 69 | return new JSONArray(content); 70 | } 71 | 72 | private String loadContent(InputStream inputStream) throws IOException { 73 | InputStreamReader streamReader = new InputStreamReader(inputStream); 74 | BufferedReader reader = new BufferedReader(streamReader); 75 | StringBuilder stringBuilder = new StringBuilder(); 76 | try { 77 | String line = null; 78 | 79 | while ((line = reader.readLine()) != null) { 80 | stringBuilder.append(line + '\n'); 81 | } 82 | } finally { 83 | reader.close(); 84 | inputStream.close(); 85 | } 86 | return stringBuilder.toString(); 87 | } 88 | 89 | public Gallery3Imp getWebGallery() { 90 | return mWebGallery; 91 | } 92 | 93 | } 94 | -------------------------------------------------------------------------------- /src/de/raptor2101/GalDroid/Activities/Listeners/ImageViewOnTouchListener.java: -------------------------------------------------------------------------------- 1 | package de.raptor2101.GalDroid.Activities.Listeners; 2 | 3 | import de.raptor2101.GalDroid.Activities.Views.GalleryImageView; 4 | import android.graphics.Matrix; 5 | import android.graphics.PointF; 6 | import android.util.FloatMath; 7 | import android.util.Log; 8 | import android.view.MotionEvent; 9 | import android.view.View; 10 | import android.view.View.OnTouchListener; 11 | import android.widget.Gallery; 12 | 13 | public class ImageViewOnTouchListener implements OnTouchListener { 14 | 15 | private enum TouchMode { 16 | None, Drag, Zoom, 17 | } 18 | 19 | private final Gallery mGalleryFullscreen; 20 | private final Gallery mGalleryThumbnails; 21 | 22 | private final float mMinDragHeight; 23 | 24 | private TouchMode mTouchMode; 25 | private PointF mScalePoint = new PointF(); 26 | private float mTouchStartY, mTouchStartX, mOldDist = 1; 27 | 28 | public ImageViewOnTouchListener(Gallery galleryFullscreen, Gallery galleryThumbnails, float minDragHeight) { 29 | mGalleryFullscreen = galleryFullscreen; 30 | mGalleryThumbnails = galleryThumbnails; 31 | mMinDragHeight = minDragHeight; 32 | } 33 | 34 | public boolean onTouch(View v, MotionEvent event) { 35 | Log.d("ImageViewActivity", "EventAction: " + event.getAction()); 36 | switch (event.getAction()) { 37 | case MotionEvent.ACTION_DOWN: 38 | mTouchStartY = event.getY(); 39 | mTouchStartX = event.getX(); 40 | mTouchMode = TouchMode.Drag; 41 | Log.d("ImageViewActivity", "Start Drag"); 42 | break; 43 | case MotionEvent.ACTION_POINTER_3_DOWN: 44 | case MotionEvent.ACTION_POINTER_2_DOWN: 45 | case MotionEvent.ACTION_POINTER_DOWN: 46 | /* 47 | * mOldDist = getSpacing(event); if(mOldDist > 10f) { mTouchMode = 48 | * TouchMode.Zoom; setScalePoint(event); } 49 | */ 50 | break; 51 | case MotionEvent.ACTION_POINTER_3_UP: 52 | case MotionEvent.ACTION_POINTER_2_UP: 53 | case MotionEvent.ACTION_POINTER_UP: 54 | mTouchMode = TouchMode.None; 55 | break; 56 | case MotionEvent.ACTION_UP: 57 | if (mTouchMode == TouchMode.Drag) { 58 | if (Math.abs(event.getX() - mTouchStartX) < 50) { 59 | float diffY = event.getY() - mTouchStartY; 60 | Log.d("ImageViewActivity", String.format("DragLength %.2f MinLength %.2f", Math.abs(diffY), mMinDragHeight)); 61 | if (Math.abs(diffY) > mMinDragHeight) { 62 | if (diffY > 0 && mGalleryThumbnails.getVisibility() == View.VISIBLE) { 63 | mGalleryThumbnails.setVisibility(View.GONE); 64 | } else if (diffY < 0 && mGalleryThumbnails.getVisibility() == View.GONE) { 65 | mGalleryThumbnails.setVisibility(View.VISIBLE); 66 | } 67 | } 68 | } 69 | } 70 | break; 71 | case MotionEvent.ACTION_MOVE: 72 | if (mTouchMode == TouchMode.Zoom) { 73 | float dist = getSpacing(event); 74 | if (dist > 10f) { 75 | GalleryImageView imageView = (GalleryImageView) mGalleryFullscreen.getSelectedView(); 76 | float scale = dist / mOldDist; 77 | if (scale >= 1 && scale <= 10) { 78 | Log.d("ImageViewActivity", "ACTION_MOVE Scale:" + scale); 79 | Matrix matrix = imageView.getImageMatrix(); 80 | 81 | matrix.postScale(scale, scale, mScalePoint.x - imageView.getLeft(), mScalePoint.y - imageView.getTop()); 82 | imageView.setImageMatrix(matrix); 83 | } 84 | } 85 | } 86 | break; 87 | } 88 | return false; 89 | } 90 | 91 | private float getSpacing(MotionEvent event) { 92 | float x = event.getX(0) - event.getX(1); 93 | float y = event.getY(0) - event.getY(1); 94 | return FloatMath.sqrt(x * x + y * y); 95 | } 96 | // Comment out till needed 97 | // private void setScalePoint(MotionEvent event) { 98 | // float x = event.getX(0) + event.getX(1); 99 | // float y = event.getY(0) + event.getY(1); 100 | // mScalePoint.set(x / 2, y / 2); 101 | // } 102 | } 103 | -------------------------------------------------------------------------------- /src/de/raptor2101/GalDroid/Activities/GalDroidApp.java: -------------------------------------------------------------------------------- 1 | /* 2 | * GalDroid - a webgallery frontend for android 3 | * Copyright (C) 2011 Raptor 2101 [raptor2101@gmx.de] 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package de.raptor2101.GalDroid.Activities; 20 | 21 | import java.security.NoSuchAlgorithmException; 22 | import java.util.List; 23 | 24 | import de.raptor2101.GalDroid.Config.GalDroidPreference; 25 | import de.raptor2101.GalDroid.Config.GalleryConfig; 26 | import de.raptor2101.GalDroid.WebGallery.ImageCache; 27 | import de.raptor2101.GalDroid.WebGallery.GalleryFactory; 28 | import de.raptor2101.GalDroid.WebGallery.Interfaces.GalleryObject; 29 | import de.raptor2101.GalDroid.WebGallery.Interfaces.WebGallery; 30 | import android.app.Activity; 31 | import android.app.Application; 32 | import android.net.http.AndroidHttpClient; 33 | 34 | public class GalDroidApp extends Application { 35 | public static final String INTENT_EXTRA_DISPLAY_GALLERY = ".de.raptor2101.GalDroid.GalleryObject"; 36 | public static final String INTENT_EXTRA_DISPLAY_INDEX = ".de.raptor2101.GalDroid.DisplayIndex"; 37 | public static final String INTENT_EXTRA_DISPLAY_OBJECT = ".de.raptor2101.GalDroid.DisplayObject"; 38 | public static final String INTENT_EXTRA_GALLERY_PROVIDER = ".de.raptor2101.GalDroid.GalleryProvider"; 39 | public static final String INTENT_EXTRA_SHOW_IMAGE_INFO = ".de.raptor2101.GalDroid.ShowImageInfo"; 40 | 41 | private WebGallery mWebGallery = null; 42 | private ImageCache mGalleryCache = null; 43 | private List mGalleryChildObjects = null; 44 | private GalleryObject mStoredGalleryObject = null; 45 | 46 | public WebGallery getWebGallery() { 47 | return mWebGallery; 48 | } 49 | 50 | public ImageCache getImageCache() { 51 | return mGalleryCache; 52 | } 53 | 54 | public void Initialize(Activity activity) throws NoSuchAlgorithmException { 55 | GalDroidPreference.Initialize(this); 56 | 57 | if (mGalleryCache == null) { 58 | mGalleryCache = new ImageCache(activity); 59 | } 60 | 61 | if (mWebGallery == null) { 62 | try { 63 | String galleryName = activity.getIntent().getExtras().getString(INTENT_EXTRA_GALLERY_PROVIDER); 64 | if (galleryName != null) { 65 | GalleryConfig galleryConfig = GalDroidPreference.getSetupByName(galleryName); 66 | mWebGallery = GalleryFactory.createFromName(galleryConfig.TypeName, galleryConfig.RootLink, AndroidHttpClient.newInstance("GalDroid")); 67 | mWebGallery.setSecurityToken(galleryConfig.SecurityToken); 68 | } 69 | } catch (NullPointerException e) { 70 | mWebGallery = null; 71 | } 72 | } 73 | } 74 | 75 | public void setWebGallery(WebGallery webGallery) { 76 | mWebGallery = webGallery; 77 | mGalleryChildObjects = null; 78 | mStoredGalleryObject = null; 79 | } 80 | 81 | public void storeGalleryObjects(GalleryObject parent, List childObjects) { 82 | if (parent != null) { 83 | mStoredGalleryObject = parent; 84 | mGalleryChildObjects = childObjects; 85 | } else { 86 | parent = null; 87 | childObjects = null; 88 | } 89 | } 90 | 91 | public List loadStoredGalleryObjects(GalleryObject parent) { 92 | if (parent == null) { 93 | return null; 94 | } 95 | 96 | if (!parent.equals(mStoredGalleryObject)) { 97 | return null; 98 | } 99 | 100 | return mGalleryChildObjects; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/de/raptor2101/GalDroid/WebGallery/Gallery3/JSON/Entity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * GalDroid - a webgallery frontend for android 3 | * Copyright (C) 2011 Raptor 2101 [raptor2101@gmx.de] 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package de.raptor2101.GalDroid.WebGallery.Gallery3.JSON; 20 | 21 | import java.util.ArrayList; 22 | import java.util.Date; 23 | import java.util.List; 24 | import java.util.regex.Matcher; 25 | import java.util.regex.Pattern; 26 | 27 | import org.json.JSONArray; 28 | import org.json.JSONException; 29 | import org.json.JSONObject; 30 | 31 | import de.raptor2101.GalDroid.WebGallery.Gallery3.DownloadObject; 32 | import de.raptor2101.GalDroid.WebGallery.Gallery3.Gallery3Imp; 33 | import de.raptor2101.GalDroid.WebGallery.Interfaces.GalleryObject; 34 | import de.raptor2101.GalDroid.WebGallery.Interfaces.GalleryDownloadObject; 35 | 36 | public abstract class Entity implements GalleryObject { 37 | private static final long serialVersionUID = 632836774464520503L; 38 | 39 | private final Pattern mPatternExtractTagId = Pattern.compile("tag_item/(\\d+),\\d+"); 40 | private final String mRootLink; 41 | private final String mTitle; 42 | private final String mLink; 43 | private final int mId; 44 | 45 | private final Date mUploadDate; 46 | private final ArrayList mTags; 47 | protected String mLink_Full; 48 | protected String mLink_Thumb; 49 | 50 | protected int mFileSize_Full; 51 | protected int mFileSize_Thumb; 52 | 53 | public Entity(JSONObject jsonObject, Gallery3Imp gallery3) throws JSONException { 54 | JSONObject entity = jsonObject.getJSONObject("entity"); 55 | 56 | mId = entity.getInt("id"); 57 | 58 | long msElapsed = entity.getLong("created") * 1000; 59 | mUploadDate = new Date(msElapsed); 60 | 61 | mTitle = entity.getString("title"); 62 | mLink = gallery3.getItemLink(mId); 63 | mRootLink = gallery3.getRootLink(); 64 | 65 | JSONObject relationShips = jsonObject.getJSONObject("relationships"); 66 | JSONObject tagsSection = relationShips.getJSONObject("tags"); 67 | JSONArray tags = tagsSection.getJSONArray("members"); 68 | 69 | mTags = new ArrayList(tags.length()); 70 | for (int i = 0; i < tags.length(); i++) { 71 | Matcher matcher = mPatternExtractTagId.matcher(tags.getString(i)); 72 | while (matcher.find()) { 73 | String tagId = matcher.group(1); 74 | mTags.add(String.format(gallery3.LinkRest_LoadTag, tagId)); 75 | } 76 | } 77 | } 78 | 79 | public String getTitle() { 80 | return mTitle; 81 | } 82 | 83 | public int getId() { 84 | return mId; 85 | } 86 | 87 | public String getObjectId() { 88 | return String.format("%s/%d", mRootLink, mId); 89 | } 90 | 91 | public String getObjectLink() { 92 | return mLink; 93 | } 94 | 95 | public Date getDateUploaded() { 96 | return mUploadDate; 97 | } 98 | 99 | public GalleryDownloadObject getImage() { 100 | return createDownloadObject(mLink_Full, mFileSize_Full); 101 | } 102 | 103 | public GalleryDownloadObject getThumbnail() { 104 | return createDownloadObject(mLink_Thumb, mFileSize_Thumb); 105 | } 106 | 107 | private GalleryDownloadObject createDownloadObject(String link, int fileSize) { 108 | return !link.equals("") ? new DownloadObject(mRootLink, link, fileSize) : null; 109 | } 110 | 111 | public List getTagLinks() { 112 | return mTags; 113 | } 114 | 115 | @Override 116 | public String toString() { 117 | return mLink; 118 | } 119 | 120 | @Override 121 | public boolean equals(Object o) { 122 | if (o instanceof Entity) { 123 | Entity entity = (Entity) o; 124 | return entity.mId == mId; 125 | } else { 126 | return false; 127 | } 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /src/de/raptor2101/GalDroid/Activities/EditGalleryActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * GalDroid - a webgallery frontend for android 3 | * Copyright (C) 2011 Raptor 2101 [raptor2101@gmx.de] 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package de.raptor2101.GalDroid.Activities; 20 | 21 | import android.app.Activity; 22 | import android.app.ProgressDialog; 23 | import android.os.Bundle; 24 | import android.view.View; 25 | import android.view.View.OnClickListener; 26 | import android.widget.ArrayAdapter; 27 | import android.widget.Button; 28 | import android.widget.Spinner; 29 | import android.widget.TextView; 30 | import de.raptor2101.GalDroid.R; 31 | import de.raptor2101.GalDroid.Config.GalDroidPreference; 32 | import de.raptor2101.GalDroid.Config.GalleryConfig; 33 | import de.raptor2101.GalDroid.WebGallery.Tasks.GalleryVerifyTask; 34 | 35 | public class EditGalleryActivity extends Activity implements OnClickListener { 36 | private ProgressDialog mProgressDialog; 37 | private ArrayAdapter mAdapter; 38 | private GalleryConfig mConfig; 39 | 40 | @Override 41 | public void onCreate(Bundle savedInstanceState) { 42 | super.onCreate(savedInstanceState); 43 | setContentView(R.layout.create_gallery_activity); 44 | 45 | Spinner spinner = (Spinner) findViewById(R.id.spinnerGalleryType); 46 | mAdapter = ArrayAdapter.createFromResource(this, R.array.gallery_types, android.R.layout.simple_spinner_item); 47 | mAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 48 | spinner.setAdapter(mAdapter); 49 | 50 | Button button = (Button) findViewById(R.id.buttonCreate); 51 | button.setOnClickListener(this); 52 | Bundle extras = getIntent().getExtras(); 53 | if (extras != null) { 54 | String configName = extras.getString(GalDroidApp.INTENT_EXTRA_GALLERY_PROVIDER); 55 | if (configName != null) { 56 | mConfig = GalDroidPreference.getSetupByName(configName); 57 | button.setText("Edit"); 58 | 59 | TextView galleryName = (TextView) findViewById(R.id.editGallery); 60 | TextView serverName = (TextView) findViewById(R.id.editServer); 61 | 62 | galleryName.setText(configName); 63 | serverName.setText(mConfig.RootLink); 64 | String typeName = mConfig.TypeName; 65 | for (int i = 0; i < mAdapter.getCount(); i++) { 66 | String galleryType = mAdapter.getItem(i).toString(); 67 | if (galleryType.equals(typeName)) { 68 | spinner.setSelection(i); 69 | } 70 | } 71 | } else { 72 | button.setText(R.string.button_create); 73 | } 74 | } else { 75 | button.setText(R.string.button_create); 76 | } 77 | mProgressDialog = new ProgressDialog(this); 78 | mProgressDialog.setTitle(R.string.progress_title_verify); 79 | mProgressDialog.setCancelable(false); 80 | } 81 | 82 | public void onClick(View v) { 83 | 84 | Spinner spinner = (Spinner) findViewById(R.id.spinnerGalleryType); 85 | String name = ((TextView) findViewById(R.id.editGallery)).getText().toString(); 86 | String galleryType = (String) spinner.getSelectedItem(); 87 | String server = ((TextView) findViewById(R.id.editServer)).getText().toString().toLowerCase(); 88 | String username = ((TextView) findViewById(R.id.editUsername)).getText().toString(); 89 | String password = ((TextView) findViewById(R.id.editPassword)).getText().toString(); 90 | 91 | if (!(server.startsWith("http://") || server.startsWith("https://"))) { 92 | server = "http://" + server; 93 | } 94 | 95 | mProgressDialog.show(); 96 | 97 | int id = mConfig != null ? mConfig.Id : -1; 98 | 99 | GalleryConfig config = new GalleryConfig(id, name, galleryType, server, ""); 100 | GalleryVerifyTask verifyTask = new GalleryVerifyTask(config, username, password, this); 101 | verifyTask.execute(); 102 | } 103 | 104 | public void onGalleryVerified(Boolean result) { 105 | mProgressDialog.dismiss(); 106 | if (result == true) { 107 | this.finish(); 108 | } 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/de/raptor2101/GalDroid/Activities/GalleryListingActivitiy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * GalDroid - a webgallery frontend for android 3 | * Copyright (C) 2011 Raptor 2101 [raptor2101@gmx.de] 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package de.raptor2101.GalDroid.Activities; 20 | 21 | import java.security.NoSuchAlgorithmException; 22 | import java.util.List; 23 | 24 | import android.app.ListActivity; 25 | import android.app.ProgressDialog; 26 | import android.content.Intent; 27 | import android.os.Bundle; 28 | import android.view.ContextMenu; 29 | import android.view.ContextMenu.ContextMenuInfo; 30 | import android.view.Menu; 31 | import android.view.MenuInflater; 32 | import android.view.MenuItem; 33 | import android.view.View; 34 | import android.widget.AdapterView.AdapterContextMenuInfo; 35 | import android.widget.ArrayAdapter; 36 | import android.widget.ListView; 37 | import android.widget.TextView; 38 | import de.raptor2101.GalDroid.R; 39 | import de.raptor2101.GalDroid.Config.GalDroidPreference; 40 | import de.raptor2101.GalDroid.WebGallery.ImageCache; 41 | import de.raptor2101.GalDroid.WebGallery.Tasks.CleanUpCacheTask; 42 | import de.raptor2101.GalDroid.WebGallery.Tasks.SyncronizeCacheTask; 43 | import de.raptor2101.GalDroid.WebGallery.Tasks.CacheTaskListener; 44 | 45 | public class GalleryListingActivitiy extends ListActivity implements CacheTaskListener { 46 | private ProgressDialog mProgressDialog; 47 | 48 | @Override 49 | public void onCreate(Bundle savedInstanceState) { 50 | super.onCreate(savedInstanceState); 51 | registerForContextMenu(getListView()); 52 | } 53 | 54 | @Override 55 | public boolean onContextItemSelected(MenuItem item) { 56 | 57 | AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo(); 58 | TextView view = (TextView) info.targetView; 59 | 60 | String galleryName = view.getText().toString(); 61 | if (item.getItemId() == R.id.item_edit_gallery) { 62 | Intent intent = new Intent(this, EditGalleryActivity.class); 63 | intent.putExtra(GalDroidApp.INTENT_EXTRA_GALLERY_PROVIDER, galleryName); 64 | this.startActivity(intent); 65 | } else { 66 | GalDroidPreference.deleteGallery(galleryName); 67 | recreate(); 68 | } 69 | return true; 70 | } 71 | 72 | @Override 73 | public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { 74 | MenuInflater inflater = getMenuInflater(); 75 | inflater.inflate(R.menu.gallery_context_menu, menu); 76 | } 77 | 78 | @Override 79 | public boolean onCreateOptionsMenu(Menu menu) { 80 | MenuInflater inflater = getMenuInflater(); 81 | inflater.inflate(R.menu.gallery_menu, menu); 82 | return true; 83 | } 84 | 85 | @Override 86 | public boolean onOptionsItemSelected(MenuItem item) { 87 | if (item.getItemId() == R.id.item_create_new) { 88 | Intent intent = new Intent(this, EditGalleryActivity.class); 89 | this.startActivity(intent); 90 | } else { 91 | CreateProgressDialog(R.string.menu_synchronize_cache); 92 | GalDroidApp app = (GalDroidApp) getApplication(); 93 | SyncronizeCacheTask task = new SyncronizeCacheTask(app.getImageCache(), this); 94 | task.execute(); 95 | } 96 | return true; 97 | } 98 | 99 | private void CreateProgressDialog(int titleRecouceId) { 100 | mProgressDialog = new ProgressDialog(this); 101 | mProgressDialog.setTitle(titleRecouceId); 102 | mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); 103 | mProgressDialog.setCancelable(false); 104 | mProgressDialog.dismiss(); 105 | } 106 | 107 | @Override 108 | protected void onListItemClick(ListView l, View v, int position, long id) { 109 | TextView view = (TextView) v; 110 | String galleryName = view.getText().toString(); 111 | 112 | Intent intent = new Intent(this, GridViewActivity.class); 113 | intent.putExtra(GalDroidApp.INTENT_EXTRA_GALLERY_PROVIDER, galleryName); 114 | 115 | this.startActivity(intent); 116 | } 117 | 118 | @Override 119 | protected void onResume() { 120 | try { 121 | GalDroidApp app = (GalDroidApp) getApplication(); 122 | app.Initialize(this); 123 | List names = GalDroidPreference.getGalleryNames(); 124 | 125 | if(names.size() == 0) { 126 | Intent intent = new Intent(this, EditGalleryActivity.class); 127 | this.startActivity(intent); 128 | } 129 | else 130 | { 131 | showNames(app, names); 132 | } 133 | 134 | 135 | } catch (NoSuchAlgorithmException e) { 136 | e.printStackTrace(); 137 | } 138 | 139 | super.onResume(); 140 | } 141 | 142 | private void showNames(GalDroidApp app, List names) { 143 | setListAdapter(new ArrayAdapter(this, R.layout.gallery_listing_activity, GalDroidPreference.getGalleryNames())); 144 | 145 | ImageCache cache = app.getImageCache(); 146 | if (cache.isCleanUpNeeded()) { 147 | CreateProgressDialog(R.string.menu_cleanup_cache); 148 | CleanUpCacheTask task = new CleanUpCacheTask(cache, this); 149 | task.execute(); 150 | } 151 | } 152 | 153 | public void onCacheOperationStart(int elementCount) { 154 | mProgressDialog.setMax(elementCount); 155 | mProgressDialog.setProgress(0); 156 | mProgressDialog.show(); 157 | 158 | } 159 | 160 | public void onCacheOperationProgress(int elementCount) { 161 | mProgressDialog.setProgress(elementCount); 162 | 163 | } 164 | 165 | public void onCacheOperationDone() { 166 | mProgressDialog.dismiss(); 167 | mProgressDialog = null; 168 | } 169 | } 170 | -------------------------------------------------------------------------------- /src/de/raptor2101/GalDroid/Activities/Views/GalleryImageView.java: -------------------------------------------------------------------------------- 1 | /* 2 | * GalDroid - a webgallery frontend for android 3 | * Copyright (C) 2011 Raptor 2101 [raptor2101@gmx.de] 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package de.raptor2101.GalDroid.Activities.Views; 20 | 21 | import java.lang.ref.WeakReference; 22 | 23 | import android.content.Context; 24 | import android.graphics.Bitmap; 25 | import android.graphics.Matrix; 26 | import android.util.Log; 27 | import android.view.LayoutInflater; 28 | import android.widget.ImageView; 29 | import android.widget.LinearLayout; 30 | import android.widget.ProgressBar; 31 | import android.widget.TextView; 32 | import de.raptor2101.GalDroid.R; 33 | import de.raptor2101.GalDroid.WebGallery.Interfaces.GalleryObject; 34 | import de.raptor2101.GalDroid.WebGallery.Tasks.ImageLoaderTask; 35 | import de.raptor2101.GalDroid.WebGallery.Tasks.ImageLoaderTaskListener; 36 | 37 | public class GalleryImageView extends LinearLayout implements ImageLoaderTaskListener { 38 | private static final String CLASS_TAG = "GalleryImageView"; 39 | private final ProgressBar mProgressBar_determinate; 40 | private final ProgressBar mProgressBar_indeterminate; 41 | private final ImageView mImageView; 42 | private final TextView mTitleTextView; 43 | private GalleryObject mGalleryObject; 44 | private WeakReference mListener; 45 | private boolean mLoaded; 46 | private WeakReference mAssignedImageDownload; 47 | 48 | public GalleryImageView(Context context, boolean showTitle) { 49 | super(context); 50 | LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 51 | inflater.inflate(R.layout.gallery_image_view, this); 52 | 53 | mProgressBar_determinate = (ProgressBar) findViewById(R.id.progressBar_Determinate); 54 | mProgressBar_indeterminate = (ProgressBar) findViewById(R.id.progressBar_Indeterminate); 55 | 56 | mTitleTextView = (TextView) findViewById(R.id.text_Title); 57 | mImageView = (ImageView) findViewById(R.id.imageView_Image); 58 | 59 | if (showTitle) { 60 | mTitleTextView.setVisibility(VISIBLE); 61 | } else { 62 | mTitleTextView.setVisibility(GONE); 63 | } 64 | 65 | mListener = new WeakReference(null); 66 | mAssignedImageDownload = new WeakReference(null); 67 | } 68 | 69 | public void setGalleryObject(GalleryObject galleryObject) { 70 | cleanup(); 71 | mGalleryObject = galleryObject; 72 | mProgressBar_determinate.setVisibility(GONE); 73 | mProgressBar_indeterminate.setVisibility(VISIBLE); 74 | this.setTitle(galleryObject.getTitle()); 75 | } 76 | 77 | public void resetLoading() { 78 | mProgressBar_determinate.setVisibility(GONE); 79 | mProgressBar_indeterminate.setVisibility(GONE); 80 | mAssignedImageDownload = new WeakReference(null); 81 | } 82 | 83 | public GalleryObject getGalleryObject() { 84 | return mGalleryObject; 85 | } 86 | 87 | public void setTitle(String title) { 88 | if (mTitleTextView != null) { 89 | mTitleTextView.setText(title); 90 | } 91 | } 92 | 93 | @Override 94 | protected void onDetachedFromWindow() { 95 | super.onDetachedFromWindow(); 96 | cleanup(); 97 | } 98 | 99 | public void cleanup() { 100 | if (mLoaded) { 101 | Log.d(CLASS_TAG, String.format("Recycle %s", mGalleryObject.getObjectId())); 102 | mImageView.setImageBitmap(null); 103 | mImageView.destroyDrawingCache(); 104 | mImageView.setVisibility(GONE); 105 | mLoaded = false; 106 | } 107 | } 108 | 109 | public Matrix getImageMatrix() { 110 | return mImageView.getMatrix(); 111 | } 112 | 113 | public void setImageMatrix(Matrix matrix) { 114 | mImageView.setScaleType(ImageView.ScaleType.MATRIX); 115 | mImageView.setImageMatrix(matrix); 116 | } 117 | 118 | public boolean isLoaded() { 119 | return mLoaded; 120 | } 121 | 122 | public String getObjectId() { 123 | return mGalleryObject.getObjectId(); 124 | } 125 | 126 | public void onLoadingStarted(String uniqueId) { 127 | Log.d(CLASS_TAG, String.format("Loading started %s", uniqueId)); 128 | 129 | mProgressBar_determinate.setMax(100); 130 | mProgressBar_determinate.setProgress(0); 131 | 132 | mProgressBar_indeterminate.setVisibility(GONE); 133 | mProgressBar_determinate.setVisibility(VISIBLE); 134 | 135 | GalleryImageViewListener listener = mListener.get(); 136 | if (listener != null) { 137 | listener.onLoadingStarted(mGalleryObject); 138 | } 139 | } 140 | 141 | public void onLoadingProgress(String uniqueId, int currentValue, int maxValue) { 142 | Log.d(CLASS_TAG, String.format("Progress %s %d %d", uniqueId, currentValue , maxValue)); 143 | mProgressBar_determinate.setMax(maxValue); 144 | mProgressBar_determinate.setProgress(currentValue); 145 | GalleryImageViewListener listener = mListener.get(); 146 | if (listener != null) { 147 | listener.onLoadingProgress(mGalleryObject, currentValue , maxValue); 148 | } 149 | } 150 | 151 | public void onLoadingCompleted(String uniqueId, Bitmap bitmap) { 152 | GalleryImageViewListener listener = mListener.get(); 153 | Log.d(CLASS_TAG, String.format("Loading done %s - Listener: %s", uniqueId, listener != null)); 154 | mProgressBar_indeterminate.setVisibility(GONE); 155 | mProgressBar_determinate.setVisibility(GONE); 156 | mLoaded = true; 157 | mImageView.setImageBitmap(bitmap); 158 | mImageView.setVisibility(VISIBLE); 159 | mAssignedImageDownload = new WeakReference(null); 160 | 161 | if (listener != null) { 162 | listener.onLoadingCompleted(mGalleryObject); 163 | } 164 | } 165 | 166 | public void onLoadingCancelled(String uniqueId) { 167 | GalleryImageViewListener listener = mListener.get(); 168 | Log.d(CLASS_TAG, String.format("Loading cancelled %s - Listener: %s", uniqueId, listener != null)); 169 | mProgressBar_indeterminate.setVisibility(GONE); 170 | mProgressBar_determinate.setVisibility(GONE); 171 | mAssignedImageDownload = new WeakReference(null); 172 | 173 | if (listener != null) { 174 | listener.onLoadingCancelled(mGalleryObject); 175 | } 176 | } 177 | 178 | public void setListener(GalleryImageViewListener listener) { 179 | mListener = new WeakReference(listener); 180 | } 181 | 182 | public void setImageDownload(ImageLoaderTask.ImageDownload imageDownload) { 183 | mAssignedImageDownload = new WeakReference(imageDownload); 184 | } 185 | 186 | public ImageLoaderTask.ImageDownload getImageDownload() { 187 | return mAssignedImageDownload.get(); 188 | } 189 | 190 | public boolean isLoading() { 191 | return mAssignedImageDownload.get() != null; 192 | } 193 | } 194 | -------------------------------------------------------------------------------- /src/de/raptor2101/GalDroid/WebGallery/ImageCache.java: -------------------------------------------------------------------------------- 1 | /* 2 | * GalDroid - a webgallery frontend for android 3 | * Copyright (C) 2011 Raptor 2101 [raptor2101@gmx.de] 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package de.raptor2101.GalDroid.WebGallery; 20 | 21 | import java.io.File; 22 | import java.io.FileInputStream; 23 | import java.io.FileOutputStream; 24 | import java.io.IOException; 25 | import java.io.OutputStream; 26 | import java.lang.ref.WeakReference; 27 | import java.security.MessageDigest; 28 | import java.security.NoSuchAlgorithmException; 29 | import java.util.Hashtable; 30 | 31 | import de.raptor2101.GalDroid.Config.GalDroidPreference; 32 | 33 | import android.content.Context; 34 | import android.graphics.Bitmap; 35 | import android.util.Log; 36 | 37 | public class ImageCache { 38 | private static final String ClassTag = "GalleryCache"; 39 | private static long mMaxCacheSize = 50 * 1024 * 1024; // convert MByte to 40 | // Byte 41 | private File mCacheDir; 42 | private MessageDigest mDigester; 43 | private Hashtable> mCachedBitmaps; 44 | 45 | public ImageCache(Context context) throws NoSuchAlgorithmException { 46 | Log.d(ClassTag, "Recreate cache"); 47 | if (mCacheDir == null) { 48 | mCacheDir = context.getExternalCacheDir(); 49 | 50 | if (mCacheDir == null) { 51 | mCacheDir = context.getCacheDir(); 52 | } 53 | } 54 | if (!mCacheDir.exists()) { 55 | mCacheDir.mkdirs(); 56 | } 57 | mCachedBitmaps = new Hashtable>(50); 58 | mDigester = MessageDigest.getInstance("MD5"); 59 | } 60 | 61 | public Bitmap getBitmap(String sourceUrl) { 62 | String hash = buildHash(sourceUrl); 63 | WeakReference reference; 64 | 65 | synchronized (mCachedBitmaps) { 66 | reference = mCachedBitmaps.get(hash); 67 | } 68 | 69 | if (reference == null) { 70 | Log.d(ClassTag, "Cache Miss Hash Reference " + sourceUrl); 71 | return null; 72 | } 73 | Bitmap bitmap = reference.get(); 74 | if (bitmap == null || bitmap.isRecycled()) { 75 | if (bitmap != null) { 76 | Log.d(ClassTag, "Bitmap Recycled " + sourceUrl); 77 | } else { 78 | Log.d(ClassTag, "Cache Miss Object Reference " + sourceUrl); 79 | } 80 | 81 | synchronized (mCachedBitmaps) { 82 | mCachedBitmaps.remove(hash); 83 | } 84 | return null; 85 | } 86 | Log.d(ClassTag, "Cache Hit Reference " + sourceUrl); 87 | return bitmap; 88 | } 89 | 90 | public void storeBitmap(String sourceUrl, Bitmap bitmap) { 91 | String hash = buildHash(sourceUrl); 92 | File cacheFile = new File(mCacheDir, hash); 93 | 94 | synchronized (mCachedBitmaps) { 95 | mCachedBitmaps.put(hash, new WeakReference(bitmap)); 96 | } 97 | 98 | Log.d(ClassTag, "Bitmap referenced " + sourceUrl); 99 | 100 | if (cacheFile.exists()) { 101 | cacheFile.delete(); 102 | } 103 | try { 104 | cacheFile.createNewFile(); 105 | 106 | FileOutputStream output = new FileOutputStream(cacheFile); 107 | bitmap.compress(Bitmap.CompressFormat.JPEG, 100, output); 108 | output.close(); 109 | Log.d(ClassTag, "Bitmap stored local " + sourceUrl); 110 | GalDroidPreference.accessCacheObject(hash, cacheFile.length()); 111 | } catch (IOException e) { 112 | Log.e(ClassTag, "Error while storing"); 113 | } 114 | } 115 | 116 | public void cacheBitmap(String sourceUrl, Bitmap bitmap) { 117 | String hash = buildHash(sourceUrl); 118 | synchronized (mCachedBitmaps) { 119 | mCachedBitmaps.put(hash, new WeakReference(bitmap)); 120 | } 121 | Log.d(ClassTag, "Bitmap referenced " + sourceUrl); 122 | } 123 | 124 | public FileInputStream getFileStream(String sourceUrl) { 125 | String hash = buildHash(sourceUrl); 126 | File cacheFile = new File(mCacheDir, hash); 127 | if (GalDroidPreference.cacheObjectExists(hash) && cacheFile.exists()) { 128 | try { 129 | Log.d(ClassTag, "Cache Hit " + sourceUrl); 130 | GalDroidPreference.accessCacheObject(hash, cacheFile.length()); 131 | return new FileInputStream(cacheFile); 132 | 133 | } catch (IOException e) { 134 | Log.e(ClassTag, "Error while accessing"); 135 | return null; 136 | } 137 | } 138 | Log.d(ClassTag, "Cache Mis " + sourceUrl); 139 | return null; 140 | } 141 | 142 | public File getFile(String sourceUrl) { 143 | String hash = buildHash(sourceUrl); 144 | return new File(mCacheDir, hash); 145 | } 146 | 147 | public OutputStream createCacheFile(String sourceUrl) throws IOException { 148 | String hash = buildHash(sourceUrl); 149 | File cacheFile = new File(mCacheDir, hash); 150 | 151 | if (cacheFile.exists()) { 152 | cacheFile.delete(); 153 | } 154 | 155 | try { 156 | Log.d(ClassTag, "Create CacheFile " + sourceUrl); 157 | cacheFile.createNewFile(); 158 | return new FileOutputStream(cacheFile); 159 | 160 | } catch (IOException e) { 161 | Log.e(ClassTag, "Error while accessing"); 162 | throw e; 163 | } 164 | } 165 | 166 | public void removeCacheFile(String uniqueId) { 167 | String hash = buildHash(uniqueId); 168 | File cacheFile = new File(mCacheDir, hash); 169 | 170 | if (cacheFile.exists()) { 171 | cacheFile.delete(); 172 | } 173 | 174 | } 175 | 176 | public void refreshCacheFile(String sourceUrl) { 177 | String hash = buildHash(sourceUrl); 178 | File cacheFile = new File(mCacheDir, hash); 179 | 180 | if (cacheFile.exists()) { 181 | GalDroidPreference.accessCacheObject(hash, cacheFile.length()); 182 | } 183 | } 184 | 185 | private String buildHash(String sourceUrl) { 186 | synchronized (mDigester) { 187 | mDigester.reset(); 188 | byte[] bytes = sourceUrl.getBytes(); 189 | mDigester.update(bytes, 0, bytes.length); 190 | byte[] diggest = mDigester.digest(); 191 | StringBuffer returnString = new StringBuffer(diggest.length); 192 | for (byte b : diggest) { 193 | returnString.append(Integer.toHexString(0xFF & b)); 194 | } 195 | return returnString.toString(); 196 | } 197 | } 198 | 199 | public void clearCachedBitmaps(boolean recycleBitmaps) { 200 | if (recycleBitmaps) { 201 | for (WeakReference reference : mCachedBitmaps.values()) { 202 | Bitmap bitmap = reference.get(); 203 | if (bitmap != null) { 204 | bitmap.recycle(); 205 | } 206 | } 207 | } 208 | mCachedBitmaps.clear(); 209 | } 210 | 211 | public File[] ListCachedFiles() { 212 | if (mCacheDir.exists()) { 213 | return mCacheDir.listFiles(); 214 | } else { 215 | return new File[0]; 216 | } 217 | } 218 | 219 | public long getMaxCacheSize() { 220 | return mMaxCacheSize; 221 | } 222 | 223 | public boolean isCleanUpNeeded() { 224 | long currentCacheSize = GalDroidPreference.getCacheSpaceNeeded(); 225 | return currentCacheSize > mMaxCacheSize; 226 | } 227 | 228 | public File getCacheDir() { 229 | return mCacheDir; 230 | } 231 | } 232 | -------------------------------------------------------------------------------- /src/de/raptor2101/GalDroid/Activities/GalleryActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * GalDroid - a webgallery frontend for android 3 | * Copyright (C) 2011 Raptor 2101 [raptor2101@gmx.de] 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package de.raptor2101.GalDroid.Activities; 20 | 21 | import java.io.File; 22 | import java.io.Serializable; 23 | import java.lang.ref.WeakReference; 24 | import java.security.NoSuchAlgorithmException; 25 | import java.util.List; 26 | 27 | import de.raptor2101.GalDroid.R; 28 | import de.raptor2101.GalDroid.WebGallery.Interfaces.GalleryObject; 29 | import de.raptor2101.GalDroid.WebGallery.Interfaces.WebGallery; 30 | import de.raptor2101.GalDroid.WebGallery.Tasks.GalleryLoaderTask; 31 | import de.raptor2101.GalDroid.WebGallery.Tasks.GalleryLoaderTaskListener; 32 | import android.app.Activity; 33 | import android.app.ProgressDialog; 34 | import android.content.ContentValues; 35 | import android.content.Intent; 36 | import android.net.Uri; 37 | import android.os.Bundle; 38 | import android.provider.MediaStore; 39 | import android.util.Log; 40 | import android.view.ViewGroup.LayoutParams; 41 | 42 | public abstract class GalleryActivity extends Activity { 43 | private static final String INSTANCE_STATE_CURRENT_INDEX = ".de.raptor2101.GalDroid.CurrentIndex"; 44 | private static final String INSTANCE_STATE_GALLERY_OBJECTS = ".de.raptor2101.GalDroid.GalleryObjects"; 45 | private List mGalleryObjects; 46 | private int mCurrentIndex; 47 | 48 | private class GalleryLoadingListener implements GalleryLoaderTaskListener { 49 | 50 | public void onDownloadStarted() { 51 | mProgressDialog.show(); 52 | } 53 | 54 | public void onDownloadProgress(int elementCount, int maxCount) { 55 | mProgressDialog.setMax(maxCount); 56 | mProgressDialog.setProgress(elementCount); 57 | 58 | } 59 | 60 | public void onDownloadCompleted(List galleryObjects) { 61 | mProgressDialog.dismiss(); 62 | GalDroidApp app = (GalDroidApp) getApplicationContext(); 63 | app.storeGalleryObjects(getDisplayedGallery(), galleryObjects); 64 | mGalleryObjects = galleryObjects; 65 | Log.d("GalleryActivity", "Call onGalleryObjectsLoaded"); 66 | onGalleryObjectsLoaded(galleryObjects); 67 | 68 | } 69 | } 70 | 71 | 72 | 73 | private ProgressDialog mProgressDialog; 74 | private GalleryLoaderTaskListener mListener; 75 | 76 | private WeakReference mDownloadTask; 77 | 78 | @Override 79 | public void onCreate(Bundle savedInstanceState) { 80 | super.onCreate(savedInstanceState); 81 | Log.d("GalleryActivity", "New Activity"); 82 | try { 83 | initialize(); 84 | 85 | } catch (NoSuchAlgorithmException e) { 86 | // TODO Auto-generated catch block 87 | e.printStackTrace(); 88 | } 89 | } 90 | 91 | @SuppressWarnings("unchecked") 92 | @Override 93 | protected void onPostCreate(Bundle savedInstanceState) { 94 | super.onPostCreate(savedInstanceState); 95 | GalDroidApp app = (GalDroidApp) getApplicationContext(); 96 | 97 | if(savedInstanceState != null) { 98 | mCurrentIndex = savedInstanceState.getInt(INSTANCE_STATE_CURRENT_INDEX); 99 | mGalleryObjects = (List) savedInstanceState.getSerializable(INSTANCE_STATE_GALLERY_OBJECTS); 100 | } else { 101 | mCurrentIndex = -1; 102 | mGalleryObjects = null; 103 | } 104 | 105 | 106 | GalleryObject diplayedGallery = getDisplayedGallery(); 107 | 108 | // Try to get galleryobjects from application cache 109 | if (mGalleryObjects == null) { 110 | mGalleryObjects = app.loadStoredGalleryObjects(diplayedGallery); 111 | } 112 | 113 | // Now we have time, load the object from the remote source 114 | if (mGalleryObjects == null) { 115 | mProgressDialog = new ProgressDialog(this); 116 | mProgressDialog.setTitle(R.string.progress_title_load_gallery); 117 | mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); 118 | mProgressDialog.setCancelable(false); 119 | mProgressDialog.dismiss(); 120 | 121 | WebGallery gallery = app.getWebGallery(); 122 | if (gallery != null) { 123 | LayoutParams params = this.getWindow().getAttributes(); 124 | gallery.setPreferedDimensions(params.height, params.width); 125 | mListener = new GalleryLoadingListener(); 126 | GalleryLoaderTask task = new GalleryLoaderTask(gallery, mListener); 127 | task.execute(diplayedGallery); 128 | mDownloadTask = new WeakReference(task); 129 | } else { 130 | // Without a valid Gallery nothing can be displayed... back to 131 | // previous activity 132 | this.finish(); 133 | } 134 | } else { 135 | onGalleryObjectsLoaded(mGalleryObjects); 136 | } 137 | } 138 | 139 | @Override 140 | protected void onResume() { 141 | super.onResume(); 142 | Log.d("GalleryActivity", "Resume Activity"); 143 | try { 144 | initialize(); 145 | } catch (NoSuchAlgorithmException e) { 146 | // TODO Auto-generated catch block 147 | e.printStackTrace(); 148 | } 149 | 150 | } 151 | 152 | private void initialize() throws NoSuchAlgorithmException { 153 | GalDroidApp app = (GalDroidApp) getApplicationContext(); 154 | app.Initialize(this); 155 | } 156 | 157 | @Override 158 | public void onSaveInstanceState(Bundle savedInstanceState) { 159 | savedInstanceState.putSerializable(INSTANCE_STATE_GALLERY_OBJECTS, (Serializable) mGalleryObjects); 160 | savedInstanceState.putInt(INSTANCE_STATE_CURRENT_INDEX, mCurrentIndex); 161 | 162 | super.onSaveInstanceState(savedInstanceState); 163 | } 164 | 165 | public abstract void onGalleryObjectsLoaded(List galleryObjects); 166 | 167 | public GalleryObject getDisplayedGallery() { 168 | try { 169 | return (GalleryObject) getIntent().getExtras().get(GalDroidApp.INTENT_EXTRA_DISPLAY_GALLERY); 170 | } catch (Exception e) { 171 | return null; 172 | } 173 | 174 | } 175 | 176 | public int getCurrentIndex() { 177 | return mCurrentIndex; 178 | } 179 | 180 | protected void setCurrentIndex(int index) { 181 | mCurrentIndex = index; 182 | } 183 | 184 | public boolean areGalleryObjectsAvailable() { 185 | return mGalleryObjects != null; 186 | } 187 | 188 | public GalleryLoaderTask getDownloadTask() { 189 | if (mDownloadTask != null) { 190 | return mDownloadTask.get(); 191 | } else { 192 | return null; 193 | } 194 | } 195 | 196 | public void showProgressBar(int textId) { 197 | mProgressDialog.setTitle(R.string.progress_title_load_gallery); 198 | mProgressDialog.setMax(100); 199 | mProgressDialog.setProgress(0); 200 | mProgressDialog.show(); 201 | } 202 | 203 | public void updateProgressBar(int current, int max) { 204 | mProgressDialog.setMax(max); 205 | mProgressDialog.setProgress(current); 206 | } 207 | 208 | public void dismissProgressBar() { 209 | mProgressDialog.dismiss(); 210 | } 211 | 212 | 213 | 214 | protected void callShareIntentActivity(File file) { 215 | ContentValues values = new ContentValues(2); 216 | values.put(MediaStore.Images.Media.MIME_TYPE, "image/png"); 217 | values.put(MediaStore.Images.Media.DATA, file.getAbsolutePath()); 218 | Uri uri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values); 219 | Intent intent = new Intent(Intent.ACTION_SEND); 220 | intent.setType("image/png"); 221 | intent.putExtra(Intent.EXTRA_STREAM, uri); 222 | intent = Intent.createChooser(intent, "Share Image"); 223 | this.startActivity(intent); 224 | } 225 | } 226 | -------------------------------------------------------------------------------- /src/de/raptor2101/GalDroid/Config/GalDroidPreference.java: -------------------------------------------------------------------------------- 1 | /* 2 | * GalDroid - a webgallery frontend for android 3 | * Copyright (C) 2011 Raptor 2101 [raptor2101@gmx.de] 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package de.raptor2101.GalDroid.Config; 20 | 21 | import java.io.File; 22 | import java.util.ArrayList; 23 | import java.util.List; 24 | 25 | import android.content.ContentValues; 26 | import android.content.Context; 27 | import android.database.Cursor; 28 | import android.database.sqlite.SQLiteDatabase; 29 | 30 | public class GalDroidPreference { 31 | private static String CONFIG_DB_NAME = "GalDroid.db"; 32 | private static String CONFIG_TABLE = "galleries"; 33 | private static String CACHE_TABLE = "cached_objects"; 34 | private static Context mContext; 35 | 36 | public static void Initialize(Context context) { 37 | if (mContext == null) { 38 | mContext = context; 39 | } 40 | } 41 | 42 | private static SQLiteDatabase createConnection() { 43 | SQLiteDatabase dataBase = mContext.openOrCreateDatabase(CONFIG_DB_NAME, Context.MODE_PRIVATE, null); 44 | dataBase.execSQL("CREATE TABLE IF NOT EXISTS " + CONFIG_TABLE + " (id integer primary key AUTOINCREMENT, name varchar(100) unique, type_name varchar(100), " 45 | + "root_link varchar(255), security_token varchar(255));"); 46 | dataBase.execSQL("CREATE TABLE IF NOT EXISTS " + CACHE_TABLE + " (hash varchar(31) primary key, lastAccessed bigint, size bigint);"); 47 | 48 | return dataBase; 49 | } 50 | 51 | public static List getGalleryNames() { 52 | 53 | synchronized (mContext) { 54 | SQLiteDatabase database = createConnection(); 55 | Cursor dbCursor = database.rawQuery("SELECT name FROM " + CONFIG_TABLE, null); 56 | List returnList = new ArrayList(dbCursor.getCount()); 57 | dbCursor.isBeforeFirst(); 58 | while (dbCursor.moveToNext()) { 59 | returnList.add(dbCursor.getString(0)); 60 | } 61 | dbCursor.close(); 62 | database.close(); 63 | return returnList; 64 | } 65 | } 66 | 67 | public static GalleryConfig getSetupByName(String name) { 68 | synchronized (mContext) { 69 | SQLiteDatabase database = createConnection(); 70 | Cursor dbCursor = database.rawQuery("SELECT id, type_name,root_link,security_token FROM " + CONFIG_TABLE, null); 71 | GalleryConfig returnValue = null; 72 | if (dbCursor.moveToFirst()) { 73 | returnValue = new GalleryConfig(dbCursor.getInt(0), name, dbCursor.getString(1), dbCursor.getString(2), dbCursor.getString(3)); 74 | } 75 | dbCursor.close(); 76 | database.close(); 77 | return returnValue; 78 | } 79 | } 80 | 81 | public static void StoreGallery(int id, String galleryName, String galleryType, String galleryLink, String securityToken) { 82 | synchronized (mContext) { 83 | SQLiteDatabase database = createConnection(); 84 | 85 | String[] selectionArgs = new String[] { String.format("%d", id) }; 86 | 87 | ContentValues values = new ContentValues(4); 88 | values.put("name", galleryName); 89 | values.put("type_name", galleryType); 90 | values.put("root_link", galleryLink); 91 | values.put("security_token", securityToken); 92 | int returnValue = database.update(CONFIG_TABLE, values, "id = @1", selectionArgs); 93 | 94 | if (returnValue == 0) { 95 | values.put("name", galleryName); 96 | values.put("type_name", galleryType); 97 | values.put("root_link", galleryLink); 98 | values.put("security_token", securityToken); 99 | database.insert(CONFIG_TABLE, null, values); 100 | } 101 | database.close(); 102 | } 103 | } 104 | 105 | public static void deleteGallery(String galleryName) { 106 | synchronized (mContext) { 107 | SQLiteDatabase database = createConnection(); 108 | String[] selectionArgs = new String[] { galleryName }; 109 | 110 | database.delete(CONFIG_TABLE, "name = @1", selectionArgs); 111 | database.close(); 112 | } 113 | 114 | } 115 | 116 | public static void accessCacheObject(String hash, long size) { 117 | synchronized (mContext) { 118 | SQLiteDatabase database = createConnection(); 119 | String[] selectionArgs = new String[] { hash }; 120 | 121 | ContentValues values = new ContentValues(3); 122 | values.put("lastAccessed", System.currentTimeMillis()); 123 | values.put("size", size); 124 | 125 | int returnValue = database.update(CACHE_TABLE, values, "hash = @1", selectionArgs); 126 | if (returnValue == 0) { 127 | values.put("hash", hash); 128 | database.insert(CACHE_TABLE, null, values); 129 | } 130 | database.close(); 131 | } 132 | } 133 | 134 | public static boolean cacheObjectExists(String hash) { 135 | boolean result; 136 | synchronized (mContext) { 137 | SQLiteDatabase database = createConnection(); 138 | String[] selectionArgs = new String[] { hash }; 139 | 140 | Cursor dbCursor = database.query(CACHE_TABLE, new String[] { "hash" }, "hash = @1", selectionArgs, null, null, null); 141 | result = dbCursor.getCount() == 1; 142 | dbCursor.close(); 143 | database.close(); 144 | } 145 | return result; 146 | } 147 | 148 | public static long getCacheSpaceNeeded() { 149 | synchronized (mContext) { 150 | SQLiteDatabase database = createConnection(); 151 | 152 | Cursor dbCursor = database.rawQuery("SELECT SUM(size) FROM " + CACHE_TABLE, null); 153 | long returnValue = -1; 154 | if (dbCursor.moveToFirst()) { 155 | returnValue = dbCursor.getLong(0); 156 | } 157 | dbCursor.close(); 158 | database.close(); 159 | return returnValue; 160 | } 161 | } 162 | 163 | public static List getCacheOjectsOrderedByAccessTime() { 164 | synchronized (mContext) { 165 | SQLiteDatabase database = createConnection(); 166 | 167 | Cursor dbCursor = database.query(CACHE_TABLE, new String[] { "hash" }, null, null, null, null, "lastAccessed desc"); 168 | List returnList = new ArrayList(dbCursor.getCount()); 169 | dbCursor.isBeforeFirst(); 170 | while (dbCursor.moveToNext()) { 171 | returnList.add(dbCursor.getString(0)); 172 | } 173 | dbCursor.close(); 174 | database.close(); 175 | return returnList; 176 | } 177 | } 178 | 179 | public static void deleteCacheObject(String hash) { 180 | synchronized (mContext) { 181 | SQLiteDatabase database = createConnection(); 182 | String[] selectionArgs = new String[] { hash }; 183 | 184 | database.delete(CACHE_TABLE, "hash = @1", selectionArgs); 185 | database.close(); 186 | } 187 | } 188 | 189 | public static GalDroidPreference GetAsyncAccess() { 190 | synchronized (mContext) { 191 | return new GalDroidPreference(createConnection()); 192 | } 193 | } 194 | 195 | private SQLiteDatabase mDbObject; 196 | 197 | private GalDroidPreference(SQLiteDatabase dbObject) { 198 | mDbObject = dbObject; 199 | } 200 | 201 | public void clearCacheTable() { 202 | mDbObject.delete(CACHE_TABLE, null, null); 203 | } 204 | 205 | public void insertCacheObject(File file) { 206 | ContentValues values = new ContentValues(3); 207 | values.put("hash", file.getName()); 208 | values.put("lastAccessed", file.lastModified()); 209 | values.put("size", file.length()); 210 | mDbObject.insert(CACHE_TABLE, null, values); 211 | } 212 | 213 | @Override 214 | protected void finalize() throws Throwable { 215 | if (mDbObject != null) { 216 | close(); 217 | } 218 | } 219 | 220 | public void close() { 221 | mDbObject.close(); 222 | mDbObject = null; 223 | } 224 | } 225 | -------------------------------------------------------------------------------- /src/de/raptor2101/GalDroid/Activities/GridViewActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * GalDroid - a webgallery frontend for android 3 | * Copyright (C) 2011 Raptor 2101 [raptor2101@gmx.de] 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package de.raptor2101.GalDroid.Activities; 20 | 21 | import java.io.File; 22 | import java.util.List; 23 | 24 | import android.app.ActionBar; 25 | import android.content.Intent; 26 | import android.graphics.Bitmap; 27 | import android.net.Uri; 28 | import android.os.Bundle; 29 | import android.util.DisplayMetrics; 30 | import android.view.ContextMenu; 31 | import android.view.MenuInflater; 32 | import android.view.MenuItem; 33 | import android.view.View; 34 | import android.view.Window; 35 | import android.view.ContextMenu.ContextMenuInfo; 36 | import android.widget.AdapterView; 37 | import android.widget.AdapterView.AdapterContextMenuInfo; 38 | import android.widget.AdapterView.OnItemClickListener; 39 | import android.widget.GridView; 40 | import de.raptor2101.GalDroid.R; 41 | import de.raptor2101.GalDroid.Activities.Helpers.ImageAdapter; 42 | import de.raptor2101.GalDroid.Activities.Helpers.ImageAdapter.ScaleMode; 43 | import de.raptor2101.GalDroid.Activities.Helpers.ImageAdapter.TitleConfig; 44 | import de.raptor2101.GalDroid.Activities.Views.GalleryImageView; 45 | 46 | import de.raptor2101.GalDroid.WebGallery.ImageCache; 47 | import de.raptor2101.GalDroid.WebGallery.Interfaces.GalleryDownloadObject; 48 | import de.raptor2101.GalDroid.WebGallery.Interfaces.GalleryObject; 49 | import de.raptor2101.GalDroid.WebGallery.Tasks.ImageLoaderTask; 50 | import de.raptor2101.GalDroid.WebGallery.Tasks.ImageLoaderTaskListener; 51 | 52 | public class GridViewActivity extends GalleryActivity implements OnItemClickListener, ImageLoaderTaskListener { 53 | 54 | private static final int CURRENT_INDEX = 0; 55 | private GridView mGridView; 56 | private ImageAdapter mAdapter; 57 | private ImageLoaderTask mImageLoaderTask; 58 | 59 | @Override 60 | public void onCreate(Bundle savedInstanceState) { 61 | requestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY); 62 | super.onCreate(savedInstanceState); 63 | setContentView(R.layout.grid_view_activity); 64 | ActionBar actionBar = getActionBar(); 65 | actionBar.setDisplayShowHomeEnabled(false); 66 | actionBar.setDisplayShowTitleEnabled(false); 67 | actionBar.hide(); 68 | 69 | mGridView = (GridView) findViewById(R.id.gridViewWidget); 70 | mGridView.setOnItemClickListener(this); 71 | 72 | GalDroidApp app = (GalDroidApp) getApplicationContext(); 73 | 74 | DisplayMetrics metrics = new DisplayMetrics(); 75 | getWindowManager().getDefaultDisplay().getMetrics(metrics); 76 | 77 | int colums = metrics.widthPixels / 295; 78 | int rows = metrics.heightPixels /295; 79 | 80 | mImageLoaderTask = new ImageLoaderTask(app.getWebGallery(), app.getImageCache(), (int)(rows*colums*1.5)); 81 | mAdapter = new ImageAdapter(this, new GridView.LayoutParams(295, 295), ScaleMode.ScaleSource, mImageLoaderTask); 82 | mAdapter.setTitleConfig(TitleConfig.ShowTitle); 83 | 84 | mGridView.setAdapter(mAdapter); 85 | 86 | registerForContextMenu(mGridView); 87 | } 88 | 89 | @Override 90 | public void onBackPressed() { 91 | mAdapter.cleanUp(); 92 | super.onBackPressed(); 93 | } 94 | 95 | @Override 96 | public void onActivityResult(int requestCode, int resultCode, Intent data) { 97 | super.onActivityResult(requestCode, resultCode, data); 98 | switch (requestCode) { 99 | case (CURRENT_INDEX): { 100 | 101 | int scrollPos = data.getIntExtra(GalDroidApp.INTENT_EXTRA_DISPLAY_INDEX, -1); 102 | mGridView.smoothScrollToPositionFromTop(scrollPos, 600); 103 | 104 | break; 105 | } 106 | } 107 | } 108 | 109 | public void onItemClick(AdapterView parent, View view, int pos, long rowId) { 110 | GalleryImageView imageView = (GalleryImageView) view; 111 | GalleryObject galleryObject = imageView.getGalleryObject(); 112 | 113 | Intent intent; 114 | if (!galleryObject.hasChildren()) { 115 | intent = new Intent(this, ImageViewActivity.class); 116 | intent.putExtra(GalDroidApp.INTENT_EXTRA_DISPLAY_GALLERY, getDisplayedGallery()); 117 | intent.putExtra(GalDroidApp.INTENT_EXTRA_DISPLAY_OBJECT, galleryObject); 118 | // The startActivityForResult is needed to scroll to the last 119 | // disyplayed imaged from the ImageView 120 | // The Result is handled by onActivityResult 121 | this.startActivityForResult(intent, CURRENT_INDEX); 122 | } else { 123 | intent = new Intent(this, GridViewActivity.class); 124 | intent.putExtra(GalDroidApp.INTENT_EXTRA_DISPLAY_GALLERY, galleryObject); 125 | this.startActivity(intent); 126 | } 127 | 128 | } 129 | 130 | public void onGalleryObjectsLoaded(List galleryObjects) { 131 | mAdapter.setGalleryObjects(galleryObjects); 132 | mImageLoaderTask.start(); 133 | } 134 | 135 | @Override 136 | public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { 137 | MenuInflater inflater = getMenuInflater(); 138 | inflater.inflate(R.menu.grid_view_context_menu, menu); 139 | } 140 | 141 | @Override 142 | public boolean onContextItemSelected(MenuItem item) { 143 | AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo(); 144 | GalleryImageView imageView = (GalleryImageView) info.targetView; 145 | 146 | 147 | switch (item.getItemId()){ 148 | case R.id.item_additional_info_object: 149 | callAdditionalInfoActivity(imageView); 150 | break; 151 | case R.id.item_additional_share_object: 152 | callShareIntentActivity(imageView); 153 | break; 154 | } 155 | 156 | 157 | return true; 158 | } 159 | 160 | private void callShareIntentActivity(GalleryImageView imageView) { 161 | 162 | 163 | GalDroidApp app = (GalDroidApp) getApplicationContext(); 164 | ImageCache cache = app.getImageCache(); 165 | 166 | 167 | GalleryDownloadObject image = imageView.getGalleryObject().getImage(); 168 | File file = cache.getFile(image.getUniqueId()); 169 | if (file.exists()) { 170 | callShareIntentActivity(file); 171 | } else { 172 | mImageLoaderTask.download(image, null, this); 173 | } 174 | } 175 | 176 | private void callAdditionalInfoActivity(GalleryImageView imageView) { 177 | Intent intent = null; 178 | intent = new Intent(this, ImageViewActivity.class); 179 | intent.putExtra(GalDroidApp.INTENT_EXTRA_DISPLAY_GALLERY, getDisplayedGallery()); 180 | intent.putExtra(GalDroidApp.INTENT_EXTRA_DISPLAY_OBJECT, imageView.getGalleryObject()); 181 | intent.putExtra(GalDroidApp.INTENT_EXTRA_SHOW_IMAGE_INFO, true); 182 | this.startActivity(intent); 183 | } 184 | 185 | @Override 186 | protected void onResume() { 187 | super.onResume(); 188 | 189 | ImageAdapter adapter = (ImageAdapter) mGridView.getAdapter(); 190 | if (adapter != null) { 191 | adapter.refreshImages(); 192 | } 193 | 194 | mImageLoaderTask.start(); 195 | } 196 | 197 | protected void onPause() { 198 | super.onPause(); 199 | 200 | try { 201 | mImageLoaderTask.stop(false); 202 | } catch (InterruptedException e) { 203 | 204 | } 205 | } 206 | 207 | @Override 208 | protected void onStop() { 209 | super.onStop(); 210 | 211 | try { 212 | mImageLoaderTask.cancel(true); 213 | } catch (InterruptedException e) { 214 | 215 | } 216 | 217 | mAdapter.cleanUp(); 218 | } 219 | 220 | public void onLoadingStarted(String uniqueId) { 221 | showProgressBar(R.string.progress_title_load_image); 222 | } 223 | 224 | public void onLoadingProgress(String uniqueId, int currentValue, int maxValue) { 225 | 226 | updateProgressBar(currentValue, maxValue); 227 | 228 | } 229 | 230 | public void onLoadingCompleted(String uniqueId, Bitmap bitmap) { 231 | GalDroidApp app = (GalDroidApp) getApplicationContext(); 232 | ImageCache cache = app.getImageCache(); 233 | 234 | File file = cache.getFile(uniqueId); 235 | if (file.exists()) { 236 | callShareIntentActivity(file); 237 | } 238 | 239 | dismissProgressBar(); 240 | } 241 | 242 | public void onLoadingCancelled(String uniqueId) { 243 | dismissProgressBar(); 244 | } 245 | } -------------------------------------------------------------------------------- /src/de/raptor2101/GalDroid/WebGallery/Tasks/ImageInformationLoaderTask.java: -------------------------------------------------------------------------------- 1 | package de.raptor2101.GalDroid.WebGallery.Tasks; 2 | 3 | import java.io.File; 4 | import java.lang.ref.WeakReference; 5 | import java.util.List; 6 | 7 | import android.media.ExifInterface; 8 | import android.os.Handler; 9 | import android.os.Message; 10 | import android.util.Log; 11 | import de.raptor2101.GalDroid.WebGallery.DegMinSec; 12 | import de.raptor2101.GalDroid.WebGallery.ImageCache; 13 | import de.raptor2101.GalDroid.WebGallery.ImageInformation; 14 | import de.raptor2101.GalDroid.WebGallery.ImageInformation.WhiteBalance; 15 | import de.raptor2101.GalDroid.WebGallery.Interfaces.GalleryObject; 16 | import de.raptor2101.GalDroid.WebGallery.Interfaces.GalleryObjectComment; 17 | import de.raptor2101.GalDroid.WebGallery.Interfaces.WebGallery; 18 | 19 | public class ImageInformationLoaderTask extends RepeatingTask { 20 | private final static String CLASS_TAG = "ImageInformationLoaderTask"; 21 | public static final int MESSAGE_IMAGE_INFORMATION = 0; 22 | public static final int MESSAGE_IMAGE_TAGS = 1; 23 | public static final int MESSAGE_IMAGE_COMMENTS = 2; 24 | 25 | private class MessageBody { 26 | public final GalleryObject mGalleryObject; 27 | public final Object mObject; 28 | 29 | public MessageBody(GalleryObject galleryObject, Object object) { 30 | mGalleryObject = galleryObject; 31 | mObject = object; 32 | } 33 | } 34 | 35 | private class InternHandler extends Handler { 36 | @SuppressWarnings("unchecked") 37 | @Override 38 | public void handleMessage(Message msg) { 39 | ImageInformationLoaderTaskListener listener = mListener.get(); 40 | MessageBody messsage = (MessageBody) msg.obj; 41 | if (listener != null) { 42 | switch (msg.what) { 43 | case ImageInformationLoaderTask.MESSAGE_IMAGE_INFORMATION: 44 | listener.onImageInformationLoaded(messsage.mGalleryObject, (ImageInformation) messsage.mObject); 45 | 46 | break; 47 | case ImageInformationLoaderTask.MESSAGE_IMAGE_COMMENTS: 48 | listener.onImageCommetsLoaded(messsage.mGalleryObject, (List) messsage.mObject); 49 | break; 50 | 51 | case ImageInformationLoaderTask.MESSAGE_IMAGE_TAGS: 52 | listener.onImageTagsLoaded(messsage.mGalleryObject, (List) messsage.mObject); 53 | break; 54 | 55 | } 56 | } 57 | } 58 | } 59 | 60 | private final InternHandler mResponseHandler = new InternHandler(); 61 | private final WebGallery mWebGallery; 62 | private final ImageCache mCache; 63 | private final WeakReference mListener; 64 | 65 | public ImageInformationLoaderTask(ImageInformationLoaderTaskListener listener, WebGallery webGallery, ImageCache cache) { 66 | super(1); 67 | mThreadName = "ImageInformationLoaderTask"; 68 | mListener = new WeakReference(listener); 69 | mWebGallery = webGallery; 70 | mCache = cache; 71 | } 72 | 73 | public void load(GalleryObject galleryObject) { 74 | if (galleryObject == null) { 75 | return; 76 | } 77 | Log.d(CLASS_TAG, String.format("enqueuing %s for loading of ImageInformations", galleryObject)); 78 | enqueueTask(galleryObject); 79 | } 80 | 81 | @Override 82 | protected Void doInBackground(GalleryObject galleryObject) { 83 | ImageInformation imageInformation = loadImageInformations(galleryObject); 84 | 85 | Message message = mResponseHandler.obtainMessage(MESSAGE_IMAGE_INFORMATION, new MessageBody(galleryObject, imageInformation)); 86 | message.sendToTarget(); 87 | 88 | if (!isCancelled()) { 89 | try { 90 | Log.d(CLASS_TAG, String.format("Try to load tags for %s", galleryObject)); 91 | 92 | List tags = mWebGallery.getDisplayObjectTags(galleryObject, null); 93 | 94 | message = mResponseHandler.obtainMessage(MESSAGE_IMAGE_TAGS, new MessageBody(galleryObject, tags)); 95 | message.sendToTarget(); 96 | } catch (Exception e) { 97 | Log.e(CLASS_TAG, String.format("Something goes wrong while loading tags for %s", galleryObject), e); 98 | } 99 | } 100 | 101 | if (!isCancelled()) { 102 | try { 103 | Log.d(CLASS_TAG, String.format("Try to load comments for %s", galleryObject)); 104 | List comments = mWebGallery.getDisplayObjectComments(galleryObject, null); 105 | 106 | message = mResponseHandler.obtainMessage(MESSAGE_IMAGE_COMMENTS, new MessageBody(galleryObject, comments)); 107 | message.sendToTarget(); 108 | } catch (Exception e) { 109 | Log.e(CLASS_TAG, String.format("Something goes wrong while comments tags for %s", galleryObject), e); 110 | } 111 | } 112 | 113 | return null; 114 | } 115 | 116 | private ImageInformation loadImageInformations(GalleryObject galleryObject) { 117 | ImageInformation imageInformation = new ImageInformation(); 118 | 119 | imageInformation.mTitle = galleryObject.getTitle(); 120 | imageInformation.mUploadDate = galleryObject.getDateUploaded(); 121 | 122 | File cachedFile = mCache.getFile(galleryObject.getImage().getUniqueId()); 123 | try { 124 | Log.d(CLASS_TAG, String.format("Try to decoding ExifInformations from %s", galleryObject)); 125 | ExifInterface exif = new ExifInterface(cachedFile.getAbsolutePath()); 126 | 127 | imageInformation.mExifCreateDate = exif.getAttribute(ExifInterface.TAG_DATETIME); 128 | imageInformation.mExifAperture = exif.getAttribute(ExifInterface.TAG_APERTURE); 129 | imageInformation.mExifIso = exif.getAttribute(ExifInterface.TAG_ISO); 130 | imageInformation.mExifModel = exif.getAttribute(ExifInterface.TAG_MODEL); 131 | imageInformation.mExifMake = exif.getAttribute(ExifInterface.TAG_MAKE); 132 | 133 | try { 134 | imageInformation.mExifExposure = 1.0f / Float.parseFloat(exif.getAttribute(ExifInterface.TAG_EXPOSURE_TIME)); 135 | 136 | } catch (Exception e) { 137 | imageInformation.mExifExposure = 0f; 138 | } 139 | 140 | try { 141 | imageInformation.mExifFlash = exif.getAttributeInt(ExifInterface.TAG_FLASH, 0); 142 | } catch (Exception e) { 143 | imageInformation.mExifFlash = 0; 144 | } 145 | 146 | try { 147 | imageInformation.mExifFocalLength = exif.getAttributeDouble(ExifInterface.TAG_FOCAL_LENGTH, 0); 148 | } catch (Exception e) { 149 | imageInformation.mExifFocalLength = 0; 150 | } 151 | 152 | try { 153 | int whiteBalance = exif.getAttributeInt(ExifInterface.TAG_WHITE_BALANCE, 0); 154 | if (whiteBalance == ExifInterface.WHITEBALANCE_AUTO) { 155 | imageInformation.mExifWhiteBalance = WhiteBalance.Auto; 156 | } else { 157 | imageInformation.mExifWhiteBalance = WhiteBalance.Manual; 158 | } 159 | } catch (Exception e) { 160 | imageInformation.mExifWhiteBalance = WhiteBalance.Manual; 161 | } 162 | 163 | imageInformation.mExifGpsAvailable = exif.getAttribute(ExifInterface.TAG_GPS_ALTITUDE_REF) != null; 164 | imageInformation.mExifGpsLat = parseDegMinSec(exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE)); 165 | imageInformation.mExifGpsLong = parseDegMinSec(exif.getAttribute(ExifInterface.TAG_GPS_LONGITUDE)); 166 | imageInformation.mExifHeight = parseHeight(exif.getAttribute(ExifInterface.TAG_GPS_ALTITUDE)); 167 | } catch (Exception e) { 168 | Log.e(CLASS_TAG, String.format("Something goes wrong while decoding ExifInformations from %s", galleryObject), e); 169 | } 170 | return imageInformation; 171 | } 172 | 173 | private float parseHeight(String tagGpsValue) { 174 | try { 175 | String[] values = tagGpsValue.split("/"); 176 | return Float.parseFloat(values[0]) / Float.parseFloat(values[1]); 177 | } catch (Exception e) { 178 | return 0; 179 | } 180 | } 181 | 182 | private DegMinSec parseDegMinSec(String gpsValue) { 183 | try { 184 | String[] values = gpsValue.split("[,/]"); 185 | float deg = Float.parseFloat(values[0]) / Float.parseFloat(values[1]); 186 | float min = Float.parseFloat(values[2]) / Float.parseFloat(values[3]); 187 | float sec = Float.parseFloat(values[4]) / Float.parseFloat(values[5]); 188 | return new DegMinSec(deg, min, sec); 189 | } catch (Exception e) { 190 | return new DegMinSec(0, 0, 0); 191 | } 192 | } 193 | 194 | @Override 195 | protected void onPostExecute(GalleryObject galleryObject, Void result) { 196 | // TODO Auto-generated method stub 197 | 198 | } 199 | 200 | public boolean isLoading(GalleryObject galleryObject) { 201 | boolean isActive = isActive(galleryObject); 202 | boolean isEnqueued = isEnqueued(galleryObject); 203 | Log.d(CLASS_TAG, String.format("isActive: %s isEnqueued %s", isActive, isEnqueued)); 204 | return isActive || isEnqueued; 205 | } 206 | 207 | public void cancel(GalleryObject galleryObject, boolean waitForCancel) throws InterruptedException { 208 | if (isEnqueued(galleryObject)) { 209 | removeEnqueuedTask(galleryObject); 210 | } else if (isActive(galleryObject)) { 211 | cancelCurrentTask(waitForCancel); 212 | } 213 | } 214 | } -------------------------------------------------------------------------------- /src/de/raptor2101/GalDroid/Activities/Helpers/ImageAdapter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * GalDroid - a webgallery frontend for android 3 | * Copyright (C) 2011 Raptor 2101 [raptor2101@gmx.de] 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package de.raptor2101.GalDroid.Activities.Helpers; 20 | 21 | import java.lang.ref.WeakReference; 22 | import java.util.ArrayList; 23 | import java.util.List; 24 | 25 | import android.content.Context; 26 | import android.graphics.Bitmap; 27 | import android.util.Log; 28 | import android.view.View; 29 | import android.view.ViewGroup; 30 | import android.view.ViewGroup.LayoutParams; 31 | import android.widget.BaseAdapter; 32 | import de.raptor2101.GalDroid.Activities.GalDroidApp; 33 | import de.raptor2101.GalDroid.Activities.Views.GalleryImageView; 34 | import de.raptor2101.GalDroid.Activities.Views.GalleryImageViewListener; 35 | import de.raptor2101.GalDroid.WebGallery.ImageCache; 36 | import de.raptor2101.GalDroid.WebGallery.Interfaces.GalleryDownloadObject; 37 | import de.raptor2101.GalDroid.WebGallery.Interfaces.GalleryObject; 38 | import de.raptor2101.GalDroid.WebGallery.Interfaces.WebGallery.ImageSize; 39 | import de.raptor2101.GalDroid.WebGallery.Tasks.ImageLoaderTask; 40 | import de.raptor2101.GalDroid.WebGallery.Tasks.ImageLoaderTask.ImageDownload; 41 | 42 | public class ImageAdapter extends BaseAdapter { 43 | private final static String ClassTag = "GalleryImageAdapter"; 44 | 45 | public enum DisplayTarget { 46 | Thumbnails, FullScreen 47 | } 48 | 49 | public enum TitleConfig { 50 | ShowTitle, HideTitle 51 | } 52 | 53 | public enum ScaleMode { 54 | ScaleSource, DontScale 55 | } 56 | 57 | // private WebGallery mWebGallery; 58 | private ImageCache mCache; 59 | private Context mContext; 60 | 61 | private List mGalleryObjects; 62 | private TitleConfig mTitleConfig; 63 | private LayoutParams mLayoutParams; 64 | private ScaleMode mScaleMode; 65 | private ImageSize mImageSize; 66 | 67 | private WeakReference mListener; 68 | private ArrayList> mImageViews; 69 | 70 | private ImageLoaderTask mImageLoaderTask; 71 | 72 | public ImageAdapter(Context context, LayoutParams layoutParams, ScaleMode scaleMode, ImageLoaderTask loaderTask) { 73 | super(); 74 | GalDroidApp appContext = (GalDroidApp) context.getApplicationContext(); 75 | mContext = context; 76 | mCache = appContext.getImageCache(); 77 | 78 | mGalleryObjects = new ArrayList(0); 79 | mImageViews = new ArrayList>(0); 80 | 81 | mTitleConfig = TitleConfig.ShowTitle; 82 | mImageSize = ImageSize.Thumbnail; 83 | mScaleMode = scaleMode; 84 | mLayoutParams = layoutParams; 85 | 86 | mListener = new WeakReference(null); 87 | mImageLoaderTask = loaderTask; 88 | } 89 | 90 | public void setListener(GalleryImageViewListener listener) { 91 | mListener = new WeakReference(listener); 92 | } 93 | 94 | public void setGalleryObjects(List galleryObjects) { 95 | if (isLoaded()) { 96 | cleanUp(); 97 | } 98 | this.mGalleryObjects = galleryObjects; 99 | this.mImageViews = new ArrayList>(galleryObjects.size()); 100 | 101 | for (int i = 0; i < galleryObjects.size(); i++) { 102 | mImageViews.add(new WeakReference(null)); 103 | } 104 | 105 | notifyDataSetChanged(); 106 | } 107 | 108 | public void setTitleConfig(TitleConfig titleConfig) { 109 | this.mTitleConfig = titleConfig; 110 | } 111 | 112 | public void setDisplayTarget(DisplayTarget displayTarget) { 113 | mImageSize = displayTarget == DisplayTarget.FullScreen ? ImageSize.Full : ImageSize.Thumbnail; 114 | } 115 | 116 | public List getGalleryObjects() { 117 | return mGalleryObjects; 118 | } 119 | 120 | public int getCount() { 121 | 122 | return mGalleryObjects.size(); 123 | } 124 | 125 | public Object getItem(int position) { 126 | return mGalleryObjects.get(position); 127 | } 128 | 129 | public long getItemId(int position) { 130 | return position; 131 | } 132 | 133 | public View getView(int position, View cachedView, ViewGroup parent) { 134 | GalleryObject galleryObject = mGalleryObjects.get(position); 135 | 136 | String objectId = galleryObject.getObjectId(); 137 | Log.d(ClassTag, String.format("Request Pos %s View %s", position, objectId)); 138 | 139 | GalleryImageView imageView = getCachedView(cachedView, galleryObject); 140 | 141 | imageView = mImageViews.get(position).get(); 142 | if (imageView == null) { 143 | Log.d(ClassTag, String.format("Miss ImageView Reference", objectId)); 144 | imageView = CreateImageView(galleryObject); 145 | mImageViews.set(position, new WeakReference(imageView)); 146 | } 147 | 148 | GalleryDownloadObject downloadObject = getDownloadObject(galleryObject); 149 | boolean isLoading = imageView.isLoading(); 150 | Log.d(ClassTag, String.format("%s isLoaded: %s", objectId, isLoading)); 151 | if (!isLoading) { 152 | Log.d(ClassTag, String.format("Init Reload", galleryObject.getObjectId())); 153 | loadGalleryImage(imageView, downloadObject); 154 | } 155 | 156 | return imageView; 157 | } 158 | 159 | private GalleryDownloadObject getDownloadObject(GalleryObject galleryObject) { 160 | GalleryDownloadObject downloadObject = mImageSize == ImageSize.Full ? galleryObject.getImage() : galleryObject.getThumbnail(); 161 | return downloadObject; 162 | } 163 | 164 | private GalleryImageView CreateImageView(GalleryObject galleryObject) { 165 | GalleryImageView imageView; 166 | imageView = new GalleryImageView(mContext, this.mTitleConfig == TitleConfig.ShowTitle); 167 | imageView.setLayoutParams(mLayoutParams); 168 | imageView.setGalleryObject(galleryObject); 169 | imageView.setListener(mListener.get()); 170 | return imageView; 171 | } 172 | 173 | private GalleryImageView getCachedView(View cachedView, GalleryObject galleryObject) { 174 | GalleryImageView imageView = null; 175 | if (cachedView != null) { 176 | imageView = (GalleryImageView) cachedView; 177 | GalleryObject originGalleryObject = imageView.getGalleryObject(); 178 | boolean equalsObject = originGalleryObject.getObjectId().equals(galleryObject.getObjectId()); 179 | boolean isLoaded = imageView.isLoaded(); 180 | Log.d(ClassTag, String.format("Cached View %s, GalleryObjectEquals %s, isLoaded %s", imageView.getObjectId(), equalsObject, isLoaded)); 181 | if (!equalsObject) { 182 | if (!isLoaded) { 183 | Log.d(ClassTag, String.format("Abort downloadTask %s", imageView.getObjectId())); 184 | try { 185 | mImageLoaderTask.cancel(getDownloadObject(originGalleryObject), false); 186 | } catch (InterruptedException e) { 187 | // nothing to do here... 188 | } 189 | } 190 | } 191 | } 192 | return imageView; 193 | } 194 | 195 | private void loadGalleryImage(GalleryImageView imageView, GalleryDownloadObject downloadObject) { 196 | if (downloadObject == null) { 197 | imageView.resetLoading(); 198 | return; 199 | } 200 | 201 | Bitmap cachedBitmap = mCache.getBitmap(downloadObject.getUniqueId()); 202 | if (cachedBitmap == null) { 203 | ImageDownload imageDownload = imageView.getImageDownload(); 204 | if(imageDownload != null) { 205 | imageDownload.updateListener(null); 206 | } 207 | LayoutParams layoutParams = mScaleMode == ScaleMode.ScaleSource ? mLayoutParams : null; 208 | imageDownload = mImageLoaderTask.download(downloadObject, layoutParams, imageView); 209 | imageView.setImageDownload(imageDownload); 210 | 211 | } else { 212 | imageView.onLoadingCompleted(downloadObject.getUniqueId(), cachedBitmap); 213 | } 214 | } 215 | 216 | public void cleanUp() { 217 | Log.d(ClassTag, String.format("CleanUp")); 218 | for (WeakReference reference : mImageViews) { 219 | GalleryImageView imageView = reference.get(); 220 | if (imageView != null) { 221 | Log.d(ClassTag, String.format("CleanUp ", imageView.getObjectId())); 222 | imageView.cleanup(); 223 | } 224 | } 225 | System.gc(); 226 | } 227 | 228 | public void refreshImages() { 229 | for (WeakReference reference : mImageViews) { 230 | GalleryImageView imageView = reference.get(); 231 | if (imageView != null && !imageView.isLoaded()) { 232 | GalleryObject galleryObject = imageView.getGalleryObject(); 233 | Log.d(ClassTag, String.format("Relaod ", imageView.getObjectId())); 234 | GalleryDownloadObject downloadObject = getDownloadObject(galleryObject); 235 | loadGalleryImage(imageView, downloadObject); 236 | } 237 | } 238 | } 239 | 240 | public boolean isLoaded() { 241 | return mGalleryObjects.size() != 0; 242 | } 243 | 244 | public ImageLoaderTask getImageLoaderTask() { 245 | return mImageLoaderTask; 246 | } 247 | } 248 | -------------------------------------------------------------------------------- /src/de/raptor2101/GalDroid/Activities/ImageViewActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * GalDroid - a webgallery frontend for android 3 | * Copyright (C) 2011 Raptor 2101 [raptor2101@gmx.de] 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package de.raptor2101.GalDroid.Activities; 20 | 21 | import java.util.List; 22 | 23 | import android.app.ActionBar; 24 | import android.app.Activity; 25 | import android.content.Intent; 26 | import android.os.Bundle; 27 | import android.util.DisplayMetrics; 28 | import android.view.Menu; 29 | import android.view.MenuInflater; 30 | import android.view.MenuItem; 31 | import android.view.View; 32 | import android.view.Window; 33 | import android.widget.AdapterView; 34 | import android.widget.AdapterView.OnItemClickListener; 35 | import android.widget.AdapterView.OnItemSelectedListener; 36 | import android.widget.Gallery; 37 | import de.raptor2101.GalDroid.R; 38 | import de.raptor2101.GalDroid.Activities.Helpers.ActionBarHider; 39 | import de.raptor2101.GalDroid.Activities.Helpers.ImageAdapter; 40 | import de.raptor2101.GalDroid.Activities.Helpers.ImageAdapter.DisplayTarget; 41 | import de.raptor2101.GalDroid.Activities.Helpers.ImageAdapter.ScaleMode; 42 | import de.raptor2101.GalDroid.Activities.Helpers.ImageAdapter.TitleConfig; 43 | import de.raptor2101.GalDroid.Activities.Listeners.ImageViewOnTouchListener; 44 | import de.raptor2101.GalDroid.Activities.Views.GalleryImageView; 45 | import de.raptor2101.GalDroid.Activities.Views.ImageInformationView; 46 | import de.raptor2101.GalDroid.WebGallery.ImageCache; 47 | import de.raptor2101.GalDroid.WebGallery.Interfaces.GalleryObject; 48 | import de.raptor2101.GalDroid.WebGallery.Interfaces.WebGallery; 49 | import de.raptor2101.GalDroid.WebGallery.Tasks.ImageLoaderTask; 50 | 51 | public class ImageViewActivity extends GalleryActivity implements OnItemSelectedListener, OnItemClickListener { 52 | 53 | private Gallery mGalleryFullscreen; 54 | private Gallery mGalleryThumbnails; 55 | 56 | private ImageAdapter mAdapterFullscreen, mAdapterThumbnails; 57 | 58 | private ImageInformationView mInformationView; 59 | 60 | private ActionBarHider mActionBarHider; 61 | 62 | private ImageLoaderTask mFullscrennImageLoaderTask; 63 | private ImageLoaderTask mThumbnailImageLoaderTask; 64 | 65 | @Override 66 | public void onCreate(Bundle savedInstanceState) { 67 | requestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY); 68 | 69 | setContentView(R.layout.image_view_activity); 70 | super.onCreate(savedInstanceState); 71 | 72 | ActionBar actionBar = getActionBar(); 73 | 74 | actionBar.setDisplayShowHomeEnabled(false); 75 | actionBar.setDisplayShowTitleEnabled(false); 76 | actionBar.hide(); 77 | mActionBarHider = new ActionBarHider(actionBar); 78 | 79 | GalDroidApp app = (GalDroidApp) getApplication(); 80 | 81 | WebGallery webGallery = app.getWebGallery(); 82 | ImageCache imageCache = app.getImageCache(); 83 | 84 | mInformationView = (ImageInformationView) findViewById(R.id.viewImageInformations); 85 | boolean showInfo = getIntent().getExtras().getBoolean(GalDroidApp.INTENT_EXTRA_SHOW_IMAGE_INFO); 86 | if (showInfo) { 87 | mInformationView.setVisibility(View.VISIBLE); 88 | } else { 89 | mInformationView.setVisibility(View.GONE); 90 | } 91 | mInformationView.initialize(); 92 | 93 | DisplayMetrics metrics = new DisplayMetrics(); 94 | getWindowManager().getDefaultDisplay().getMetrics(metrics); 95 | 96 | mGalleryFullscreen = (Gallery) findViewById(R.id.singleImageGallery); 97 | mGalleryThumbnails = (Gallery) findViewById(R.id.thumbnailImageGallery); 98 | 99 | mFullscrennImageLoaderTask = new ImageLoaderTask(webGallery, imageCache, 5); 100 | mThumbnailImageLoaderTask = new ImageLoaderTask(webGallery, imageCache, (int) ((metrics.widthPixels / 100) * 1.5)); 101 | 102 | mGalleryThumbnails.setWillNotCacheDrawing(true); 103 | 104 | ImageViewOnTouchListener touchListener = new ImageViewOnTouchListener(mGalleryFullscreen, mGalleryThumbnails, metrics.heightPixels / 5f); 105 | 106 | mAdapterFullscreen = new ImageAdapter(this, new Gallery.LayoutParams(metrics.widthPixels, metrics.heightPixels), ScaleMode.ScaleSource, mFullscrennImageLoaderTask); 107 | mAdapterFullscreen.setTitleConfig(TitleConfig.HideTitle); 108 | mAdapterFullscreen.setDisplayTarget(DisplayTarget.FullScreen); 109 | 110 | mAdapterThumbnails = new ImageAdapter(this, new Gallery.LayoutParams(100, 100), ScaleMode.DontScale, mThumbnailImageLoaderTask); 111 | mAdapterThumbnails.setTitleConfig(TitleConfig.HideTitle); 112 | mAdapterThumbnails.setDisplayTarget(DisplayTarget.Thumbnails); 113 | 114 | mGalleryFullscreen.setAdapter(mAdapterFullscreen); 115 | mGalleryThumbnails.setAdapter(mAdapterThumbnails); 116 | 117 | mGalleryFullscreen.setOnItemClickListener(this); 118 | mGalleryFullscreen.setOnTouchListener(touchListener); 119 | mGalleryFullscreen.setOnItemSelectedListener(this); 120 | mGalleryThumbnails.setOnItemSelectedListener(this); 121 | } 122 | 123 | @Override 124 | public void onBackPressed() { 125 | ImageAdapter adapter = (ImageAdapter) mGalleryFullscreen.getAdapter(); 126 | adapter.cleanUp(); 127 | 128 | Intent resultIntent = new Intent(this, ImageViewActivity.class); 129 | resultIntent.putExtra(GalDroidApp.INTENT_EXTRA_DISPLAY_INDEX, getCurrentIndex()); 130 | setResult(Activity.RESULT_OK, resultIntent); 131 | 132 | super.onBackPressed(); 133 | } 134 | 135 | @Override 136 | protected void onResume() { 137 | super.onResume(); 138 | 139 | ImageAdapter adapter = (ImageAdapter) mGalleryFullscreen.getAdapter(); 140 | if (adapter != null) { 141 | adapter.refreshImages(); 142 | } 143 | 144 | adapter = (ImageAdapter) mGalleryThumbnails.getAdapter(); 145 | if (adapter != null) { 146 | adapter.refreshImages(); 147 | } 148 | 149 | mFullscrennImageLoaderTask.start(); 150 | mThumbnailImageLoaderTask.start(); 151 | } 152 | 153 | @Override 154 | protected void onPause() { 155 | super.onPause(); 156 | 157 | try { 158 | mFullscrennImageLoaderTask.stop(false); 159 | mThumbnailImageLoaderTask.stop(false); 160 | } catch (InterruptedException e) { 161 | 162 | } 163 | } 164 | 165 | @Override 166 | protected void onStop() { 167 | super.onStop(); 168 | 169 | try { 170 | mFullscrennImageLoaderTask.cancel(true); 171 | mThumbnailImageLoaderTask.cancel(true); 172 | } catch (InterruptedException e) { 173 | 174 | } 175 | 176 | ImageAdapter adapter = (ImageAdapter) mGalleryFullscreen.getAdapter(); 177 | adapter.cleanUp(); 178 | adapter = (ImageAdapter) mGalleryThumbnails.getAdapter(); 179 | adapter.cleanUp(); 180 | } 181 | 182 | @Override 183 | public boolean onCreateOptionsMenu(Menu menu) { 184 | MenuInflater inflater = getMenuInflater(); 185 | inflater.inflate(R.menu.image_view_options_menu, menu); 186 | return true; 187 | } 188 | 189 | @Override 190 | public boolean onOptionsItemSelected(MenuItem item) { 191 | switch (item.getItemId()) { 192 | case R.id.item_additional_info_object: 193 | if (mInformationView.getVisibility() == View.GONE) { 194 | mInformationView.setVisibility(View.VISIBLE); 195 | } else { 196 | mInformationView.setVisibility(View.GONE); 197 | } 198 | break; 199 | case R.id.item_additional_share_object: 200 | GalleryImageView view = (GalleryImageView) mGalleryFullscreen.getSelectedView(); 201 | String uniqueId = view.getGalleryObject().getImage().getUniqueId(); 202 | GalDroidApp app = (GalDroidApp) getApplicationContext(); 203 | ImageCache cache = app.getImageCache(); 204 | callShareIntentActivity(cache.getFile(uniqueId)); 205 | break; 206 | } 207 | return true; 208 | } 209 | 210 | public void onItemSelected(AdapterView gallery, View view, int position, long arg3) { 211 | setCurrentIndex(position); 212 | 213 | if (gallery == mGalleryFullscreen) { 214 | mGalleryThumbnails.setSelection(position); 215 | } else { 216 | mGalleryFullscreen.setSelection(position); 217 | view = mGalleryFullscreen.getSelectedView(); 218 | } 219 | mInformationView.setGalleryImageView((GalleryImageView) view); 220 | } 221 | 222 | public void onNothingSelected(AdapterView arg0) { 223 | // Empty Stub, cause nothing to do 224 | } 225 | 226 | @Override 227 | public void onGalleryObjectsLoaded(List galleryObjects) { 228 | mAdapterFullscreen.setGalleryObjects(galleryObjects); 229 | mAdapterThumbnails.setGalleryObjects(galleryObjects); 230 | 231 | int currentIndex = getCurrentIndex(); 232 | if (currentIndex == -1) { 233 | GalleryObject currentObject = (GalleryObject) getIntent().getExtras().getSerializable(GalDroidApp.INTENT_EXTRA_DISPLAY_OBJECT); 234 | currentIndex = galleryObjects.indexOf(currentObject); 235 | } 236 | 237 | mGalleryFullscreen.setSelection(currentIndex); 238 | mGalleryThumbnails.setSelection(currentIndex); 239 | mFullscrennImageLoaderTask.start(); 240 | } 241 | 242 | public void onItemClick(AdapterView arg0, View arg1, int arg2, long arg3) { 243 | if (mActionBarHider.isShowing()) { 244 | mActionBarHider.hide(); 245 | } else { 246 | mActionBarHider.show(); 247 | } 248 | 249 | } 250 | } 251 | -------------------------------------------------------------------------------- /src/de/raptor2101/GalDroid/WebGallery/Tasks/RepeatingTask.java: -------------------------------------------------------------------------------- 1 | package de.raptor2101.GalDroid.WebGallery.Tasks; 2 | 3 | import java.lang.Thread.State; 4 | import java.util.LinkedList; 5 | import java.util.concurrent.Callable; 6 | 7 | import android.os.Handler; 8 | import android.os.Message; 9 | import android.util.Log; 10 | 11 | public abstract class RepeatingTask implements TaskInterface { 12 | protected static final String CLASS_TAG = "RepeatingTask"; 13 | private static final int MESSAGE_POST_RESULT = 1; 14 | private static final int MESSAGE_POST_PROGRESS = 2; 15 | private static final int MESSAGE_POST_ERROR = 3; 16 | private static final int MESSAGE_PRE_EXECUTION = 4; 17 | 18 | private final int mMaxEnqueuedTasks; 19 | 20 | public RepeatingTask(int maxEnquedTasks) { 21 | mMaxEnqueuedTasks = maxEnquedTasks; 22 | } 23 | 24 | private class TaskMessage { 25 | public final ParameterType mParameter; 26 | public final MessageType mMessage; 27 | 28 | public TaskMessage(ParameterType parameter, MessageType message) { 29 | mMessage = message; 30 | mParameter = parameter; 31 | } 32 | } 33 | 34 | private class MessageHandler extends Handler { 35 | @SuppressWarnings("unchecked") 36 | @Override 37 | public void handleMessage(Message msg) { 38 | switch (msg.what) { 39 | case MESSAGE_PRE_EXECUTION: { 40 | TaskMessage message = (TaskMessage) msg.obj; 41 | onPreExecute(message.mParameter); 42 | break; 43 | } 44 | case MESSAGE_POST_RESULT: { 45 | TaskMessage message = (TaskMessage) msg.obj; 46 | onPostExecute(message.mParameter, message.mMessage); 47 | break; 48 | } 49 | case MESSAGE_POST_PROGRESS: { 50 | TaskMessage message = (TaskMessage) msg.obj; 51 | onProgressUpdate(message.mParameter, message.mMessage); 52 | break; 53 | } 54 | case MESSAGE_POST_ERROR: { 55 | TaskMessage message = (TaskMessage) msg.obj; 56 | onExceptionThrown(message.mParameter, message.mMessage); 57 | break; 58 | } 59 | } 60 | } 61 | } 62 | 63 | private final MessageHandler mMessageHandler = new MessageHandler(); 64 | 65 | private class Task implements Callable { 66 | private final ParameterType mCallParameter; 67 | 68 | public Task(ParameterType callParameter) { 69 | mCallParameter = callParameter; 70 | } 71 | 72 | public ResultType call() throws Exception { 73 | return doInBackground(mCallParameter); 74 | } 75 | 76 | @Override 77 | public int hashCode() { 78 | return mCallParameter.hashCode(); 79 | } 80 | 81 | @Override 82 | public boolean equals(Object obj) { 83 | if (this == obj) 84 | return true; 85 | if (obj == null) 86 | return false; 87 | if (getClass() != obj.getClass()) 88 | return false; 89 | @SuppressWarnings("unchecked") 90 | Task other = (Task) obj; 91 | if (!getOuterType().equals(other.getOuterType())) 92 | return false; 93 | if (mCallParameter == null) { 94 | if (other.mCallParameter != null) 95 | return false; 96 | } else if (!mCallParameter.equals(other.mCallParameter)) 97 | return false; 98 | return true; 99 | } 100 | 101 | @SuppressWarnings("rawtypes") 102 | private RepeatingTask getOuterType() { 103 | return RepeatingTask.this; 104 | } 105 | 106 | @Override 107 | public String toString() { 108 | return mCallParameter.toString(); 109 | } 110 | } 111 | 112 | protected final LinkedList mTaskQueue = new LinkedList(); 113 | 114 | private class InternRunnable implements Runnable { 115 | 116 | boolean mRunning = true; 117 | Task mCurrentCallable; 118 | long mThreadID; 119 | public void run() { 120 | mThreadID = Thread.currentThread().getId(); 121 | Log.d(this.buildLogTag(), "Thread started"); 122 | mIsStarted = true; 123 | while (mRunning) { 124 | try { 125 | Message message; 126 | mCurrentCallable = waitForCallable(); 127 | try { 128 | TaskMessage messageBody = new TaskMessage(mCurrentCallable.mCallParameter, null); 129 | message = mMessageHandler.obtainMessage(MESSAGE_PRE_EXECUTION, messageBody); 130 | message.sendToTarget(); 131 | 132 | Log.d(this.buildLogTag(), String.format("Executing Task(%s)", mCurrentCallable.mCallParameter)); 133 | ResultType result = mCurrentCallable.call(); 134 | messageBody = new TaskMessage(mCurrentCallable.mCallParameter, result); 135 | message = mMessageHandler.obtainMessage(MESSAGE_POST_RESULT, messageBody); 136 | } catch (Exception e) { 137 | Log.e(this.buildLogTag(), String.format("Something goes wrong while executing Task(%s)", mCurrentCallable.mCallParameter), e); 138 | TaskMessage messageBody = new TaskMessage(mCurrentCallable.mCallParameter, e); 139 | message = mMessageHandler.obtainMessage(MESSAGE_POST_ERROR, messageBody); 140 | } 141 | Log.d(buildLogTag(), String.format("Invoke Callback for Task(%s)", mCurrentCallable.mCallParameter)); 142 | message.sendToTarget(); 143 | mCurrentCallable = null; 144 | mIsCancelled = false; 145 | } catch (InterruptedException e) { 146 | Log.d(buildLogTag(), "got interrupted"); 147 | } 148 | } 149 | Log.d(this.buildLogTag(), "Thread finished"); 150 | } 151 | 152 | private String buildLogTag() { 153 | return String.format("%s (%d:%s)", CLASS_TAG, mThreadID, mThreadName); 154 | } 155 | 156 | private Task waitForCallable() throws InterruptedException { 157 | synchronized (mTaskQueue) { 158 | Log.d(this.buildLogTag(), String.format("Looking for enqueued task, QueueSize: %d",mTaskQueue.size())); 159 | while (mTaskQueue.size() == 0) { 160 | mIsSleeping = true; 161 | Log.d(String.format("%s (%s)", CLASS_TAG, mThreadName), "Waiting for enqueued task"); 162 | mTaskQueue.wait(); 163 | } 164 | mIsSleeping = false; 165 | Log.d(this.buildLogTag(), String.format("Returning enqueued task, QueueSize: %d",mTaskQueue.size())); 166 | return mTaskQueue.poll(); 167 | } 168 | } 169 | } 170 | 171 | private Thread mThread; 172 | private final InternRunnable mRunnable = new InternRunnable(); 173 | private boolean mIsStarted = false; 174 | private boolean mIsSleeping = false; 175 | private boolean mIsStopping = false; 176 | private boolean mIsCancelled = false; 177 | 178 | protected String mThreadName = CLASS_TAG; 179 | 180 | protected void enqueueTask(ParameterType parameter) { 181 | if (!mIsStopping) { 182 | Log.d(buildLogTag(), String.format("Enqueuing %s , QueueSize: %d", parameter, mTaskQueue.size())); 183 | synchronized (mTaskQueue) { 184 | mTaskQueue.add(new Task(parameter)); 185 | 186 | while (mMaxEnqueuedTasks > 0 && mTaskQueue.size() > mMaxEnqueuedTasks) { 187 | mTaskQueue.poll(); 188 | } 189 | 190 | Log.d(buildLogTag(), "Notify waiting WorkerThread"); 191 | mTaskQueue.notifyAll(); 192 | } 193 | } 194 | } 195 | 196 | private String buildLogTag() { 197 | long threadID = mThread != null? mThread.getId() : -1; 198 | return String.format("%s (%d:%s)", CLASS_TAG, threadID, mThreadName); 199 | } 200 | 201 | protected void removeEnqueuedTask(ParameterType parameter) { 202 | Log.d(buildLogTag(), String.format("Remove enqueued %s", parameter)); 203 | synchronized (mTaskQueue) { 204 | mTaskQueue.remove(parameter); 205 | } 206 | } 207 | 208 | protected void cancelCurrentTask(boolean waitForCancel) throws InterruptedException { 209 | if(mRunnable.mCurrentCallable != null) { 210 | mIsCancelled = true; 211 | mThread.interrupt(); 212 | } 213 | 214 | while(waitForCancel && mIsCancelled) { 215 | mThread.interrupt(); 216 | Thread.sleep(100); 217 | } 218 | } 219 | 220 | public final void start() { 221 | if (mThread == null || mThread.getState() == State.TERMINATED) { 222 | mIsStarted = false; 223 | mIsSleeping = false; 224 | mIsStopping = false; 225 | mRunnable.mRunning = true; 226 | mThread = new Thread(mRunnable, mThreadName); 227 | mThread.setDaemon(false); 228 | Log.d(buildLogTag(), "Starting WorkerThread"); 229 | mThread.start(); 230 | } 231 | } 232 | 233 | public final void stop(boolean waitForStopped) throws InterruptedException{ 234 | if (mThread != null) { 235 | mRunnable.mRunning = false; 236 | if(mIsSleeping) { 237 | mThread.interrupt(); 238 | } 239 | 240 | if (waitForStopped) { 241 | mThread.join(); 242 | } 243 | mThread = null; 244 | } 245 | } 246 | 247 | public final void cancel(boolean waitForCancel) throws InterruptedException { 248 | if (mThread != null) { 249 | mIsCancelled = true; 250 | mRunnable.mRunning = false; 251 | synchronized (mTaskQueue) { 252 | mTaskQueue.clear(); 253 | } 254 | mThread.interrupt(); 255 | if (waitForCancel) { 256 | mThread.join(); 257 | } 258 | mThread = null; 259 | } 260 | } 261 | 262 | protected void onPreExecute(ParameterType callParameter) { 263 | } 264 | 265 | protected final void publishProgress(ProgressType progress){ 266 | TaskMessage messageBody = new TaskMessage(mRunnable.mCurrentCallable.mCallParameter, progress); 267 | Message message = mMessageHandler.obtainMessage(MESSAGE_POST_PROGRESS, messageBody); 268 | message.sendToTarget(); 269 | } 270 | 271 | protected abstract ResultType doInBackground(ParameterType callParameter); 272 | 273 | protected abstract void onPostExecute(ParameterType parameter, ResultType result); 274 | 275 | protected void onExceptionThrown(ParameterType callParameter, Exception exception) { 276 | } 277 | 278 | protected void onProgressUpdate(ParameterType callParameter, ProgressType progress) { 279 | } 280 | 281 | protected void onCancelled(ParameterType callParameter, ResultType result) { 282 | onCancelled(); 283 | } 284 | 285 | protected void onCancelled() { 286 | } 287 | 288 | public final Status getStatus() { 289 | if (mThread == null || mThread.getState() == State.TERMINATED) { 290 | return Status.FINISHED; 291 | } 292 | if (!mIsStarted) { 293 | return Status.PENDING; 294 | } 295 | if (mIsSleeping) { 296 | return Status.SLEEPING; 297 | } 298 | return Status.RUNNING; 299 | } 300 | 301 | public boolean isCancelled() { 302 | return mIsCancelled; 303 | } 304 | 305 | protected boolean isEnqueued(ParameterType callParameter) { 306 | synchronized (mTaskQueue) { 307 | return mTaskQueue.contains(new Task(callParameter)); 308 | } 309 | } 310 | 311 | protected boolean isActive(ParameterType parameter) { 312 | Status status = getStatus(); 313 | if (status != Status.RUNNING) { 314 | return false; 315 | } 316 | return mRunnable.mCurrentCallable != null && mRunnable.mCurrentCallable.mCallParameter.equals(parameter); 317 | } 318 | 319 | protected ParameterType getEnqueuedTask(ParameterType callParameter) { 320 | synchronized (mTaskQueue) { 321 | int index = mTaskQueue.indexOf(callParameter); 322 | if(index > -1) { 323 | return mTaskQueue.get(index).mCallParameter; 324 | } else { 325 | return null; 326 | } 327 | } 328 | } 329 | 330 | protected ParameterType getEnqueuedTask(int index) { 331 | synchronized (mTaskQueue) { 332 | return mTaskQueue.get(index).mCallParameter; 333 | } 334 | } 335 | 336 | protected int getEnqueuedTaskPosition(ParameterType callParameter) { 337 | synchronized (mTaskQueue) { 338 | return mTaskQueue.indexOf(callParameter); 339 | } 340 | } 341 | 342 | protected ParameterType getActiveTask() { 343 | if(mRunnable.mCurrentCallable != null) { 344 | return mRunnable.mCurrentCallable.mCallParameter; 345 | } else { 346 | return null; 347 | } 348 | 349 | } 350 | } 351 | -------------------------------------------------------------------------------- /res/layout/image_information_view.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 18 | 19 | 23 | 24 | 27 | 28 | 29 | 30 | 36 | 37 | 42 | 43 | 44 | 45 | 46 | 53 | 54 | 59 | 60 | 61 | 62 | 63 | 69 | 70 | 77 | 78 | 83 | 84 | 85 | 86 | 93 | 94 | 98 | 99 | 102 | 103 | 104 | 105 | 111 | 112 | 117 | 118 | 119 | 120 | 121 | 127 | 128 | 133 | 134 | 135 | 136 | 137 | 143 | 144 | 149 | 150 | 151 | 152 | 153 | 159 | 160 | 165 | 166 | 167 | 168 | 169 | 175 | 176 | 181 | 182 | 183 | 184 | 185 | 191 | 192 | 197 | 198 | 199 | 200 | 201 | 207 | 208 | 213 | 214 | 215 | 216 | 217 | 223 | 224 | 229 | 230 | 231 | 232 | 233 | 240 | 241 | 246 | 247 | 248 | 249 | 256 | 257 | 261 | 262 | 263 | 264 | 271 | 272 | 277 | 278 | 279 | 280 | 281 | 288 | 289 | 294 | 295 | 296 | 297 | 298 | 305 | 306 | 311 | 312 | 313 | 321 | 322 | 326 | 327 | 330 | 331 | 336 | 337 | 338 | 342 | 343 | 350 | 351 | 352 | -------------------------------------------------------------------------------- /src/de/raptor2101/GalDroid/WebGallery/Gallery3/Gallery3Imp.java: -------------------------------------------------------------------------------- 1 | /* 2 | * GalDroid - a webgallery frontend for android 3 | * Copyright (C) 2011 Raptor 2101 [raptor2101@gmx.de] 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package de.raptor2101.GalDroid.WebGallery.Gallery3; 20 | 21 | import java.io.BufferedReader; 22 | import java.io.IOException; 23 | import java.io.InputStream; 24 | import java.io.InputStreamReader; 25 | import java.util.ArrayList; 26 | import java.util.List; 27 | import java.util.concurrent.ExecutionException; 28 | 29 | import org.apache.http.HttpResponse; 30 | import org.apache.http.client.ClientProtocolException; 31 | import org.apache.http.client.HttpClient; 32 | import org.apache.http.client.methods.HttpGet; 33 | import org.apache.http.client.methods.HttpPost; 34 | import org.apache.http.entity.mime.HttpMultipartMode; 35 | import org.apache.http.entity.mime.MultipartEntity; 36 | import org.apache.http.entity.mime.content.StringBody; 37 | import org.json.JSONArray; 38 | import org.json.JSONException; 39 | import org.json.JSONObject; 40 | 41 | import android.os.AsyncTask.Status; 42 | import android.util.FloatMath; 43 | 44 | import de.raptor2101.GalDroid.WebGallery.Stream; 45 | import de.raptor2101.GalDroid.WebGallery.Gallery3.JSON.AlbumEntity; 46 | import de.raptor2101.GalDroid.WebGallery.Gallery3.JSON.CommentEntity; 47 | import de.raptor2101.GalDroid.WebGallery.Gallery3.JSON.CommentEntity.CommentState; 48 | import de.raptor2101.GalDroid.WebGallery.Gallery3.JSON.Entity; 49 | import de.raptor2101.GalDroid.WebGallery.Gallery3.JSON.EntityFactory; 50 | import de.raptor2101.GalDroid.WebGallery.Gallery3.Tasks.JSONArrayLoaderTask; 51 | import de.raptor2101.GalDroid.WebGallery.Interfaces.GalleryDownloadObject; 52 | import de.raptor2101.GalDroid.WebGallery.Interfaces.GalleryObject; 53 | import de.raptor2101.GalDroid.WebGallery.Interfaces.GalleryObjectComment; 54 | import de.raptor2101.GalDroid.WebGallery.Interfaces.GalleryProgressListener; 55 | import de.raptor2101.GalDroid.WebGallery.Interfaces.WebGallery; 56 | 57 | public class Gallery3Imp implements WebGallery { 58 | private HttpClient mHttpClient; 59 | private String mSecurityToken; 60 | private float mMaxImageDiag; 61 | private final String mRootLink; 62 | public final String LinkRest_LoadSecurityToken; 63 | public final String LinkRest_LoadItem; 64 | public final String LinkRest_LoadTag; 65 | public final String LinkRest_LoadBunchItems; 66 | public final String LinkRest_LoadBunchTags; 67 | public final String LinkRest_LoadPicture; 68 | public final String LinkRest_LoadComments; 69 | 70 | private static int MAX_REQUEST_SIZE = 4000; 71 | 72 | public Gallery3Imp(String rootLink) { 73 | mRootLink = rootLink; 74 | LinkRest_LoadSecurityToken = rootLink + "/index.php/rest"; 75 | LinkRest_LoadItem = rootLink + "/index.php/rest/item/%d"; 76 | LinkRest_LoadTag = rootLink + "/index.php/rest/tag/%s"; 77 | LinkRest_LoadBunchItems = rootLink + "/index.php/rest/items?urls=[%s]"; 78 | LinkRest_LoadBunchTags = rootLink + "/index.php/rest/tags?urls=[%s]"; 79 | LinkRest_LoadPicture = rootLink + "/index.php/rest/data/%s?size=%s"; 80 | LinkRest_LoadComments = rootLink + "/index.php/rest/item_comments/%d"; 81 | } 82 | 83 | public String getItemLink(int id) { 84 | return String.format(LinkRest_LoadItem, id); 85 | } 86 | 87 | private RestCall buildRestCall(String url, long suggestedLength) { 88 | HttpGet httpRequest = new HttpGet(url); 89 | 90 | httpRequest.addHeader("X-Gallery-Request-Method", "get"); 91 | httpRequest.addHeader("X-Gallery-Request-Key", mSecurityToken); 92 | 93 | return new RestCall(this, httpRequest, suggestedLength); 94 | } 95 | 96 | private Entity loadGalleryEntity(String url) throws ClientProtocolException, IOException, JSONException { 97 | 98 | RestCall restCall = buildRestCall(url, -1); 99 | return EntityFactory.parseJSON(restCall.loadJSONObject(), this); 100 | } 101 | 102 | private List loadJSONObjectsParallel(String bunchUrl, List urls, int taskCount, GalleryProgressListener listener) { 103 | int objectSize = urls.size(); 104 | ArrayList tasks = new ArrayList(taskCount); 105 | 106 | ArrayList jsonObjects = new ArrayList(objectSize); 107 | 108 | for (int i = 0; i < objectSize;) { 109 | StringBuilder requstUrl = new StringBuilder(MAX_REQUEST_SIZE); 110 | JSONArrayLoaderTask task = new JSONArrayLoaderTask(); 111 | tasks.add(task); 112 | /* 113 | * TODO Kommentar anpassen Otherwise the max length of a GET-Request might 114 | * be exceeded 115 | */ 116 | 117 | for (; i < objectSize; i++) { 118 | String url = urls.get(i); 119 | if (url.length() + requstUrl.length() > MAX_REQUEST_SIZE) { 120 | break; 121 | } 122 | requstUrl.append("%22" + url + "%22,"); 123 | } 124 | 125 | requstUrl.deleteCharAt(requstUrl.length() - 1); 126 | String realUrl = String.format(bunchUrl, requstUrl); 127 | 128 | task.execute(buildRestCall(realUrl, -1)); 129 | } 130 | 131 | for (JSONArrayLoaderTask task : tasks) { 132 | if (task.getStatus() != Status.FINISHED) { 133 | try { 134 | JSONArray jsonArray = task.get(); 135 | for (int i = 0; i < jsonArray.length(); i++) { 136 | try { 137 | jsonObjects.add(jsonArray.getJSONObject(i)); 138 | if (listener != null) { 139 | listener.handleProgress(jsonObjects.size(), objectSize); 140 | } 141 | } catch (JSONException e) { 142 | e.printStackTrace(); 143 | } 144 | } 145 | } catch (InterruptedException e) { 146 | 147 | } catch (ExecutionException e) { 148 | 149 | } 150 | } 151 | } 152 | 153 | return jsonObjects; 154 | } 155 | 156 | public GalleryObject getDisplayObject(String url) throws ClientProtocolException, IOException, JSONException { 157 | return loadGalleryEntity(url); 158 | } 159 | 160 | public List getDisplayObjects() { 161 | return getDisplayObjects(String.format(LinkRest_LoadItem, 1), null); 162 | } 163 | 164 | public List getDisplayObjects(String url) { 165 | return getDisplayObjects(url, null); 166 | } 167 | 168 | public List getDisplayObjects(GalleryProgressListener progressListener) { 169 | return getDisplayObjects(String.format(LinkRest_LoadItem, 1), progressListener); 170 | } 171 | 172 | public List getDisplayObjects(String url, GalleryProgressListener listener) { 173 | ArrayList displayObjects; 174 | try { 175 | GalleryObject galleryObject = loadGalleryEntity(url); 176 | if (galleryObject.hasChildren()) { 177 | AlbumEntity album = (AlbumEntity) galleryObject; 178 | List members = album.getMembers(); 179 | 180 | displayObjects = new ArrayList(members.size()); 181 | 182 | List jsonObjects = loadJSONObjectsParallel(LinkRest_LoadBunchItems, members, 5, listener); 183 | 184 | for (JSONObject jsonObject : jsonObjects) { 185 | if (jsonObject != null) { 186 | displayObjects.add(EntityFactory.parseJSON(jsonObject, this)); 187 | } 188 | } 189 | } else 190 | displayObjects = new ArrayList(0); 191 | 192 | } catch (ClientProtocolException e) { 193 | displayObjects = new ArrayList(0); 194 | e.printStackTrace(); 195 | } catch (IOException e) { 196 | displayObjects = new ArrayList(0); 197 | e.printStackTrace(); 198 | } catch (JSONException e) { 199 | displayObjects = new ArrayList(0); 200 | e.printStackTrace(); 201 | } 202 | 203 | return displayObjects; 204 | } 205 | 206 | public List getDisplayObjects(GalleryObject galleryObject) { 207 | return getDisplayObjects(galleryObject, null); 208 | } 209 | 210 | public List getDisplayObjects(GalleryObject galleryObject, GalleryProgressListener progressListener) { 211 | try { 212 | Entity entity = (Entity) galleryObject; 213 | if (!entity.hasChildren()) { 214 | return null; 215 | } 216 | return getDisplayObjects(entity.getObjectLink(), progressListener); 217 | } catch (ClassCastException e) { 218 | return null; 219 | } 220 | } 221 | 222 | public List getDisplayObjectTags(GalleryObject galleryObject, GalleryProgressListener listener) throws IOException { 223 | try { 224 | Entity entity = (Entity) galleryObject; 225 | List tagLinks = entity.getTagLinks(); 226 | int linkCount = tagLinks.size(); 227 | ArrayList tags = new ArrayList(linkCount); 228 | 229 | if (linkCount > 0) { 230 | for (int i = 0; i < linkCount; i++) { 231 | try { 232 | RestCall restCall = buildRestCall(tagLinks.get(i), -1); 233 | JSONObject jsonObject = restCall.loadJSONObject(); 234 | tags.add(EntityFactory.parseTag(jsonObject)); 235 | } catch (JSONException e) { 236 | // Nothing to do here 237 | } catch (IOException e) { 238 | // Nothing to do here 239 | } 240 | 241 | } 242 | } 243 | return tags; 244 | } catch (ClassCastException e) { 245 | throw new IOException("GalleryObject doesn't contain to Gallery3Implementation", e); 246 | } 247 | 248 | } 249 | 250 | public List getDisplayObjectComments(GalleryObject galleryObject, GalleryProgressListener listener) throws IOException, ClientProtocolException, JSONException { 251 | try { 252 | Entity entity = (Entity) galleryObject; 253 | String commentSource = String.format(LinkRest_LoadComments, entity.getId()); 254 | RestCall restCall = buildRestCall(commentSource, -1); 255 | JSONObject jsonObject = restCall.loadJSONObject(); 256 | JSONArray jsonItemComments = jsonObject.getJSONArray("members"); 257 | int commentCount = jsonItemComments.length(); 258 | 259 | ArrayList comments = new ArrayList(commentCount); 260 | ArrayList authors = new ArrayList(commentCount); 261 | 262 | for (int i = 0; i < commentCount; i++) { 263 | restCall = buildRestCall(jsonItemComments.getString(i), -1); 264 | jsonObject = restCall.loadJSONObject(); 265 | 266 | CommentEntity comment = EntityFactory.parseComment(jsonObject); 267 | if (comment.getState() == CommentState.Published) { 268 | comments.add(comment); 269 | 270 | if (!comment.isAuthorInformationLoaded()) { 271 | authors.add(comment.getAuthorId()); 272 | } 273 | } 274 | } 275 | 276 | return comments; 277 | } catch (ClassCastException e) { 278 | throw new IOException("GalleryObject doesn't contain to Gallery3Implementation", e); 279 | } 280 | } 281 | 282 | private Stream getFileStream(String sourceLink, long suggestedLength) throws ClientProtocolException, IOException { 283 | RestCall restCall = buildRestCall(sourceLink, suggestedLength); 284 | return restCall.open(); 285 | 286 | } 287 | 288 | public Stream getFileStream(GalleryDownloadObject galleryDownloadObject) throws ClientProtocolException, IOException { 289 | if (!(galleryDownloadObject instanceof DownloadObject)) { 290 | throw new IOException("downloadObject don't belong to the Gallery3 Implementation"); 291 | } 292 | DownloadObject downloadObject = (DownloadObject) galleryDownloadObject; 293 | if (!(downloadObject.getRootLink().equals(mRootLink))) { 294 | throw new IOException("downloadObject don't belong to the this Host"); 295 | } 296 | return getFileStream(downloadObject.getUniqueId(), downloadObject.getFileSize()); 297 | } 298 | 299 | public void setHttpClient(HttpClient httpClient) { 300 | mHttpClient = httpClient; 301 | } 302 | 303 | public String getSecurityToken(String user, String password) throws SecurityException { 304 | try { 305 | HttpPost httpRequest = new HttpPost(LinkRest_LoadSecurityToken); 306 | 307 | httpRequest.addHeader("X-Gallery-Request-Method", "post"); 308 | MultipartEntity mpEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE); 309 | 310 | mpEntity.addPart("user", new StringBody(user)); 311 | mpEntity.addPart("password", new StringBody(password)); 312 | 313 | httpRequest.setEntity(mpEntity); 314 | HttpResponse response; 315 | 316 | response = mHttpClient.execute(httpRequest); 317 | InputStream inputStream = response.getEntity().getContent(); 318 | InputStreamReader streamReader = new InputStreamReader(inputStream); 319 | BufferedReader reader = new BufferedReader(streamReader); 320 | String content = reader.readLine(); 321 | inputStream.close(); 322 | if (content.length() == 0 || content.startsWith("[]")) { 323 | throw new SecurityException("Couldn't verify user-credentials"); 324 | } 325 | 326 | return content.trim().replace("\"", ""); 327 | } catch (Exception e) { 328 | throw new SecurityException("Couldn't verify user-credentials", e); 329 | } 330 | } 331 | 332 | public HttpClient getHttpClient() { 333 | return mHttpClient; 334 | } 335 | 336 | public void setSecurityToken(String securityToken) { 337 | mSecurityToken = securityToken; 338 | } 339 | 340 | public void setPreferedDimensions(int height, int width) { 341 | mMaxImageDiag = FloatMath.sqrt(height * height + width * width); 342 | } 343 | 344 | public String getRootLink() { 345 | return mRootLink; 346 | } 347 | 348 | public float getMaxImageDiag() { 349 | return mMaxImageDiag; 350 | } 351 | } 352 | -------------------------------------------------------------------------------- /src/de/raptor2101/GalDroid/WebGallery/Tasks/ImageLoaderTask.java: -------------------------------------------------------------------------------- 1 | /* 2 | * GalDroid - a webgallery frontend for android 3 | * Copyright (C) 2011 Raptor 2101 [raptor2101@gmx.de] 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package de.raptor2101.GalDroid.WebGallery.Tasks; 20 | 21 | import java.io.FileInputStream; 22 | import java.io.IOException; 23 | import java.io.InputStream; 24 | import java.io.OutputStream; 25 | import java.lang.ref.WeakReference; 26 | 27 | import android.graphics.Bitmap; 28 | import android.graphics.BitmapFactory; 29 | import android.graphics.BitmapFactory.Options; 30 | import android.util.Log; 31 | import android.view.ViewGroup.LayoutParams; 32 | import de.raptor2101.GalDroid.WebGallery.ImageCache; 33 | import de.raptor2101.GalDroid.WebGallery.Stream; 34 | import de.raptor2101.GalDroid.WebGallery.Interfaces.GalleryDownloadObject; 35 | import de.raptor2101.GalDroid.WebGallery.Interfaces.WebGallery; 36 | 37 | public class ImageLoaderTask implements TaskInterface { 38 | protected final static String CLASS_TAG = "ImageLoaderTask"; 39 | 40 | public class ImageDownload{ 41 | private final LayoutParams mLayoutParams; 42 | private WeakReference mListener; 43 | private final GalleryDownloadObject mDownloadObject; 44 | 45 | public ImageDownload(GalleryDownloadObject downloadObject, LayoutParams layoutParams , ImageLoaderTaskListener listener) { 46 | mListener = new WeakReference(listener); 47 | mDownloadObject = downloadObject; 48 | mLayoutParams = layoutParams; 49 | } 50 | 51 | @Override 52 | public int hashCode() { 53 | final int prime = 31; 54 | int result = 1; 55 | result = prime * result + getOuterType().hashCode(); 56 | result = prime * result + ((mDownloadObject == null) ? 0 : mDownloadObject.hashCode()); 57 | return result; 58 | } 59 | 60 | @Override 61 | public boolean equals(Object obj) { 62 | if (this == obj) { 63 | return true; 64 | } 65 | if (obj == null) { 66 | return false; 67 | } 68 | if (getClass() != obj.getClass()) { 69 | return false; 70 | } 71 | ImageDownload other = (ImageDownload) obj; 72 | if (!getOuterType().equals(other.getOuterType())) { 73 | return false; 74 | } 75 | if (mDownloadObject == null) { 76 | if (other.mDownloadObject != null) { 77 | return false; 78 | } 79 | } else if (!mDownloadObject.equals(other.mDownloadObject)) { 80 | return false; 81 | } 82 | return true; 83 | } 84 | 85 | public ImageLoaderTaskListener getListener() { 86 | return mListener.get(); 87 | } 88 | 89 | public GalleryDownloadObject getDownloadObject() { 90 | return mDownloadObject; 91 | } 92 | 93 | public LayoutParams getLayoutParams() { 94 | return mLayoutParams; 95 | } 96 | 97 | @Override 98 | public String toString() { 99 | return mDownloadObject.toString(); 100 | } 101 | 102 | private ImageLoaderTask getOuterType() { 103 | return ImageLoaderTask.this; 104 | } 105 | 106 | public void updateListener(ImageLoaderTaskListener listener) { 107 | mListener = new WeakReference(listener); 108 | } 109 | } 110 | 111 | private class DownloadTask extends RepeatingTask { 112 | protected final static String CLASS_TAG = "ImageLoaderTask"; 113 | 114 | public DownloadTask(int maxEnqueuedDownloads) { 115 | super(maxEnqueuedDownloads); 116 | mThreadName = "ImageLoaderTask"; 117 | } 118 | 119 | @Override 120 | protected void onPreExecute(ImageDownload imageDownload) { 121 | ImageLoaderTaskListener listener = imageDownload.getListener(); 122 | GalleryDownloadObject galleryDownloadObject = imageDownload.getDownloadObject(); 123 | Log.d(CLASS_TAG, String.format("%s - Task started - Listener %s", galleryDownloadObject, listener != null)); 124 | 125 | if (listener != null) { 126 | listener.onLoadingStarted(galleryDownloadObject.getUniqueId()); 127 | } 128 | }; 129 | 130 | @Override 131 | protected void onCancelled(ImageDownload imageDownload, Bitmap bitmap) { 132 | GalleryDownloadObject galleryDownloadObject = imageDownload.getDownloadObject(); 133 | Log.d(CLASS_TAG, String.format("%s - Task canceled", galleryDownloadObject)); 134 | 135 | synchronized (mCache) { 136 | mCache.removeCacheFile(galleryDownloadObject.getUniqueId()); 137 | } 138 | 139 | ImageLoaderTaskListener listener = imageDownload.getListener(); 140 | if (listener != null) { 141 | listener.onLoadingCancelled(galleryDownloadObject.getUniqueId()); 142 | } 143 | } 144 | 145 | @Override 146 | protected Bitmap doInBackground(ImageDownload imageDownload) { 147 | GalleryDownloadObject galleryDownloadObject = imageDownload.getDownloadObject(); 148 | try { 149 | Log.d(CLASS_TAG, String.format("%s - Task running", galleryDownloadObject)); 150 | String uniqueId = galleryDownloadObject.getUniqueId(); 151 | InputStream inputStream = mCache.getFileStream(uniqueId); 152 | 153 | if (inputStream == null) { 154 | DownloadImage(galleryDownloadObject); 155 | 156 | } 157 | 158 | LayoutParams layoutParams = imageDownload.getLayoutParams(); 159 | if(layoutParams != null && inputStream != null) { 160 | ScaleImage(galleryDownloadObject, layoutParams); 161 | } 162 | 163 | Options options = new Options(); 164 | options.inPreferQualityOverSpeed = true; 165 | options.inPreferredConfig = Bitmap.Config.ARGB_8888; 166 | options.inDither = true; 167 | options.inScaled = false; 168 | options.inPurgeable = true; 169 | options.inInputShareable = true; 170 | 171 | 172 | if (isCancelled()) { 173 | return null; 174 | } 175 | 176 | Log.d(CLASS_TAG, String.format("%s - Decoding local image", galleryDownloadObject)); 177 | Bitmap bitmap; 178 | try { 179 | inputStream = mCache.getFileStream(uniqueId); 180 | bitmap = BitmapFactory.decodeStream(inputStream, null, options); 181 | } finally { 182 | inputStream.close(); 183 | } 184 | 185 | if (bitmap != null) { 186 | mCache.cacheBitmap(uniqueId, bitmap); 187 | Log.i(CLASS_TAG, String.format("%s - Decoding local image - complete", galleryDownloadObject)); 188 | } else { 189 | Log.w(CLASS_TAG, String.format("Something goes wrong while Decoding %s, removing CachedFile", galleryDownloadObject)); 190 | mCache.removeCacheFile(uniqueId); 191 | } 192 | return bitmap; 193 | } catch (Exception e) { 194 | Log.w(CLASS_TAG, String.format("Something goes wrong while Downloading %s. ExceptionMessage: %s", galleryDownloadObject, e.getMessage())); 195 | return null; 196 | } 197 | } 198 | 199 | @Override 200 | protected void onProgressUpdate(ImageDownload imageDownload, Progress progress) { 201 | GalleryDownloadObject galleryDownloadObject = imageDownload.getDownloadObject(); 202 | ImageLoaderTaskListener listener = imageDownload.getListener(); 203 | if (!isCancelled() && listener != null) { 204 | listener.onLoadingProgress(galleryDownloadObject.getUniqueId(), progress.curValue, progress.maxValue); 205 | } 206 | } 207 | 208 | @Override 209 | protected void onPostExecute(ImageDownload imageDownload, Bitmap bitmap) { 210 | ImageLoaderTaskListener listener = imageDownload.getListener(); 211 | GalleryDownloadObject galleryDownloadObject = imageDownload.getDownloadObject(); 212 | Log.d(CLASS_TAG, String.format("%s - Task done - Listener %s", galleryDownloadObject, listener != null)); 213 | 214 | if (!isCancelled() && listener != null) { 215 | listener.onLoadingCompleted(galleryDownloadObject.getUniqueId(), bitmap); 216 | } 217 | } 218 | 219 | private void DownloadImage(GalleryDownloadObject galleryDownloadObject) throws IOException { 220 | Log.d(CLASS_TAG, String.format("%s - Downloading to local cache file", galleryDownloadObject)); 221 | 222 | Stream networkStream = mWebGallery.getFileStream(galleryDownloadObject); 223 | String uniqueId = galleryDownloadObject.getUniqueId(); 224 | OutputStream fileStream = mCache.createCacheFile(uniqueId); 225 | 226 | byte[] writeCache = new byte[10 * 1024]; 227 | int readCounter; 228 | int currentPos = 0; 229 | int length = (int) networkStream.getContentLength(); 230 | 231 | while ((readCounter = networkStream.read(writeCache)) > 0 && !isCancelled()) { 232 | fileStream.write(writeCache, 0, readCounter); 233 | currentPos += readCounter; 234 | 235 | publishProgress(new Progress(currentPos, length)); 236 | } 237 | 238 | publishProgress(new Progress(length, length)); 239 | 240 | fileStream.close(); 241 | networkStream.close(); 242 | 243 | if (isCancelled()) { 244 | // if the download is aborted, the file is waste of bytes... 245 | Log.i(CLASS_TAG, String.format("%s - Download canceled", galleryDownloadObject)); 246 | mCache.removeCacheFile(uniqueId); 247 | } else { 248 | mCache.refreshCacheFile(uniqueId); 249 | } 250 | Log.d(CLASS_TAG, String.format("%s - Downloading to local cache file - complete", galleryDownloadObject)); 251 | } 252 | 253 | private void ScaleImage(GalleryDownloadObject galleryDownloadObject, LayoutParams layoutParams) throws IOException { 254 | Log.d(CLASS_TAG, String.format("%s - Decoding Bounds", galleryDownloadObject)); 255 | 256 | String uniqueId = galleryDownloadObject.getUniqueId(); 257 | FileInputStream bitmapStream = mCache.getFileStream(uniqueId); 258 | try { 259 | Options options = new Options(); 260 | options.inJustDecodeBounds = true; 261 | synchronized (mCache) { 262 | if (isCancelled()) { 263 | return; 264 | } 265 | 266 | BitmapFactory.decodeStream(bitmapStream, null, options); 267 | } 268 | bitmapStream.close(); 269 | Log.d(CLASS_TAG, String.format("%s - Decoding Bounds - done", galleryDownloadObject)); 270 | int imgHeight = options.outHeight; 271 | int imgWidth = options.outWidth; 272 | int highestLayoutDimension = layoutParams.height > layoutParams.width ? layoutParams.height : layoutParams.width; 273 | int highestImageDimension = imgHeight > imgWidth ? imgHeight : imgWidth; 274 | int sampleSize = highestImageDimension / highestLayoutDimension; 275 | options = new Options(); 276 | options.inInputShareable = true; 277 | options.inPreferredConfig = Bitmap.Config.ARGB_8888; 278 | options.inDither = true; 279 | options.inPurgeable = true; 280 | options.inPreferQualityOverSpeed = true; 281 | if (sampleSize > 1) { 282 | options.inSampleSize = sampleSize; 283 | } 284 | synchronized (mCache) { 285 | if (isCancelled()) { 286 | return; 287 | } 288 | 289 | bitmapStream = mCache.getFileStream(uniqueId); 290 | Log.d(CLASS_TAG, String.format("%s - Resize Image", galleryDownloadObject)); 291 | Bitmap bitmap = BitmapFactory.decodeStream(bitmapStream, null, options); 292 | 293 | mCache.cacheBitmap(uniqueId, bitmap); 294 | bitmap.recycle(); 295 | Log.d(CLASS_TAG, String.format("%s - Resize Image - done", galleryDownloadObject)); 296 | } 297 | } finally { 298 | bitmapStream.close(); 299 | } 300 | } 301 | } 302 | 303 | private DownloadTask mDownloadTask; 304 | private ImageCache mCache; 305 | private WebGallery mWebGallery; 306 | 307 | 308 | public ImageLoaderTask(WebGallery webGallery, ImageCache cache, int maxEnqueuedDownloads) { 309 | mWebGallery = webGallery; 310 | mCache = cache; 311 | mDownloadTask = new DownloadTask(maxEnqueuedDownloads); 312 | 313 | } 314 | 315 | public ImageDownload download(GalleryDownloadObject galleryDownloadObject, LayoutParams layoutParams, ImageLoaderTaskListener listener) { 316 | Log.d(CLASS_TAG, String.format("Enqueue download for %s - Listener: %s", galleryDownloadObject, listener != null)); 317 | ImageDownload imageDownload = new ImageDownload(galleryDownloadObject, layoutParams, listener); 318 | mDownloadTask.enqueueTask(imageDownload); 319 | return imageDownload; 320 | } 321 | 322 | public ImageDownload getActiveDownload(){ 323 | return mDownloadTask.getActiveTask(); 324 | } 325 | 326 | public boolean isDownloading(GalleryDownloadObject galleryDownloadObject) { 327 | if (galleryDownloadObject == null) { 328 | return false; 329 | } 330 | ImageDownload imageDownload = new ImageDownload(galleryDownloadObject, null, null); 331 | boolean isActive = mDownloadTask.isActive(imageDownload); 332 | boolean isEnqueued = mDownloadTask.isEnqueued(imageDownload); 333 | return isActive || isEnqueued; 334 | } 335 | 336 | public void cancel(GalleryDownloadObject downloadObject, boolean waitForCancel) throws InterruptedException { 337 | if (downloadObject == null) { 338 | return; 339 | } 340 | 341 | ImageDownload imageDownload = new ImageDownload(downloadObject, null, null); 342 | if (mDownloadTask.isEnqueued(imageDownload)) { 343 | mDownloadTask.removeEnqueuedTask(imageDownload); 344 | } else if (mDownloadTask.isActive(imageDownload)) { 345 | mDownloadTask.cancelCurrentTask(waitForCancel); 346 | } 347 | } 348 | 349 | public void cancelActiveDownload(boolean waitForCancel) throws InterruptedException { 350 | mDownloadTask.cancelCurrentTask(waitForCancel); 351 | } 352 | 353 | public Status getStatus() { 354 | return mDownloadTask.getStatus(); 355 | } 356 | 357 | public void start() { 358 | mDownloadTask.start(); 359 | 360 | } 361 | 362 | public void stop(boolean waitForStopped) throws InterruptedException { 363 | mDownloadTask.stop(waitForStopped); 364 | 365 | } 366 | 367 | public void cancel(boolean waitForCancel) throws InterruptedException { 368 | mDownloadTask.cancel(waitForCancel); 369 | 370 | } 371 | } 372 | --------------------------------------------------------------------------------