save images to external storage instead of internal. this requires more permissions. fixed #150 fixed #177 fixed #333 - this might need some more polish though
This commit is contained in:
		
							parent
							
								
									620d1df82e
								
							
						
					
					
						commit
						98a80ffc61
					
				| @ -8,6 +8,8 @@ | |||||||
|         android:minSdkVersion="14" |         android:minSdkVersion="14" | ||||||
|         android:targetSdkVersion="19" /> |         android:targetSdkVersion="19" /> | ||||||
| 
 | 
 | ||||||
|  |     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> | ||||||
|  |     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> | ||||||
|     <uses-permission android:name="android.permission.READ_CONTACTS" /> |     <uses-permission android:name="android.permission.READ_CONTACTS" /> | ||||||
|     <uses-permission android:name="android.permission.READ_PROFILE" /> |     <uses-permission android:name="android.permission.READ_PROFILE" /> | ||||||
|     <uses-permission android:name="android.permission.INTERNET" /> |     <uses-permission android:name="android.permission.INTERNET" /> | ||||||
|  | |||||||
| @ -20,7 +20,6 @@ import android.content.Context; | |||||||
| import android.database.Cursor; | import android.database.Cursor; | ||||||
| import android.graphics.Bitmap; | import android.graphics.Bitmap; | ||||||
| import android.graphics.BitmapFactory; | import android.graphics.BitmapFactory; | ||||||
| import android.net.Uri; |  | ||||||
| 
 | 
 | ||||||
| public class Account  extends AbstractEntity{ | public class Account  extends AbstractEntity{ | ||||||
| 	 | 	 | ||||||
|  | |||||||
| @ -20,6 +20,7 @@ import android.graphics.Matrix; | |||||||
| import android.graphics.RectF; | import android.graphics.RectF; | ||||||
| import android.media.ExifInterface; | import android.media.ExifInterface; | ||||||
| import android.net.Uri; | import android.net.Uri; | ||||||
|  | import android.os.Environment; | ||||||
| import android.util.Base64; | import android.util.Base64; | ||||||
| import android.util.Base64OutputStream; | import android.util.Base64OutputStream; | ||||||
| import android.util.Log; | import android.util.Log; | ||||||
| @ -27,6 +28,7 @@ import android.util.LruCache; | |||||||
| import eu.siacs.conversations.R; | import eu.siacs.conversations.R; | ||||||
| import eu.siacs.conversations.entities.Conversation; | import eu.siacs.conversations.entities.Conversation; | ||||||
| import eu.siacs.conversations.entities.Message; | import eu.siacs.conversations.entities.Message; | ||||||
|  | import eu.siacs.conversations.services.ImageProvider; | ||||||
| import eu.siacs.conversations.utils.CryptoHelper; | import eu.siacs.conversations.utils.CryptoHelper; | ||||||
| import eu.siacs.conversations.xmpp.jingle.JingleFile; | import eu.siacs.conversations.xmpp.jingle.JingleFile; | ||||||
| import eu.siacs.conversations.xmpp.pep.Avatar; | import eu.siacs.conversations.xmpp.pep.Avatar; | ||||||
| @ -55,11 +57,11 @@ public class FileBackend { | |||||||
| 		return thumbnailCache; | 		return thumbnailCache; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public JingleFile getJingleFile(Message message) { | 	public JingleFile getJingleFileLegacy(Message message) { | ||||||
| 		return getJingleFile(message, true); | 		return getJingleFileLegacy(message, true); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public JingleFile getJingleFile(Message message, boolean decrypted) { | 	public JingleFile getJingleFileLegacy(Message message, boolean decrypted) { | ||||||
| 		Conversation conversation = message.getConversation(); | 		Conversation conversation = message.getConversation(); | ||||||
| 		String prefix = context.getFilesDir().getAbsolutePath(); | 		String prefix = context.getFilesDir().getAbsolutePath(); | ||||||
| 		String path = prefix + "/" + conversation.getAccount().getJid() + "/" | 		String path = prefix + "/" + conversation.getAccount().getJid() + "/" | ||||||
| @ -76,7 +78,28 @@ public class FileBackend { | |||||||
| 		} | 		} | ||||||
| 		return new JingleFile(path + "/" + filename); | 		return new JingleFile(path + "/" + filename); | ||||||
| 	} | 	} | ||||||
|  | 	 | ||||||
|  | 	public JingleFile getJingleFile(Message message) { | ||||||
|  | 		return getJingleFile(message, true); | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
|  | 	public JingleFile getJingleFile(Message message, boolean decrypted) { | ||||||
|  | 		StringBuilder filename = new StringBuilder(); | ||||||
|  | 		filename.append(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsolutePath()); | ||||||
|  | 		filename.append("/Conversations/"); | ||||||
|  | 		filename.append(message.getUuid()); | ||||||
|  | 		if ((decrypted) || (message.getEncryption() == Message.ENCRYPTION_NONE)) { | ||||||
|  | 			filename.append(".webp"); | ||||||
|  | 		} else { | ||||||
|  | 			if (message.getEncryption() == Message.ENCRYPTION_OTR) { | ||||||
|  | 				filename.append(".webp"); | ||||||
|  | 			} else { | ||||||
|  | 				filename.append(".webp.pgp"); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		return new JingleFile(filename.toString()); | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
| 	public Bitmap resize(Bitmap originalBitmap, int size) { | 	public Bitmap resize(Bitmap originalBitmap, int size) { | ||||||
| 		int w = originalBitmap.getWidth(); | 		int w = originalBitmap.getWidth(); | ||||||
| 		int h = originalBitmap.getHeight(); | 		int h = originalBitmap.getHeight(); | ||||||
| @ -190,8 +213,11 @@ public class FileBackend { | |||||||
| 			throws FileNotFoundException { | 			throws FileNotFoundException { | ||||||
| 		Bitmap thumbnail = thumbnailCache.get(message.getUuid()); | 		Bitmap thumbnail = thumbnailCache.get(message.getUuid()); | ||||||
| 		if ((thumbnail == null) && (!cacheOnly)) { | 		if ((thumbnail == null) && (!cacheOnly)) { | ||||||
| 			Bitmap fullsize = BitmapFactory.decodeFile(getJingleFile(message) | 			File file = getJingleFile(message); | ||||||
| 					.getAbsolutePath()); | 			if (!file.exists()) { | ||||||
|  | 				file = getJingleFileLegacy(message); | ||||||
|  | 			} | ||||||
|  | 			Bitmap fullsize = BitmapFactory.decodeFile(file.getAbsolutePath()); | ||||||
| 			if (fullsize == null) { | 			if (fullsize == null) { | ||||||
| 				throw new FileNotFoundException(); | 				throw new FileNotFoundException(); | ||||||
| 			} | 			} | ||||||
| @ -347,6 +373,15 @@ public class FileBackend { | |||||||
| 		return inSampleSize; | 		return inSampleSize; | ||||||
| 
 | 
 | ||||||
| 	} | 	} | ||||||
|  | 	 | ||||||
|  | 	public Uri getJingleFileUri(Message message) { | ||||||
|  | 		File file = getJingleFile(message); | ||||||
|  | 		if (file.exists()) { | ||||||
|  | 			return Uri.parse("file://"+file.getAbsolutePath()); | ||||||
|  | 		} else { | ||||||
|  | 			return ImageProvider.getProviderUri(message); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	public class ImageCopyException extends Exception { | 	public class ImageCopyException extends Exception { | ||||||
| 		private static final long serialVersionUID = -1010013599132881427L; | 		private static final long serialVersionUID = -1010013599132881427L; | ||||||
|  | |||||||
| @ -61,7 +61,7 @@ public class ImageProvider extends ContentProvider { | |||||||
| 			message.setConversation(conversation); | 			message.setConversation(conversation); | ||||||
| 			conversation.setAccount(account); | 			conversation.setAccount(account); | ||||||
| 	 | 	 | ||||||
| 			File file = fileBackend.getJingleFile(message); | 			File file = fileBackend.getJingleFileLegacy(message); | ||||||
| 			pfd = ParcelFileDescriptor.open(file, | 			pfd = ParcelFileDescriptor.open(file, | ||||||
| 					ParcelFileDescriptor.MODE_READ_ONLY); | 					ParcelFileDescriptor.MODE_READ_ONLY); | ||||||
| 			return pfd; | 			return pfd; | ||||||
| @ -110,7 +110,7 @@ public class ImageProvider extends ContentProvider { | |||||||
| 		return 0; | 		return 0; | ||||||
| 	} | 	} | ||||||
| 	 | 	 | ||||||
| 	public static Uri getContentUri(Message message) { | 	public static Uri getProviderUri(Message message) { | ||||||
| 		return Uri | 		return Uri | ||||||
| 				.parse("content://eu.siacs.conversations.images/" | 				.parse("content://eu.siacs.conversations.images/" | ||||||
| 						+ message.getConversationUuid() | 						+ message.getConversationUuid() | ||||||
|  | |||||||
| @ -52,8 +52,8 @@ public class MessageAdapter extends ArrayAdapter<Message> { | |||||||
| 		if (this.accountBitmap == null) { | 		if (this.accountBitmap == null) { | ||||||
| 
 | 
 | ||||||
| 			if (getCount() > 0) { | 			if (getCount() > 0) { | ||||||
| 				this.accountBitmap = getItem(0) | 				this.accountBitmap = getItem(0).getConversation().getAccount() | ||||||
| 						.getConversation().getAccount().getImage(getContext(), 48); | 						.getImage(getContext(), 48); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		return this.accountBitmap; | 		return this.accountBitmap; | ||||||
| @ -237,8 +237,8 @@ public class MessageAdapter extends ArrayAdapter<Message> { | |||||||
| 			@Override | 			@Override | ||||||
| 			public void onClick(View v) { | 			public void onClick(View v) { | ||||||
| 				Intent intent = new Intent(Intent.ACTION_VIEW); | 				Intent intent = new Intent(Intent.ACTION_VIEW); | ||||||
| 				intent.setDataAndType(ImageProvider.getContentUri(message), | 				intent.setDataAndType(activity.xmppConnectionService | ||||||
| 						"image/*"); | 						.getFileBackend().getJingleFileUri(message), "image/*"); | ||||||
| 				getContext().startActivity(intent); | 				getContext().startActivity(intent); | ||||||
| 			} | 			} | ||||||
| 		}); | 		}); | ||||||
| @ -249,7 +249,8 @@ public class MessageAdapter extends ArrayAdapter<Message> { | |||||||
| 				Intent shareIntent = new Intent(); | 				Intent shareIntent = new Intent(); | ||||||
| 				shareIntent.setAction(Intent.ACTION_SEND); | 				shareIntent.setAction(Intent.ACTION_SEND); | ||||||
| 				shareIntent.putExtra(Intent.EXTRA_STREAM, | 				shareIntent.putExtra(Intent.EXTRA_STREAM, | ||||||
| 						ImageProvider.getContentUri(message)); | 						activity.xmppConnectionService.getFileBackend() | ||||||
|  | 								.getJingleFileUri(message)); | ||||||
| 				shareIntent.setType("image/webp"); | 				shareIntent.setType("image/webp"); | ||||||
| 				getContext().startActivity( | 				getContext().startActivity( | ||||||
| 						Intent.createChooser(shareIntent, | 						Intent.createChooser(shareIntent, | ||||||
| @ -269,7 +270,7 @@ public class MessageAdapter extends ArrayAdapter<Message> { | |||||||
| 			switch (type) { | 			switch (type) { | ||||||
| 			case SENT: | 			case SENT: | ||||||
| 				view = (View) activity.getLayoutInflater().inflate( | 				view = (View) activity.getLayoutInflater().inflate( | ||||||
| 						R.layout.message_sent, parent,false); | 						R.layout.message_sent, parent, false); | ||||||
| 				viewHolder.message_box = (LinearLayout) view | 				viewHolder.message_box = (LinearLayout) view | ||||||
| 						.findViewById(R.id.message_box); | 						.findViewById(R.id.message_box); | ||||||
| 				viewHolder.contact_picture = (ImageView) view | 				viewHolder.contact_picture = (ImageView) view | ||||||
| @ -287,7 +288,7 @@ public class MessageAdapter extends ArrayAdapter<Message> { | |||||||
| 				break; | 				break; | ||||||
| 			case RECIEVED: | 			case RECIEVED: | ||||||
| 				view = (View) activity.getLayoutInflater().inflate( | 				view = (View) activity.getLayoutInflater().inflate( | ||||||
| 						R.layout.message_recieved, parent,false); | 						R.layout.message_recieved, parent, false); | ||||||
| 				viewHolder.message_box = (LinearLayout) view | 				viewHolder.message_box = (LinearLayout) view | ||||||
| 						.findViewById(R.id.message_box); | 						.findViewById(R.id.message_box); | ||||||
| 				viewHolder.contact_picture = (ImageView) view | 				viewHolder.contact_picture = (ImageView) view | ||||||
| @ -314,7 +315,7 @@ public class MessageAdapter extends ArrayAdapter<Message> { | |||||||
| 				break; | 				break; | ||||||
| 			case STATUS: | 			case STATUS: | ||||||
| 				view = (View) activity.getLayoutInflater().inflate( | 				view = (View) activity.getLayoutInflater().inflate( | ||||||
| 						R.layout.message_status, parent,false); | 						R.layout.message_status, parent, false); | ||||||
| 				viewHolder.contact_picture = (ImageView) view | 				viewHolder.contact_picture = (ImageView) view | ||||||
| 						.findViewById(R.id.message_photo); | 						.findViewById(R.id.message_photo); | ||||||
| 				if (item.getConversation().getMode() == Conversation.MODE_SINGLE) { | 				if (item.getConversation().getMode() == Conversation.MODE_SINGLE) { | ||||||
| @ -452,7 +453,8 @@ public class MessageAdapter extends ArrayAdapter<Message> { | |||||||
| 
 | 
 | ||||||
| 		public Bitmap get(Contact contact, Context context) { | 		public Bitmap get(Contact contact, Context context) { | ||||||
| 			if (!contactBitmaps.containsKey(contact.getJid())) { | 			if (!contactBitmaps.containsKey(contact.getJid())) { | ||||||
| 				contactBitmaps.put(contact.getJid(), contact.getImage(48, context)); | 				contactBitmaps.put(contact.getJid(), | ||||||
|  | 						contact.getImage(48, context)); | ||||||
| 			} | 			} | ||||||
| 			return contactBitmaps.get(contact.getJid()); | 			return contactBitmaps.get(contact.getJid()); | ||||||
| 		} | 		} | ||||||
|  | |||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Loading…
	
		Reference in New Issue
	
	Block a user
	 iNPUTmice
						iNPUTmice