58 import android.content.Intent; |
54 import android.content.Intent; |
59 import android.content.IntentFilter; |
55 import android.content.IntentFilter; |
60 import android.content.ServiceConnection; |
56 import android.content.ServiceConnection; |
61 import android.content.SharedPreferences; |
57 import android.content.SharedPreferences; |
62 import android.content.SharedPreferences.Editor; |
58 import android.content.SharedPreferences.Editor; |
|
59 import android.graphics.Bitmap; |
63 import android.net.Uri; |
60 import android.net.Uri; |
64 import android.os.Bundle; |
61 import android.os.Bundle; |
65 import android.os.Environment; |
|
66 import android.os.IBinder; |
62 import android.os.IBinder; |
67 import android.os.RemoteException; |
63 import android.os.RemoteException; |
68 import android.preference.PreferenceManager; |
64 import android.preference.PreferenceManager; |
69 import android.provider.MediaStore; |
65 import android.provider.MediaStore; |
70 import android.util.Log; |
66 import android.util.Log; |
112 |
108 |
113 private static final int SELECT_PHOTO_DLG = 0; |
109 private static final int SELECT_PHOTO_DLG = 0; |
114 |
110 |
115 private static final int CAMERA_WITH_DATA = 0; |
111 private static final int CAMERA_WITH_DATA = 0; |
116 private static final int PHOTO_PICKED_WITH_DATA = 1; |
112 private static final int PHOTO_PICKED_WITH_DATA = 1; |
117 |
113 private static final int PHOTO_CROPPED = 2; |
118 private static final File PHOTO_DIR = new File( |
|
119 Environment.getExternalStorageDirectory() + "/DCIM/Camera"); |
|
120 |
|
121 private static final String KEY_CURRENT_PHOTO_FILE = "currentphotofile"; |
|
122 |
|
123 private static final Uri MY_AVATAR_URI = Uri.parse(AvatarProvider.CONTENT_URI + "/my_avatar"); |
|
124 |
114 |
125 private EditText mStatusMessageEditText; |
115 private EditText mStatusMessageEditText; |
126 private Toast mToast; |
116 private Toast mToast; |
127 private Button mOk; |
117 private Button mOk; |
128 private Button mClear; |
118 private Button mClear; |
129 private Button mContact; |
119 private Button mContact; |
130 private Spinner mSpinner; |
120 private Spinner mSpinner; |
131 private ImageButton mAvatar; |
121 private ImageButton mAvatar; |
132 private Uri mAvatarUri; |
122 private Uri mAvatarUri; |
|
123 private Bitmap avatarBitmap; |
133 |
124 |
134 private SharedPreferences mSettings; |
125 private SharedPreferences mSettings; |
135 private ArrayAdapter<CharSequence> mAdapter; |
126 private ArrayAdapter<CharSequence> mAdapter; |
136 private IXmppFacade mXmppFacade; |
127 private IXmppFacade mXmppFacade; |
137 private final ServiceConnection mServConn = new BeemServiceConnection(); |
128 private final ServiceConnection mServConn = new BeemServiceConnection(); |
138 private final OnClickListener mOnClickOk = new MyOnClickListener(); |
129 private final OnClickListener mOnClickOk = new MyOnClickListener(); |
139 private final BeemBroadcastReceiver mReceiver = new BeemBroadcastReceiver(); |
130 private final BeemBroadcastReceiver mReceiver = new BeemBroadcastReceiver(); |
140 private boolean mShowCurrentAvatar = true; |
131 private boolean mShowCurrentAvatar = true; |
141 private boolean mDisableAvatar; |
132 private boolean mDisableAvatar; |
142 private File mCurrentPhotoFile; |
|
143 |
133 |
144 /** |
134 /** |
145 * Constructor. |
135 * Constructor. |
146 */ |
136 */ |
147 public ChangeStatus() { |
137 public ChangeStatus() { |
202 finish(); |
189 finish(); |
203 } |
190 } |
204 bindService(new Intent(this, BeemService.class), mServConn, BIND_AUTO_CREATE); |
191 bindService(new Intent(this, BeemService.class), mServConn, BIND_AUTO_CREATE); |
205 } |
192 } |
206 |
193 |
207 /** |
|
208 * {@inheritDoc} |
|
209 */ |
|
210 @Override |
194 @Override |
211 protected void onPause() { |
195 protected void onPause() { |
212 super.onPause(); |
196 super.onPause(); |
213 unbindService(mServConn); |
197 unbindService(mServConn); |
214 } |
198 } |
215 |
199 |
216 /* (non-Javadoc) |
|
217 * @see android.app.Activity#onDestroy() |
|
218 */ |
|
219 @Override |
200 @Override |
220 protected void onDestroy() { |
201 protected void onDestroy() { |
221 super.onDestroy(); |
202 super.onDestroy(); |
222 this.unregisterReceiver(mReceiver); |
203 this.unregisterReceiver(mReceiver); |
223 } |
204 } |
224 |
|
225 /* |
|
226 * The activity is often reclaimed by the system memory. |
|
227 */ |
|
228 @Override |
|
229 protected void onSaveInstanceState(Bundle outState) { |
|
230 if (mCurrentPhotoFile != null) { |
|
231 outState.putString(KEY_CURRENT_PHOTO_FILE, mCurrentPhotoFile.toString()); |
|
232 } |
|
233 super.onSaveInstanceState(outState); |
|
234 } |
|
235 |
|
236 @Override |
|
237 protected void onRestoreInstanceState(Bundle savedInstanceState) { |
|
238 String fileName = savedInstanceState.getString(KEY_CURRENT_PHOTO_FILE); |
|
239 if (fileName != null) { |
|
240 mCurrentPhotoFile = new File(fileName); |
|
241 } |
|
242 super.onRestoreInstanceState(savedInstanceState); |
|
243 } |
|
244 |
|
245 |
|
246 |
205 |
247 @Override |
206 @Override |
248 protected Dialog onCreateDialog(int id) { |
207 protected Dialog onCreateDialog(int id) { |
249 if (id == SELECT_PHOTO_DLG) |
208 if (id == SELECT_PHOTO_DLG) |
250 return createPickPhotoDialog(); |
209 return createPickPhotoDialog(); |
251 return null; |
210 return null; |
252 } |
211 } |
253 |
212 |
254 @Override |
213 @Override |
255 protected void onActivityResult(int requestCode, int resultCode, Intent data) { |
214 protected void onActivityResult(int requestCode, int resultCode, Intent data) { |
256 // Ignore failed requests |
215 // Ignore failed requests |
257 if (resultCode != RESULT_OK) return; |
216 if (resultCode != RESULT_OK) return; |
258 |
217 |
259 switch (requestCode) { |
218 switch (requestCode) { |
260 case PHOTO_PICKED_WITH_DATA: |
219 case PHOTO_PICKED_WITH_DATA: |
261 // We tell the activity to put the result in MY_AVATAR_URI |
220 mAvatarUri = data.getData(); |
262 mAvatarUri = MY_AVATAR_URI; |
|
263 Log.d(TAG, "selected avatar uri " + mAvatarUri); |
221 Log.d(TAG, "selected avatar uri " + mAvatarUri); |
264 if (mAvatarUri != null) { |
222 if (mAvatarUri != null) { |
265 // force reload of image even it is the same uri |
|
266 mAvatar.setImageURI(null); |
|
267 mAvatar.setImageURI(mAvatarUri); |
223 mAvatar.setImageURI(mAvatarUri); |
268 mDisableAvatar = false; |
224 mDisableAvatar = false; |
269 mShowCurrentAvatar = false; |
225 mShowCurrentAvatar = false; |
|
226 avatarBitmap = null; |
270 } |
227 } |
271 break; |
228 break; |
272 |
229 case CAMERA_WITH_DATA: |
273 case CAMERA_WITH_DATA: |
230 if (!doCropPhoto(data.getData())) { |
274 doCropPhoto(mCurrentPhotoFile); |
231 mAvatarUri = data.getData(); |
275 break; |
232 mAvatar.setImageURI(mAvatarUri); |
|
233 mDisableAvatar = false; |
|
234 mShowCurrentAvatar = false; |
|
235 avatarBitmap = null; |
|
236 } |
|
237 break; |
|
238 case PHOTO_CROPPED: |
|
239 avatarBitmap = data.getParcelableExtra("data"); |
|
240 if (avatarBitmap != null) { |
|
241 mAvatar.setImageBitmap(avatarBitmap); |
|
242 mDisableAvatar = false; |
|
243 mShowCurrentAvatar = false; |
|
244 mAvatarUri = null; |
|
245 } |
|
246 break; |
276 default: |
247 default: |
277 Log.w(TAG, "onActivityResult : invalid request code"); |
248 Log.w(TAG, "onActivityResult : invalid request code"); |
278 |
|
279 } |
249 } |
280 } |
250 } |
281 |
251 |
282 /** |
252 /** |
283 * Return the status index from status the settings. |
253 * Return the status index from status the settings. |
412 } |
384 } |
413 }); |
385 }); |
414 return builder.create(); |
386 return builder.create(); |
415 } |
387 } |
416 |
388 |
417 /** |
|
418 * Create a file name for the icon photo using current time. |
|
419 * @return the filename |
|
420 */ |
|
421 private String getPhotoFileName() { |
|
422 Date date = new Date(System.currentTimeMillis()); |
|
423 SimpleDateFormat dateFormat = new SimpleDateFormat("'IMG'_yyyyMMdd_HHmmss"); |
|
424 return dateFormat.format(date) + ".jpg"; |
|
425 } |
|
426 |
389 |
427 /** |
390 /** |
428 * Launches Camera to take a picture and store it in a file. |
391 * Launches Camera to take a picture and store it in a file. |
429 */ |
392 */ |
430 protected void doTakePhoto() { |
393 protected void doTakePhoto() { |
431 try { |
394 try { |
432 // Launch camera to take photo for selected contact |
395 // Launch camera to take photo for selected contact |
433 PHOTO_DIR.mkdirs(); |
396 final Intent intent = getTakePickIntent(); |
434 mCurrentPhotoFile = new File(PHOTO_DIR, getPhotoFileName()); |
|
435 final Intent intent = getTakePickIntent(mCurrentPhotoFile); |
|
436 startActivityForResult(intent, CAMERA_WITH_DATA); |
397 startActivityForResult(intent, CAMERA_WITH_DATA); |
437 } catch (ActivityNotFoundException e) { |
398 } catch (ActivityNotFoundException e) { |
438 Toast.makeText(this, R.string.photoPickerNotFoundText, Toast.LENGTH_LONG).show(); |
399 Toast.makeText(this, R.string.photoPickerNotFoundText, Toast.LENGTH_LONG).show(); |
439 } |
400 } |
440 } |
401 } |
441 |
402 |
442 /** |
403 /** |
443 * Constructs an intent for capturing a photo and storing it in a temporary file. |
404 * Constructs an intent for capturing a photo and storing it in a temporary file. |
444 * @param f the temporary file to use to store the picture |
|
445 * @return the intent |
405 * @return the intent |
446 */ |
406 */ |
447 public static Intent getTakePickIntent(File f) { |
407 public static Intent getTakePickIntent() { |
448 Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE, null); |
408 Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE, null); |
449 intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f)); |
|
450 return intent; |
409 return intent; |
451 } |
410 } |
452 |
411 |
453 /** |
412 /** |
454 * Sends a newly acquired photo to Gallery for cropping. |
413 * Sends a newly acquired photo to Gallery for cropping. |
455 * @param f the image file to crop |
414 * @param uri the image file to crop |
456 */ |
415 * @return true if was able to launch a cropping activity |
457 protected void doCropPhoto(final File f) { |
416 */ |
|
417 protected boolean doCropPhoto(final Uri uri) { |
458 try { |
418 try { |
459 |
|
460 // Add the image to the media store |
|
461 // level 8 |
|
462 /* |
|
463 MediaScannerConnection.scanFile( |
|
464 this, |
|
465 new String[] { f.getAbsolutePath() }, |
|
466 new String[] { null }, |
|
467 null); |
|
468 */ |
|
469 |
|
470 // Launch gallery to crop the photo |
419 // Launch gallery to crop the photo |
471 final Intent intent = getCropImageIntent(Uri.fromFile(f)); |
420 final Intent intent = getCropImageIntent(uri); |
472 startActivityForResult(intent, PHOTO_PICKED_WITH_DATA); |
421 startActivityForResult(intent, PHOTO_CROPPED); |
|
422 return true; |
473 } catch (ActivityNotFoundException e) { |
423 } catch (ActivityNotFoundException e) { |
474 Log.e(TAG, "Cannot crop image", e); |
424 Log.e(TAG, "Cannot crop image", e); |
475 Toast.makeText(this, R.string.photoPickerNotFoundText, Toast.LENGTH_LONG).show(); |
425 Toast.makeText(this, R.string.photoPickerNotFoundText, Toast.LENGTH_LONG).show(); |
|
426 return false; |
476 } |
427 } |
477 } |
428 } |
478 |
429 |
479 /** |
430 /** |
480 * Constructs an intent for image cropping. |
431 * Constructs an intent for image cropping. |
487 intent.putExtra("crop", "true"); |
438 intent.putExtra("crop", "true"); |
488 intent.putExtra("aspectX", 1); |
439 intent.putExtra("aspectX", 1); |
489 intent.putExtra("aspectY", 1); |
440 intent.putExtra("aspectY", 1); |
490 intent.putExtra("outputX", ICON_SIZE); |
441 intent.putExtra("outputX", ICON_SIZE); |
491 intent.putExtra("outputY", ICON_SIZE); |
442 intent.putExtra("outputY", ICON_SIZE); |
492 intent.putExtra(MediaStore.EXTRA_OUTPUT, MY_AVATAR_URI); |
443 intent.putExtra("return-data", true); |
493 return intent; |
444 return intent; |
494 } |
445 } |
495 |
446 |
496 /** |
447 /** |
497 * Launches Gallery to pick a photo. |
448 * Launches Gallery to pick a photo. |
516 intent.putExtra("crop", "true"); |
467 intent.putExtra("crop", "true"); |
517 intent.putExtra("aspectX", 1); |
468 intent.putExtra("aspectX", 1); |
518 intent.putExtra("aspectY", 1); |
469 intent.putExtra("aspectY", 1); |
519 intent.putExtra("outputX", ICON_SIZE); |
470 intent.putExtra("outputX", ICON_SIZE); |
520 intent.putExtra("outputY", ICON_SIZE); |
471 intent.putExtra("outputY", ICON_SIZE); |
521 intent.putExtra(MediaStore.EXTRA_OUTPUT, MY_AVATAR_URI); |
|
522 // use this to get the bitmap in the intent |
472 // use this to get the bitmap in the intent |
523 // intent.putExtra("return-data", true); |
473 intent.putExtra("return-data", true); |
524 return intent; |
474 return intent; |
525 } |
475 } |
526 |
476 |
527 |
477 |
528 |
478 |