2016-01-02 2 views
5

Я искал высоко и низко, чтобы найти пример того, как реализовать изменения изображения профиля в моем приложении. Я хочу, чтобы люди добавляли/изменяли изображение своего профиля с помощью Parse.com (похоже на все приложения для социальных сетей сегодня).Как создать приложение, которое позволяет загружать/изменять изображение профиля?

Например: Twitter, Facebook, Instagram и т. Д. Все они позволяют вам загружать или загружать изображение профиля, и это изображение сохраняется и может быть просмотрено позже.

у меня не было никакой удачи в поиске какой-либо материал, который охватывает как сделать такую ​​вещь, и нет другого, кажется, понимание того, что я пытаюсь достичь здесь:

An Image Downloaded From Parse Stay On Screen Even After You Exit And Reopen App?

До сих пор в моем приложении пользователь может сделать снимок с намерением камеры или загрузить изображение из галереи, и это изображение будет отображаться в представлении изображения отлично.

Проблема заключается в следующем: Когда я выхожу и снова открываю приложение, изображение внутри образа изображения больше не отображается (оно исчезло).

Как я могу решить эту проблему?

MainActivity:

 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 
ParseQuery<ParseObject> imagesQuery = new ParseQuery<>("ImageUploads"); 
      imagesQuery.orderByDescending("createdAt"); 
      imagesQuery.findInBackground(new FindCallback<ParseObject>() { 
       @Override 
       public void done(List<ParseObject> 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); 
     } 
    } 

ответ

2

Во-первых, я должен сказать, что это очень хорошо сформулировал вопрос, и я был бы рад, что каждый парень с небольшим количеством репутации спрашивает так хорошо сформулированные вопросы.

Проблема, с которой вы столкнулись, в основном связана с жизненным циклом Android-активности. Я думаю, проблема действительно тривиальна: я не вижу в вашей деятельности onCreate() места, где вы извлекаете изображение из Parse: ваш метод загрузки вызывается только в onClickListener.

Так вместо того, чтобы его здесь, я бы извлечь его методом private, вроде что-то вроде этого:

Edit:

private void queryImagesFromParse(){ 
     ParseQuery<ParseObject> imagesQuery = new ParseQuery<>("User"); 
     imagesQuery.findInBackground(new FindCallback<ParseObject>() { 
      @Override 
      public void done(List<ParseObject> 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)

Btw, очень хорошо, что вы используете Picasso, но это может быть лучше отформатируйте ее с Context из ваших Activity так Picasso.with(MainActivity.this).load(imgUrl).into(mProfilePic); вместо Picasso.with(getApplicationContext()).load(imgUrl).into(mProfilePic); (должно быть 1 нс быстрее!)

Edit: быть также уверены, что изображение является загрузка и запрашиваются из таблицы пользователей грамматического разбора это будет убедитесь, что каждый пользователь увидит свое собственное изображение (в настоящее время он зарегистрирован в имени пользователя возраст), а не всех остальных пользователей, загружающих следующее изображение.

Надеюсь, это поможет!

+1

Огромное спасибо за ваш ответ и за ваш комплимент. Я думал, что я останусь в затруднительном положении с этим вопросом без какой-либо помощи, поэтому ваша помощь очень ценится. Когда я вернусь домой, я попробую ваш подход, и если у меня возникнут какие-либо дополнительные проблемы, я дам вам знать. – Equivocal

+0

Я внес изменения в код, и он все еще не работает. Возможно, я не сделал то, что вы сказали правильно, но я не уверен. Я сделал, чтобы создать метод вне onCreate и поместить содержимое запроса внутри этого метода, чем вызвать этот метод внутри onClick внутри onCreate. – Equivocal

+0

Да, отлично, но вы тоже забыли назвать его в 'onCreate', не так ли? Вы также должны вызвать его в 'onCreate', чтобы он загружался в первый раз. –

Смежные вопросы