2016-01-02 8 views
5

Szukałem wysokiego i niskiego poziomu, aby znaleźć przykład, jak zaimplementować zmiany obrazu profilu w mojej aplikacji. Chcę umożliwić osobom dodawanie/zmianę ich wizerunku profilowego za pomocą Parse.com (Podobne do wszystkich dzisiejszych aplikacji społecznościowych).Jak utworzyć aplikację, która umożliwia przesłanie/zmianę obrazu profilu?

Na przykład: Twitter, Facebook, Instagram i tak dalej, wszystkie pozwalają na pobranie/przesłanie obrazu profilu, który jest zapisany i można go oglądać później.

nie miałem szczęścia ze znalezieniem jakiegokolwiek materiału, który obejmuje, jak zrobić coś takiego, a nie innego wydaje się zrozumieć, co próbuję osiągnąć tutaj:

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

tej pory w moim app użytkownik może zrobić zdjęcie z intencją kamery lub przesłać obraz z galerii i ten obraz jest doskonale wyświetlany w widoku obrazu.

Problem: po wyjściu i ponownym otwarciu aplikacji obraz wewnątrz widoku obrazu nie jest już wyświetlany (zniknął).

Jak mogę rozwiązać ten problem?

główną działalność:

 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); 
     } 
    } 

Odpowiedz

2

Po pierwsze, muszę powiedzieć, że to naprawdę dobrze sformułowane pytanie i byłbym szczęśliwy, że każdy facet z niewielu tak dobrych reputacji pyta sformułowane pytania.

Wystąpił problem to w zasadzie problem z cyklem życia aplikacji Android. Chyba problem jest naprawdę trywialny: nigdzie nie widzę miejsca, w którym pobierasz obraz z analizy: twoja metoda pobierania jest wywoływana tylko w onClickListener.

Więc zamiast go tutaj, chciałbym wyodrębnić go do sposobu private, rodzaj coś takiego:

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(); 
       } 
      } 
     }); 
    } 

(Powyższy kod jest tylko dać chropowaty pomysł, byłbym zdziwiony, gdyby go skompilował).

A następnie, możesz nazwać tę metodę na końcu onCreate() (onStart może również działać, ale wolałbym onCreate()). Oczywiście, można wywołać tej metody także od miejsca, gdzie było wcześniej (to jest rzeczywiście to, co się dzieje, jeśli dosłownie extract metoda Right-Click>Refractor>Extract Method)

Btw, bardzo dobrze, że używasz Picasso ale może to być lepiej zainicjować go z Context twojego Activity tak Picasso.with(MainActivity.this).load(imgUrl).into(mProfilePic); zamiast Picasso.with(getApplicationContext()).load(imgUrl).into(mProfilePic); (powinien być 1 ns szybciej!)

Edit: Upewnij się również, że obraz jest w trakcie wysyłania i zapytał z tabeli użytkownika na przeanalizować ten będzie upewnij się, że każdy użytkownik zobaczy własny obraz (aktualnie zalogowany użytkownik im wiek), a nie każdego innego użytkownika, który przesyła następny obraz.

Mam nadzieję, że pomoże!

+1

Dziękuję bardzo za odpowiedź i za twój komplement. Pomyślałem, że zostanę pozostawiony sam na sam z tym pytaniem bez żadnej pomocy, więc twoja pomoc jest bardzo ceniona. Kiedy wrócę do domu, spróbuję Twojego podejścia i jeśli napotkam jakiekolwiek dalsze problemy, dam ci znać. – Equivocal

+0

Wprowadziłem zmiany do kodu i nadal nie działa Mogłem nie zrobić tego, co powiedziałeś poprawnie, ale nie jestem pewien. To, co zrobiłem, to stworzyć metodę poza onCreate i umieścić zawartość zapytania wewnątrz tej metody, niż wywołać tę metodę wewnątrz onClick w onCreate. – Equivocal

+0

Tak, idealnie, ale zapomniałeś zadzwonić również w "onCreate", prawda? Musisz wywołać to również w 'onCreate', aby załadować go za pierwszym razem. –