web-dev-qa-db-ja.com

プロフィール写真のアップロード/変更を可能にするアプリを作成するにはどうすればよいですか?

私は自分のアプリ内でプロフィール写真の変更を実装する方法の例を見つけるために高低を検索してきました。 Parse.comを使用してプロフィール画像を追加/変更できるようにしたい(今日のすべてのソーシャルメディアアプリと同様)。

例:Twitter、Facebook、Instagramなど、すべてプロファイル画像を取得/アップロードでき、その画像は保存されて表示できます後で。

私はそのようなことを行う方法をカバーする資料を見つけることができず、私がここで達成しようとしていることを理解している人は他にいないようです:

解析からダウンロードした画像は、アプリを終了して再度開いた後も画面に表示されたままですか?

これまでのところ、私のアプリでは、ユーザーはカメラインテントで写真を撮ったり、ギャラリーから画像をアップロードしたりでき、その画像は画像ビューに完全に表示されます。

問題は次のとおりです:アプリを終了して再度開くと、画像ビュー内の画像が表示されなくなります(消えます)。

どうすればこの問題を解決できますか?

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

まず、これは非常によく定式化された質問であると言わなければなりません。評判の低いすべての人が非常によく定式化された質問をすることを嬉しく思います。

発生する問題は基本的にAndroidアクティビティライフサイクルの問題です。問題は非常に些細なことだと思います。アクティビティonCreate()のどこにも画像を取得する場所がありません。解析から:ダウンロードメソッドはonClickListenerでのみ呼び出されます。

したがって、ここに置く代わりに、次のようなprivateメソッドに抽出します。

編集:

   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の場合に実際に発生することです)

ところで、Picassoを使用するのは非常に良いですが、ContextActivityで初期化する方がよいので、Picasso.with(MainActivity.this).load(imgUrl).into(mProfilePic);ではなくPicasso.with(getApplicationContext()).load(imgUrl).into(mProfilePic);を使用します。 (1 ns速くなるはずです!)

編集:また、画像がアップロードされ、ParseのUserテーブルからクエリされていることを確認してください。これにより、各ユーザーには、他のすべての画像ではなく、自分の画像(現在ログインしているユーザーの画像)が表示されます。次の画像をアップロードするユーザー。

それが役に立てば幸い!

5
Laurent Meyer