PublishProfilePictureActivity.java

  1package eu.siacs.conversations.ui;
  2
  3import android.app.PendingIntent;
  4import android.content.Intent;
  5import android.content.pm.PackageManager;
  6import android.graphics.Bitmap;
  7import android.net.Uri;
  8import android.os.Bundle;
  9import android.view.Menu;
 10import android.view.MenuItem;
 11import android.view.View;
 12import android.view.View.OnClickListener;
 13import android.view.View.OnLongClickListener;
 14import android.widget.Button;
 15import android.widget.ImageView;
 16import android.widget.TextView;
 17import android.widget.Toast;
 18
 19import com.soundcloud.android.crop.Crop;
 20
 21import java.io.File;
 22
 23import eu.siacs.conversations.Config;
 24import eu.siacs.conversations.R;
 25import eu.siacs.conversations.entities.Account;
 26import eu.siacs.conversations.persistance.FileBackend;
 27import eu.siacs.conversations.utils.FileUtils;
 28import eu.siacs.conversations.utils.PhoneHelper;
 29import eu.siacs.conversations.xmpp.pep.Avatar;
 30
 31public class PublishProfilePictureActivity extends XmppActivity {
 32
 33	private static final int REQUEST_CHOOSE_FILE_AND_CROP = 0xac23;
 34	private static final int REQUEST_CHOOSE_FILE = 0xac24;
 35	private ImageView avatar;
 36	private TextView accountTextView;
 37	private TextView hintOrWarning;
 38	private TextView secondaryHint;
 39	private Button cancelButton;
 40	private Button publishButton;
 41	private Uri avatarUri;
 42	private Uri defaultUri;
 43	private Account account;
 44	private boolean support = false;
 45	private OnLongClickListener backToDefaultListener = new OnLongClickListener() {
 46
 47		@Override
 48		public boolean onLongClick(View v) {
 49			avatarUri = defaultUri;
 50			loadImageIntoPreview(defaultUri);
 51			return true;
 52		}
 53	};
 54	private boolean mInitialAccountSetup;
 55	private UiCallback<Avatar> avatarPublication = new UiCallback<Avatar>() {
 56
 57		@Override
 58		public void success(Avatar object) {
 59			runOnUiThread(new Runnable() {
 60
 61				@Override
 62				public void run() {
 63					if (mInitialAccountSetup) {
 64						Intent intent = new Intent(getApplicationContext(),
 65								StartConversationActivity.class);
 66						intent.putExtra("init", true);
 67						startActivity(intent);
 68					}
 69					Toast.makeText(PublishProfilePictureActivity.this,
 70							R.string.avatar_has_been_published,
 71							Toast.LENGTH_SHORT).show();
 72					finish();
 73				}
 74			});
 75		}
 76
 77		@Override
 78		public void error(final int errorCode, Avatar object) {
 79			runOnUiThread(new Runnable() {
 80
 81				@Override
 82				public void run() {
 83					hintOrWarning.setText(errorCode);
 84					hintOrWarning.setTextColor(getWarningTextColor());
 85					publishButton.setText(R.string.publish);
 86					enablePublishButton();
 87				}
 88			});
 89
 90		}
 91
 92		@Override
 93		public void userInputRequried(PendingIntent pi, Avatar object) {
 94		}
 95	};
 96
 97	@Override
 98	public void onCreate(Bundle savedInstanceState) {
 99		super.onCreate(savedInstanceState);
100		setContentView(R.layout.activity_publish_profile_picture);
101		this.avatar = (ImageView) findViewById(R.id.account_image);
102		this.cancelButton = (Button) findViewById(R.id.cancel_button);
103		this.publishButton = (Button) findViewById(R.id.publish_button);
104		this.accountTextView = (TextView) findViewById(R.id.account);
105		this.hintOrWarning = (TextView) findViewById(R.id.hint_or_warning);
106		this.secondaryHint = (TextView) findViewById(R.id.secondary_hint);
107		this.publishButton.setOnClickListener(new OnClickListener() {
108
109			@Override
110			public void onClick(View v) {
111				if (avatarUri != null) {
112					publishButton.setText(R.string.publishing);
113					disablePublishButton();
114					xmppConnectionService.publishAvatar(account, avatarUri,
115							avatarPublication);
116				}
117			}
118		});
119		this.cancelButton.setOnClickListener(new OnClickListener() {
120
121			@Override
122			public void onClick(View v) {
123				if (mInitialAccountSetup) {
124					Intent intent = new Intent(getApplicationContext(),
125							StartConversationActivity.class);
126					if (xmppConnectionService != null && xmppConnectionService.getAccounts().size() == 1) {
127						intent.putExtra("init", true);
128					}
129					startActivity(intent);
130				}
131				finish();
132			}
133		});
134		this.avatar.setOnClickListener(new OnClickListener() {
135
136			@Override
137			public void onClick(View v) {
138				if (hasStoragePermission(REQUEST_CHOOSE_FILE)) {
139					chooseAvatar(false);
140				}
141
142			}
143		});
144		this.defaultUri = PhoneHelper.getProfilePictureUri(getApplicationContext());
145	}
146
147	private void chooseAvatar(boolean crop) {
148		Intent attachFileIntent = new Intent();
149		attachFileIntent.setType("image/*");
150		attachFileIntent.setAction(Intent.ACTION_GET_CONTENT);
151		Intent chooser = Intent.createChooser(attachFileIntent, getString(R.string.attach_file));
152		startActivityForResult(chooser, crop ? REQUEST_CHOOSE_FILE_AND_CROP : REQUEST_CHOOSE_FILE);
153	}
154
155	@Override
156	public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
157		if (grantResults.length > 0)
158			if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
159				if (requestCode == REQUEST_CHOOSE_FILE_AND_CROP) {
160					chooseAvatar(true);
161				} else if (requestCode == REQUEST_CHOOSE_FILE) {
162					chooseAvatar(false);
163				}
164			} else {
165				Toast.makeText(this, R.string.no_storage_permission, Toast.LENGTH_SHORT).show();
166			}
167	}
168
169	@Override
170	public boolean onCreateOptionsMenu(Menu menu) {
171		getMenuInflater().inflate(R.menu.publish_avatar, menu);
172		return super.onCreateOptionsMenu(menu);
173	}
174
175	@Override
176	public boolean onOptionsItemSelected(final MenuItem item) {
177		if (item.getItemId() == R.id.action_crop_image) {
178			if (hasStoragePermission(REQUEST_CHOOSE_FILE_AND_CROP)) {
179				chooseAvatar(true);
180			}
181			return true;
182		} else {
183			return super.onOptionsItemSelected(item);
184		}
185	}
186
187	@Override
188	protected void onActivityResult(int requestCode, int resultCode, final Intent data) {
189		super.onActivityResult(requestCode, resultCode, data);
190		if (resultCode == RESULT_OK) {
191			Uri source = data.getData();
192			switch (requestCode) {
193				case REQUEST_CHOOSE_FILE_AND_CROP:
194					if (FileBackend.weOwnFile(this, source)) {
195						Toast.makeText(this,R.string.security_error_invalid_file_access,Toast.LENGTH_SHORT).show();
196						return;
197					}
198					String original = FileUtils.getPath(this, source);
199					if (original != null) {
200						source = Uri.parse("file://"+original);
201					}
202					Uri destination = Uri.fromFile(new File(getCacheDir(), "croppedAvatar"));
203					final int size = getPixel(192);
204					Crop.of(source, destination).asSquare().withMaxSize(size, size).start(this);
205					break;
206				case REQUEST_CHOOSE_FILE:
207					if (FileBackend.weOwnFile(this, source)) {
208						Toast.makeText(this,R.string.security_error_invalid_file_access,Toast.LENGTH_SHORT).show();
209						return;
210					}
211					this.avatarUri = source;
212					if (xmppConnectionServiceBound) {
213						loadImageIntoPreview(this.avatarUri);
214					}
215					break;
216				case Crop.REQUEST_CROP:
217					this.avatarUri = Uri.fromFile(new File(getCacheDir(), "croppedAvatar"));
218					if (xmppConnectionServiceBound) {
219						loadImageIntoPreview(this.avatarUri);
220					}
221					break;
222			}
223		} else {
224			if (requestCode == Crop.REQUEST_CROP  && data != null) {
225				Throwable throwable = Crop.getError(data);
226				if (throwable != null && throwable instanceof OutOfMemoryError) {
227					Toast.makeText(this,R.string.selection_too_large, Toast.LENGTH_SHORT).show();
228				}
229			}
230		}
231	}
232
233	@Override
234	protected void onBackendConnected() {
235		this.account = extractAccount(getIntent());
236		if (this.account != null) {
237			if (this.account.getXmppConnection() != null) {
238				this.support = this.account.getXmppConnection().getFeatures().pep();
239			}
240			if (this.avatarUri == null) {
241				if (this.account.getAvatar() != null
242						|| this.defaultUri == null) {
243					this.avatar.setImageBitmap(avatarService().get(account, getPixel(192)));
244					if (this.defaultUri != null) {
245						this.avatar
246								.setOnLongClickListener(this.backToDefaultListener);
247					} else {
248						this.secondaryHint.setVisibility(View.INVISIBLE);
249					}
250					if (!support) {
251						this.hintOrWarning
252								.setTextColor(getWarningTextColor());
253						if (account.getStatus() == Account.State.ONLINE) {
254							this.hintOrWarning.setText(R.string.error_publish_avatar_no_server_support);
255						} else {
256							this.hintOrWarning.setText(R.string.error_publish_avatar_offline);
257						}
258					}
259				} else {
260					this.avatarUri = this.defaultUri;
261					loadImageIntoPreview(this.defaultUri);
262					this.secondaryHint.setVisibility(View.INVISIBLE);
263				}
264			} else {
265				loadImageIntoPreview(avatarUri);
266			}
267			String account;
268			if (Config.DOMAIN_LOCK != null) {
269				account = this.account.getJid().getLocalpart();
270			} else {
271				account = this.account.getJid().toBareJid().toString();
272			}
273			this.accountTextView.setText(account);
274		}
275	}
276
277	@Override
278	protected void onStart() {
279		super.onStart();
280		if (getIntent() != null) {
281			this.mInitialAccountSetup = getIntent().getBooleanExtra("setup", false);
282		}
283		if (this.mInitialAccountSetup) {
284			this.cancelButton.setText(R.string.skip);
285		}
286	}
287
288	protected void loadImageIntoPreview(Uri uri) {
289		Bitmap bm = null;
290		try {
291			bm = xmppConnectionService.getFileBackend().cropCenterSquare(uri, getPixel(192));
292		} catch (Exception e) {
293			e.printStackTrace();
294		}
295
296		if (bm == null) {
297			disablePublishButton();
298			this.hintOrWarning.setTextColor(getWarningTextColor());
299			this.hintOrWarning
300					.setText(R.string.error_publish_avatar_converting);
301			return;
302		}
303		this.avatar.setImageBitmap(bm);
304		if (support) {
305			enablePublishButton();
306			this.publishButton.setText(R.string.publish);
307			this.hintOrWarning.setText(R.string.publish_avatar_explanation);
308			this.hintOrWarning.setTextColor(getPrimaryTextColor());
309		} else {
310			disablePublishButton();
311			this.hintOrWarning.setTextColor(getWarningTextColor());
312			if (account.getStatus() == Account.State.ONLINE) {
313				this.hintOrWarning.setText(R.string.error_publish_avatar_no_server_support);
314			} else {
315				this.hintOrWarning.setText(R.string.error_publish_avatar_offline);
316			}
317		}
318		if (this.defaultUri != null && uri.equals(this.defaultUri)) {
319			this.secondaryHint.setVisibility(View.INVISIBLE);
320			this.avatar.setOnLongClickListener(null);
321		} else if (this.defaultUri != null) {
322			this.secondaryHint.setVisibility(View.VISIBLE);
323			this.avatar.setOnLongClickListener(this.backToDefaultListener);
324		}
325	}
326
327	protected void enablePublishButton() {
328		this.publishButton.setEnabled(true);
329		this.publishButton.setTextColor(getPrimaryTextColor());
330	}
331
332	protected void disablePublishButton() {
333		this.publishButton.setEnabled(false);
334		this.publishButton.setTextColor(getSecondaryTextColor());
335	}
336
337	public void refreshUiReal() {
338		//nothing to do. This Activity doesn't implement any listeners
339	}
340}