我一直在寻找一个如何在我的应用程序中实现配置文件图片更改的示例.我想允许人们使用Parse.com添加/更改他们的个人资料图片(类似于今天的所有社交媒体应用程序).
例如: Twitter,Facebook,Instagram等,它们都允许您拍摄/上传个人资料图像,并保存该图像,以后可以查看.
我没有找到任何材料来解决如何做这样的事情,似乎没有其他人理解我在这里想要实现的目标:
即使在退出并重新打开应用程序后,图像也会从屏幕上停留下来?
到目前为止,在我的应用程序中,用户可以使用相机意图拍摄照片或从图库上传图像,该图像将在图像视图中完美显示.
问题是:当我退出并重新打开应用程序时,图像视图内的图像不再显示(它已消失).
我怎么解决这个问题?
主要活动:
public class MainActivity extends AppCompatActivity { public static final int TAKE_PIC_REQUEST_CODE = 0; public static final int CHOOSE_PIC_REQUEST_CODE = 1; public static final int MEDIA_TYPE_IMAGE = 2; private Uri mMediaUri; private TextView mChangeProfilePic; protected ImageView mPreviewImageView; private Button mSaveChangesBtn; public ImageView mProfilePic; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) .setAction("Action", null).show(); } }); //Initialize variables mChangeProfilePic = (TextView) findViewById(R.id.changeProfileImageTxt); mPreviewImageView = (ImageView) findViewById(R.id.profileImage); mSaveChangesBtn = (Button) findViewById(R.id.saveProfileChangesBtn); mSaveChangesBtn.setEnabled(false); final Button mNextBtn = (Button) findViewById(R.id.NextBtn); mNextBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intentNext = new Intent(MainActivity.this, SecondActivity.class); startActivity(intentNext); } }); //Change profile image //set onlClick to TextView mChangeProfilePic.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(getApplicationContext(), "Change Pic Pressed", Toast.LENGTH_SHORT).show(); //show dialog AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this); builder.setTitle("Upload or Take a photo"); builder.setPositiveButton("Upload", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { //upload image Intent choosePictureIntent = new Intent(Intent.ACTION_GET_CONTENT); choosePictureIntent.setType("image/*"); startActivityForResult(choosePictureIntent, CHOOSE_PIC_REQUEST_CODE); mSaveChangesBtn.setEnabled(true); } }); builder.setNegativeButton("Take Photo", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { //take photo Intent takePicture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); mMediaUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE); if (mMediaUri == null) { //display error Toast.makeText(getApplicationContext(), "Sorry there was an error! Try again.", Toast.LENGTH_LONG).show(); mSaveChangesBtn.setEnabled(false); } else { takePicture.putExtra(MediaStore.EXTRA_OUTPUT, mMediaUri); startActivityForResult(takePicture, TAKE_PIC_REQUEST_CODE); mSaveChangesBtn.setEnabled(true); } } }); AlertDialog dialog = builder.create(); dialog.show(); } });//End change profile image onClick Listener //Save profile changes button //Also uploads content to parse and pulls it back same time mSaveChangesBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //create parse object for image to upload final ParseObject imageUpload = new ParseObject("ImageUploads"); try { //convert image to bytes for upload. byte[] fileBytes = FileHelper.getByteArrayFromFile(MainActivity.this, mMediaUri); if (fileBytes == null) { //there was an error Toast.makeText(getApplicationContext(), "There was an error. Try again!", Toast.LENGTH_LONG).show(); mSaveChangesBtn.setEnabled(false); } else { fileBytes = FileHelper.reduceImageForUpload(fileBytes); String fileName = FileHelper.getFileName(MainActivity.this, mMediaUri, "image"); final ParseFile file = new ParseFile(fileName, fileBytes); imageUpload.saveEventually(new SaveCallback() { @Override public void done(ParseException e) { if (e == null) { imageUpload.put("imageContent", file); imageUpload.saveInBackground(new SaveCallback() { @Override public void done(ParseException e) { Toast.makeText(getApplicationContext(), "Success Uploading iMage!", Toast.LENGTH_LONG).show(); //Retrieve the recently saved image from Parse queryParseProfileImages(imageUpload); mSaveChangesBtn.setEnabled(false); } } ); } else { //there was an error Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show(); mSaveChangesBtn.setEnabled(false); } } }); } } catch (Exception e1) { Toast.makeText(getApplicationContext(), e1.getMessage(), Toast.LENGTH_LONG).show(); } }//End onClick(View v) });//End onClick Listener //This method queries for the most recent picture taken ParseQueryimagesQuery = new ParseQuery<>("ImageUploads"); imagesQuery.orderByDescending("createdAt"); imagesQuery.findInBackground(new FindCallback () { @Override public void done(List images, ParseException e) { if(e == null){ //for (int i = 0; i < images.size(); i++) { final String imgUrl = images.get(0).getParseFile("imageContent").getUrl(); mProfilePic = (ImageView) findViewById(R.id.profileImage); Picasso.with(MainActivity.this).load(imgUrl).into(mProfilePic); //} //images.pinInBackground(); //profileImageId = profImgObj.getObjectId(); //Log.d(TAG, "The object id is: " + profileImageId); }else{ Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_LONG).show(); } } }); }//End onCreate //Method containing ParseQuery to download/pull back the image that was uploaded to Parse //Inside the Image View private void queryParseProfileImages(final ParseObject imageUploadPassed) { ParseFile userImageRetrievedObj = (ParseFile) imageUploadPassed.get("imageContent"); userImageRetrievedObj.getDataInBackground(new GetDataCallback() { public void done(byte[] data, ParseException e) { if (e == null) { final String imgUrl = imageUploadPassed.getParseFile("imageContent").getUrl(); mProfilePic = (ImageView) findViewById(R.id.profileImage); Picasso.with(MainActivity.this).load(imgUrl).into(mProfilePic); imageUploadPassed.pinInBackground(); } else { // something went wrong } } }); } //inner helper method private Uri getOutputMediaFileUri(int mediaTypeImage) { if (isExternalStorageAvailable()) { //get the URI //get external storage dir File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "UPLOADIMAGES"); //create subdirectore if it does not exist if (!mediaStorageDir.exists()) { //create dir if (!mediaStorageDir.mkdirs()) { return null; } } //create a file name //create file File mediaFile = null; Date now = new Date(); String timestamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(now); String path = mediaStorageDir.getPath() + File.separator; if (mediaTypeImage == MEDIA_TYPE_IMAGE) { mediaFile = new File(path + "IMG_" + timestamp + ".jpg"); } //return file uri Log.d("UPLOADIMAGE", "FILE: " + Uri.fromFile(mediaFile)); return Uri.fromFile(mediaFile); } else { return null; } } //check if external storage is mounted. helper method private boolean isExternalStorageAvailable() { String state = Environment.getExternalStorageState(); if (state.equals(Environment.MEDIA_MOUNTED)) { return true; } else { return false; } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_OK) { if (requestCode == CHOOSE_PIC_REQUEST_CODE) { if (data == null) { Toast.makeText(getApplicationContext(), "Image cannot be null!", Toast.LENGTH_LONG).show(); } else { mMediaUri = data.getData(); //set previews mPreviewImageView.setImageURI(mMediaUri); //Bundle extras = data.getExtras(); //Log.e("URI", mMediaUri.toString()); //Bitmap bmp = (Bitmap) extras.get("data"); } } else { Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); mediaScanIntent.setData(mMediaUri); sendBroadcast(mediaScanIntent); //set previews mPreviewImageView.setImageURI(mMediaUri); } } else if (resultCode != RESULT_CANCELED) { Toast.makeText(getApplicationContext(), "Cancelled!", Toast.LENGTH_LONG).show(); } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } }
Laurent Meye.. 5
首先,我必须说这是一个非常好的公式化问题,我很高兴每个名誉不高的人都提出如此好的公式化问题。
您遇到的问题基本上是Android Activity生命周期的问题。我想这个问题确实很简单:我在“活动”中onCreate()
找不到从Parse检索图像的地方:您的下载方法仅在中调用onClickListener
。
因此,我将其提取到一个private
方法中,而不是在这里,就像这样:
编辑:
private void queryImagesFromParse(){ ParseQueryimagesQuery = new ParseQuery<>("User"); imagesQuery.findInBackground(new FindCallback () { @Override public void done(List imagesItems, ParseException e) { if(e == null){ ParseUser userCurrentOfParse = ParseUser.getCurrentUser(); if(userCurrentOfParse != null) { //final String imgUrl = imageUploadPassed.getParseFile("imageContent").getUrl(); final String imgUrl = userCurrentOfParse.getParseFile("userProfilePics").getUrl(); mHomeProfilePic = (ImageView) findViewById(R.id.userHomeProfilePicImageView); Picasso.with(HomeActivity.this).load(imgUrl).into(mHomeProfilePic); //imageUploadPassed.pinInBackground(); // profileImageId = imageUploadPassed.getObjectId(); //Log.d(TAG, "The object id is: " + profileImageId); } }else{ Toast.makeText(HomeActivity.this, e.getMessage(), Toast.LENGTH_LONG).show(); } } }); }
(上面的代码只是给出一个大概的想法,如果编译的话,我会感到惊讶)。
然后,您在()的末尾调用此方法onCreate()
(onStart
也可以使用,但我更喜欢onCreate()
)。当然,你也可以调用此方法从它从前的地方(即实际上是什么,如果你从字面上发生extract
的方法Right-Click
> Refractor
> Extract Method
)
顺便说一下,很不错,你使用Picasso
,但它可能是更好地与初始化它Context
你的Activity
这样Picasso.with(MainActivity.this).load(imgUrl).into(mProfilePic);
,而不是Picasso.with(getApplicationContext()).load(imgUrl).into(mProfilePic);
(应为1纳秒更快!)
编辑:还要确保正在从Parse的User表中上载并查询该图像,这将确保每个用户将看到自己的图像(当前已登录用户的图像),而不是每个其他上传下一个图像的用户的图像。
希望能帮助到你!
首先,我必须说这是一个非常好的公式化问题,我很高兴每个名誉不高的人都提出如此好的公式化问题。
您遇到的问题基本上是Android Activity生命周期的问题。我想这个问题确实很简单:我在“活动”中onCreate()
找不到从Parse检索图像的地方:您的下载方法仅在中调用onClickListener
。
因此,我将其提取到一个private
方法中,而不是在这里,就像这样:
编辑:
private void queryImagesFromParse(){ ParseQueryimagesQuery = new ParseQuery<>("User"); imagesQuery.findInBackground(new FindCallback () { @Override public void done(List imagesItems, ParseException e) { if(e == null){ ParseUser userCurrentOfParse = ParseUser.getCurrentUser(); if(userCurrentOfParse != null) { //final String imgUrl = imageUploadPassed.getParseFile("imageContent").getUrl(); final String imgUrl = userCurrentOfParse.getParseFile("userProfilePics").getUrl(); mHomeProfilePic = (ImageView) findViewById(R.id.userHomeProfilePicImageView); Picasso.with(HomeActivity.this).load(imgUrl).into(mHomeProfilePic); //imageUploadPassed.pinInBackground(); // profileImageId = imageUploadPassed.getObjectId(); //Log.d(TAG, "The object id is: " + profileImageId); } }else{ Toast.makeText(HomeActivity.this, e.getMessage(), Toast.LENGTH_LONG).show(); } } }); }
(上面的代码只是给出一个大概的想法,如果编译的话,我会感到惊讶)。
然后,您在()的末尾调用此方法onCreate()
(onStart
也可以使用,但我更喜欢onCreate()
)。当然,你也可以调用此方法从它从前的地方(即实际上是什么,如果你从字面上发生extract
的方法Right-Click
> Refractor
> Extract Method
)
顺便说一下,很不错,你使用Picasso
,但它可能是更好地与初始化它Context
你的Activity
这样Picasso.with(MainActivity.this).load(imgUrl).into(mProfilePic);
,而不是Picasso.with(getApplicationContext()).load(imgUrl).into(mProfilePic);
(应为1纳秒更快!)
编辑:还要确保正在从Parse的User表中上载并查询该图像,这将确保每个用户将看到自己的图像(当前已登录用户的图像),而不是每个其他上传下一个图像的用户的图像。
希望能帮助到你!