Back4App 和 android studio,如何正确保存 ParseObject 错误
Posted
技术标签:
【中文标题】Back4App 和 android studio,如何正确保存 ParseObject 错误【英文标题】:Back4App and android studio , How to properly save a ParseObject Error 【发布时间】:2021-08-07 10:50:03 【问题描述】:这是我遇到的错误,由于我对 back4app 和 android studio 的理解非常有限(com.parse.ParseException: java.lang.IllegalStateException: Unable to对未保存的 ParseFile 进行编码。)。 我尝试过的一些解决方案不可行,似乎 ParseFile 没有正确保存。我已经尝试过回调函数和进度函数,但它似乎不起作用。所以在这一点上,我不知道如何解决这个问题 这是我的撰写片段的代码
package com.example.rentahome.fragments;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageDecoder;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.text.SpannableStringBuilder;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.FileProvider;
import androidx.fragment.app.Fragment;
import com.example.rentahome.ImageFilePath;
import com.example.rentahome.Post;
import com.example.rentahome.R;
import com.example.rentahome.Reviews;
import com.example.rentahome.databinding.FragmentComposeBinding;
import com.parse.Parse;
import com.parse.ParseException;
import com.parse.ParseFile;
import com.parse.ParseObject;
import com.parse.ParseRelation;
import com.parse.ParseUser;
import com.parse.ProgressCallback;
import com.parse.SaveCallback;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import static android.app.Activity.RESULT_OK;
import static com.parse.Parse.getApplicationContext;
public class ComposeFragment extends Fragment
public static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 43;
public static final int PICK_PHOTO_CODE = 21;
private File photoFile;
FragmentComposeBinding fragmentComposeBinding;
private String photoFileName = "photo.jpg";
public String realPath = new String();
public static final String TAG = "ComposeFragment";
public ComposeFragment()
// Required empty public constructor
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
return inflater.inflate(R.layout.fragment_compose, container, false);
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState)
super.onViewCreated(view, savedInstanceState);
fragmentComposeBinding = FragmentComposeBinding.bind(view);
fragmentComposeBinding.btnPicture.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
uploadImage();
);
fragmentComposeBinding.btnSubmit.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
String address = fragmentComposeBinding.etAddress.getText().toString();
String price = fragmentComposeBinding.etPrice.getText().toString();
String description = fragmentComposeBinding.etDescription.getText().toString();
if(address.isEmpty())
Toast.makeText(getContext(), "Address cannot be empty", Toast.LENGTH_SHORT).show();
return;
if(price.isEmpty())
Toast.makeText(getContext(), "Price cannot be empty", Toast.LENGTH_SHORT).show();
return;
if(description.isEmpty())
Toast.makeText(getContext(), "Description cannot be empty", Toast.LENGTH_SHORT).show();
return;
if(realPath == null || fragmentComposeBinding.ivPostImage.getDrawable()==null)
Toast.makeText(getContext(),"There is no image", Toast.LENGTH_SHORT).show();
return;
ParseUser currentUser = ParseUser.getCurrentUser();
savePost(address, price, description, currentUser);
);
private void uploadImage()
// create Intent to upload a picture and return control to the calling application
// Edit action for MediaStore
Intent intent = new Intent(Intent.ACTION_PICK,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
// Create a File reference for future access
//photoFile = getPhotoFileUri(photoFileName);
// wrap File object into a content provider
// required for API >= 24
// See https://guides.codepath.com/android/Sharing-Content-with-Intents#sharing-files-with-api-24-or-higher
//Uri fileProvider = FileProvider.getUriForFile(getContext(), "com.example.rentahome.fileprovider", photoFile);
//intent.putExtra(MediaStore.EXTRA_OUTPUT, fileProvider);
// If you call startActivityForResult() using an intent that no app can handle, your app will crash.
// So as long as the result is not null, it's safe to use the intent.
if (intent.resolveActivity(getContext().getPackageManager()) != null)
// Start the image pick intent to pick photo from external folder
startActivityForResult(intent, PICK_PHOTO_CODE);
public Bitmap loadFromUri(Uri photoUri)
Bitmap image = null;
try
// check version of Anrdoid on device
if(Build.VERSION.SDK_INT > 27)
// newer version
ImageDecoder.Source source = ImageDecoder.createSource(this.getContext().getContentResolver(), photoUri);
image = ImageDecoder.decodeBitmap(source);
else
//support older
image = MediaStore.Images.Media.getBitmap(this.getContext().getContentResolver(),photoUri);
catch (IOException e)
e.printStackTrace();
return image;
private File getPhotoFileUri(String fileName)
// Get safe storage directory for photos
// Use `getExternalFilesDir` on Context to access package-specific directories.
// This way, we don't need to request external read/write runtime permissions.
File mediaStorageDir = new File(getContext().getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), TAG);
// Create the storage directory if it does not exist
if (!mediaStorageDir.exists() && !mediaStorageDir.mkdirs())
Log.d(TAG, "failed to create directory..");
// Return the file target for the photo based on filename
File file = new File(mediaStorageDir.getPath() + File.separator + fileName);
return file;
@Override
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data)
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_PHOTO_CODE && resultCode == RESULT_OK && data != null && data.getData() != null)
Uri uri = data.getData();
realPath = ImageFilePath.getPath(getContext(), data.getData());
// realPath = RealPathUtil.getRealPathFromURI_API19(this, data.getData());
Log.i(TAG, "onActivityResult: file path : " + realPath);
Log.i(TAG, "onActivityResult: file path : " + getContext().getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).getPath() );
try
Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContext().getContentResolver(), uri);
// Log.d(TAG, String.valueOf(bitmap));
fragmentComposeBinding.ivPostImage.setImageBitmap(bitmap);
catch (IOException e)
e.printStackTrace();
else
Toast.makeText(getContext(), "Something Went Wrong", Toast.LENGTH_SHORT).show();
// if ((data != null) && requestCode == PICK_PHOTO_CODE)
// if (resultCode == RESULT_OK)
// Uri photoUri = data.getData();
// // by this point we have the camera photo on disk
// //Bitmap selectedImage = BitmapFactory.decodeFile(photoFile.getAbsolutePath());
// //Load the image located at photoUri into selectedImage
// Bitmap selectedImage = loadFromUri(photoUri);
// // RESIZE BITMAP, see section below
// // Load the taken image into a preview
// fragmentComposeBinding.ivPostImage.setImageBitmap(selectedImage);
//
// else // Result was a failure
// Toast.makeText(getContext(), "Image not found", Toast.LENGTH_SHORT).show();
//
//
private void savePost(String address, String price, String description, ParseUser currentUser)
//Post post = new Post();
ParseObject post = ParseObject.create("Post");
File file = new File(realPath);
ParseFile photo = new ParseFile(file);
photo.saveInBackground();
// post.setImage(photo);
// int parsed_price = Integer.parseInt(price);
// post.setPrice(parsed_price);
// post.setDescription(description);
// post.setUser(currentUser);
// post.setAddress(address);
// //photo.saveInBackground();
ParseRelation<ParseObject> hi;
//parse String price to int..
post.put("image",photo);
post.put("description",description);
post.put("address",address);
post.put("user",currentUser);
post.put("price",price);
//post.put("Reviews",hi);
// Reviews gameScore = new Reviews();
//
// gameScore.setlikesCount(0);
// gameScore.setdislikesCount(0);
// gameScore.setAuthor(currentUser);
// gameScore.setRating((float) (5.0));
// gameScore.setDescription("hi");
////
//// gameScore.put("Description","Hi ");
//// gameScore.put("author",currentUser);
//// gameScore.put("rating",(float)(5.0));
//// gameScore.put("likesCount",0);
//// gameScore.put("dislikesCount",0);
//
// ParseRelation<Reviews> temp = new ParseRelation<Reviews>();
// temp.add(gameScore);
post.saveInBackground(new SaveCallback()
@Override
public void done(com.parse.ParseException e)
if(e!=null)
Log.e(TAG,"Issue with saving posts..", e);
Toast.makeText(getContext(), "Error while saving", Toast.LENGTH_SHORT).show();
return;
Log.i(TAG,"Saved successfully!");
fragmentComposeBinding.etDescription.setText("");
fragmentComposeBinding.ivPostImage.setImageResource(0);
);
这是我的帖子课程,其中一个特别之处是我在帖子课程中的关系。有一个包含对象评论的评论关系
package com.example.rentahome;
import com.parse.ParseClassName;
import com.parse.ParseFile;
import com.parse.ParseObject;
import com.parse.ParseRelation;
import com.parse.ParseUser;
import java.util.ArrayList;
@ParseClassName("Post")
public class Post extends ParseObject
public static final String KEY_DESCRIPTION = "description";
public static final String KEY_IMAGE = "image"; //image should be 'uploaded'
public static final String KEY_USER = "user";
public static final String KEY_CREATED_KEY = "createdAt"; //have to figure out how to implement
public static final String KEY_address = "address";
public static final String KEY_price = "price";
public static final String KEY_reviews = "Reviews";
public static final String KEY_objectID = "objectID";
public String getDescription()
return getString(KEY_DESCRIPTION);
public void setDescription(String description)
put(KEY_DESCRIPTION, description);
public ParseFile getImage()
return getParseFile(KEY_IMAGE);
public void setImage(ParseFile parseFile)
put(KEY_IMAGE, parseFile);
public ParseUser getUser()
return getParseUser(KEY_USER);
public void setUser(ParseUser user)put(KEY_USER, user);
public String getAddress() return getString(KEY_address);
public void setAddress(String address) put(KEY_address, address);
public int getPrice()return getInt(KEY_price);
public void setPrice(int price)put(KEY_price,price);
public String getobjectID()return getString(KEY_objectID);
public ParseRelation<ParseObject> getrelation() return getRelation(KEY_reviews);
public void setrelation(ParseRelation<ParseObject> relation)put(KEY_reviews, relation);
//public ParseRelation<ParseObject> getReviews()return getRelation(KEY_reviews);
//public void setReviews(ParseRelation<ParseObject> reviews)put(KEY_reviews, reviews);
//public Date getCreatedAt() return getDate(KEY_CREATED_KEY);
我的复习课
package com.example.rentahome;
import com.parse.ParseClassName;
import com.parse.ParseObject;
import com.parse.ParseUser;
@ParseClassName("Reviews")
public class Reviews extends ParseObject
public static final String KEY_author = "author";
public static final String KEY_description = "Description";
public static final String KEY_likesCount = "likesCount";
public static final String KEY_dislikesCount = "dislikesCount";
public static final String KEY_rating = "rating";
public String getDescription()return getString(KEY_description);
public void setDescription(String description)put(KEY_description, description);
public ParseUser getAuthor()return getParseUser(KEY_author);
public void setAuthor(ParseUser author)put(KEY_author,author);
public float getRating()return (float)getDouble(KEY_rating);
public void setRating(float rating) put(KEY_rating, rating);
public int getlikesCount() return getInt(KEY_likesCount);
public void setlikesCount(int likesCount)put(KEY_likesCount, likesCount);
public int getdislikesCount() return getInt(KEY_dislikesCount);
public void setdislikesCount(int dislikesCount)put(KEY_dislikesCount, dislikesCount);
这是错误信息
E/ComposeFragment: Issue with saving posts..
com.parse.ParseException: java.lang.IllegalStateException: Unable to encode an unsaved ParseFile.
at com.parse.ParseTaskUtils$2$1.run(ParseTaskUtils.java:119)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Caused by: java.lang.IllegalStateException: Unable to encode an unsaved ParseFile.
at com.parse.ParseFile.encode(ParseFile.java:653)
at com.parse.ParseEncoder.encode(ParseEncoder.java:77)
at com.parse.ParseSetOperation.encode(ParseSetOperation.java:31)
at com.parse.ParseEncoder.encode(ParseEncoder.java:126)
at com.parse.ParseObjectCoder.encode(ParseObjectCoder.java:57)
at com.parse.NetworkObjectController.saveAsync(NetworkObjectController.java:60)
at com.parse.ParseObject$32.then(ParseObject.java:2282)
at com.parse.ParseObject$32.then(ParseObject.java:2277)
at com.parse.boltsinternal.Task$15.run(Task.java:907)
at com.parse.boltsinternal.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:113)
at com.parse.boltsinternal.Task.completeAfterTask(Task.java:898)
at com.parse.boltsinternal.Task.continueWithTask(Task.java:713)
at com.parse.boltsinternal.Task.continueWithTask(Task.java:724)
at com.parse.boltsinternal.Task$13.then(Task.java:816)
at com.parse.boltsinternal.Task$13.then(Task.java:804)
at com.parse.boltsinternal.Task$15.run(Task.java:907)
at com.parse.boltsinternal.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:113)
at com.parse.boltsinternal.Task.completeAfterTask(Task.java:898)
at com.parse.boltsinternal.Task.access$100(Task.java:28)
at com.parse.boltsinternal.Task$11.then(Task.java:706)
at com.parse.boltsinternal.Task$11.then(Task.java:703)
at com.parse.boltsinternal.Task.runContinuations(Task.java:946)
at com.parse.boltsinternal.Task.trySetResult(Task.java:984)
at com.parse.boltsinternal.TaskCompletionSource.trySetResult(TaskCompletionSource.java:45)
at com.parse.boltsinternal.TaskCompletionSource.setResult(TaskCompletionSource.java:68)
at com.parse.boltsinternal.Task$15$1.then(Task.java:924)
at com.parse.boltsinternal.Task$15$1.then(Task.java:911)
at com.parse.boltsinternal.Task$14.run(Task.java:866)
at com.parse.boltsinternal.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:113)
at com.parse.boltsinternal.Task.completeImmediately(Task.java:857)
at com.parse.boltsinternal.Task.continueWith(Task.java:659)
at com.parse.boltsinternal.Task.continueWith(Task.java:670)
at com.parse.boltsinternal.Task$15.run(Task.java:911)
at com.parse.boltsinternal.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:113)
at com.parse.boltsinternal.Task.completeAfterTask(Task.java:898)
at com.parse.boltsinternal.Task.access$100(Task.java:28)
at com.parse.boltsinternal.Task$11.then(Task.java:706)
at com.parse.boltsinternal.Task$11.then(Task.java:703)
at com.parse.boltsinternal.Task.runContinuations(Task.java:946)
at com.parse.boltsinternal.Task.trySetResult(Task.java:984)
at com.parse.boltsinternal.TaskCompletionSource.trySetResult(TaskCompletionSource.java:45)
at com.parse.boltsinternal.TaskCompletionSource.setResult(TaskCompletionSource.java:68)
at com.parse.boltsinternal.Task$8.then(Task.java:562)
at com.parse.boltsinternal.Task$8.then(Task.java:536)
at com.parse.boltsinternal.Task$14.run(Task.java:866)
at com.parse.boltsinternal.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:113)
at com.parse.boltsinternal.Task.completeImmediately(Task.java:857)
at com.parse.boltsinternal.Task.access$000(Task.java:28)
at com.parse.boltsinternal.Task$10.then(Task.java:652)
at com.parse.boltsinternal.Task$10.then(Task.java:649)
E/ComposeFragment: at com.parse.boltsinternal.Task.runContinuations(Task.java:946)
at com.parse.boltsinternal.Task.trySetResult(Task.java:984)
at com.parse.boltsinternal.TaskCompletionSource.trySetResult(TaskCompletionSource.java:45)
at com.parse.boltsinternal.TaskCompletionSource.setResult(TaskCompletionSource.java:68)
at com.parse.boltsinternal.Task$14.run(Task.java:867)
at com.parse.boltsinternal.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:113)
at com.parse.boltsinternal.Task.completeImmediately(Task.java:857)
at com.parse.boltsinternal.Task.access$000(Task.java:28)
at com.parse.boltsinternal.Task$10.then(Task.java:652)
at com.parse.boltsinternal.Task$10.then(Task.java:649)
at com.parse.boltsinternal.Task.runContinuations(Task.java:946)
at com.parse.boltsinternal.Task.trySetError(Task.java:1001)
at com.parse.boltsinternal.TaskCompletionSource.trySetError(TaskCompletionSource.java:52)
at com.parse.boltsinternal.TaskCompletionSource.setError(TaskCompletionSource.java:77)
at com.parse.boltsinternal.Task$8.then(Task.java:552)
at com.parse.boltsinternal.Task$8.then(Task.java:536)
at com.parse.boltsinternal.Task$14.run(Task.java:866)
at com.parse.boltsinternal.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:113)
at com.parse.boltsinternal.Task.completeImmediately(Task.java:857)
at com.parse.boltsinternal.Task.access$000(Task.java:28)
at com.parse.boltsinternal.Task$10.then(Task.java:652)
at com.parse.boltsinternal.Task$10.then(Task.java:649)
at com.parse.boltsinternal.Task.runContinuations(Task.java:946)
at com.parse.boltsinternal.Task.trySetError(Task.java:1001)
at com.parse.boltsinternal.TaskCompletionSource.trySetError(TaskCompletionSource.java:52)
at com.parse.boltsinternal.TaskCompletionSource.setError(TaskCompletionSource.java:77)
at com.parse.boltsinternal.Task$15$1.then(Task.java:922)
at com.parse.boltsinternal.Task$15$1.then(Task.java:911)
at com.parse.boltsinternal.Task$14.run(Task.java:866)
at com.parse.boltsinternal.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:113)
at com.parse.boltsinternal.Task.completeImmediately(Task.java:857)
at com.parse.boltsinternal.Task.access$000(Task.java:28)
at com.parse.boltsinternal.Task$10.then(Task.java:652)
at com.parse.boltsinternal.Task$10.then(Task.java:649)
at com.parse.boltsinternal.Task.runContinuations(Task.java:946)
at com.parse.boltsinternal.Task.trySetError(Task.java:1001)
at com.parse.boltsinternal.TaskCompletionSource.trySetError(TaskCompletionSource.java:52)
at com.parse.boltsinternal.TaskCompletionSource.setError(TaskCompletionSource.java:77)
at com.parse.boltsinternal.Task$15$1.then(Task.java:922)
at com.parse.boltsinternal.Task$15$1.then(Task.java:911)
at com.parse.boltsinternal.Task$14.run(Task.java:866)
at com.parse.boltsinternal.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:113)
at com.parse.boltsinternal.Task.completeImmediately(Task.java:857)
at com.parse.boltsinternal.Task.continueWith(Task.java:659)
at com.parse.boltsinternal.Task.continueWith(Task.java:670)
at com.parse.boltsinternal.Task$15.run(Task.java:911)
at com.parse.boltsinternal.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:113)
at com.parse.boltsinternal.Task.completeAfterTask(Task.java:898)
at com.parse.boltsinternal.Task.access$100(Task.java:28)
at com.parse.boltsinternal.Task$11.then(Task.java:706)
at com.parse.boltsinternal.Task$11.then(Task.java:703)
at com.parse.boltsinternal.Task.runContinuations(Task.java:946)
at com.parse.boltsinternal.Task.trySetError(Task.java:1001)
at com.parse.boltsinternal.TaskCompletionSource.trySetError(TaskCompletionSource.java:52)
at com.parse.boltsinternal.TaskCompletionSource.setError(TaskCompletionSource.java:77)
at com.parse.boltsinternal.Task$15$1.then(Task.java:922)
at com.parse.boltsinternal.Task$15$1.then(Task.java:911)
at com.parse.boltsinternal.Task$14.run(Task.java:866)
at com.parse.boltsinternal.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:113)
at com.parse.boltsinternal.Task.completeImmediately(Task.java:857)
at com.parse.boltsinternal.Task.continueWith(Task.java:659)
at com.parse.boltsinternal.Task.continueWith(Task.java:670)
at com.parse.boltsinternal.Task$15.run(Task.java:911)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:923)
【问题讨论】:
【参考方案1】:您的问题发生是因为您没有等待photo.saveInBackground
完成。您的代码应如下所示:
ParseObject post = ParseObject.create("Post");
File file = new File(realPath);
ParseFile photo = new ParseFile(file);
photo.saveInBackground(new SaveCallback()
@Override
public void done(com.parse.ParseException e)
// Handle success or failure here ...
post.put("image",photo);
post.put("description",description);
post.put("address",address);
post.put("user",currentUser);
post.put("price",price);
post.saveInBackground(new SaveCallback()
@Override
public void done(com.parse.ParseException e)
// Handle success or failure here ...
);
);
【讨论】:
很抱歉,该解决方案对我不起作用。在我放置代码并替换它之后仍然是同样的错误。仍然说 java.lang.IllegalStateException: Unable to encoding an unsaved ParseFile。我认为文件可能有问题。 您检查过e
的值吗?也许第一个请求失败了。
问题已解决。路径错了!哈哈在我这边你的代码工作得很好以上是关于Back4App 和 android studio,如何正确保存 ParseObject 错误的主要内容,如果未能解决你的问题,请参考以下文章
未收到在 Back4App 上解析的 Android 推送通知