Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialKevin Nguyen
77 PointsWhen saving in the background..app freezes before sending the message. Help please!
When I am trying to send the message I will hit the send button. The app freezes for 5secs or more before executing the send() and the finish(). Why is it freezing first before sending?
package com.thegreathoudini.kevin.odysity;
import android.app.AlertDialog;
import android.app.ListActivity;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.Toast;
import com.parse.FindCallback;
import com.parse.ParseException;
import com.parse.ParseFile;
import com.parse.ParseInstallation;
import com.parse.ParseObject;
import com.parse.ParsePush;
import com.parse.ParseQuery;
import com.parse.ParseRelation;
import com.parse.ParseUser;
import com.parse.SaveCallback;
import java.util.ArrayList;
import java.util.List;
public class RecipientsActivity extends ListActivity {
public static final String TAG = RecipientsActivity.class.getSimpleName();
protected ParseRelation<ParseUser> mFriendsRelations;
protected ParseUser mCurrentUser;
protected List<ParseUser> mFriends;
protected ProgressBar mLoadingRecipients;
protected MenuItem mSendMenuItem;
protected Uri mMediaUri;
protected String mFileType;
protected EditText mCommentText;
protected String mComment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recipients);
getActionBar();
getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
mMediaUri = getIntent().getData();
mFileType = getIntent().getExtras().getString(ParseConstants.KEY_FILE_TYPE);
}
@Override
protected void onResume() {
super.onResume();
mCommentText = (EditText) findViewById(R.id.commentEditText);
mLoadingRecipients = (ProgressBar) findViewById(R.id.loadingRecipientsProgress);
mCurrentUser = ParseUser.getCurrentUser();
mFriendsRelations = mCurrentUser.getRelation(ParseConstants.KEY_Friends_Relations);
mLoadingRecipients.setVisibility(View.VISIBLE);
ParseQuery<ParseUser> query = ParseUser.getQuery();
query.orderByAscending(ParseConstants.KEY_USERNAME);
query.setLimit(1000);
query.setCachePolicy(ParseQuery.CachePolicy.CACHE_ELSE_NETWORK);
query.findInBackground(new FindCallback<ParseUser>() {
@Override
public void done(List<ParseUser> friends, ParseException e) {
//Build the list of Parse relations
mLoadingRecipients.setVisibility(View.INVISIBLE);
if (e == null) {
mFriends = friends;
String[] friendsUsername = new String[mFriends.size()];
int i = 0;
for (ParseUser friendlist : mFriends) {
friendsUsername[i] = friendlist.get(ParseConstants.KEY_NAME).toString();
i++;
ArrayAdapter<String> adapter = new ArrayAdapter<String>(
RecipientsActivity.this, android.R.layout.simple_list_item_checked, friendsUsername);
setListAdapter(adapter);
}
} else {
mLoadingRecipients.setVisibility(View.INVISIBLE);
Log.e(TAG, e.getMessage());
AlertDialog.Builder builder = new AlertDialog.Builder(RecipientsActivity.this);
builder.setTitle(R.string.signup_error_title)
.setMessage(R.string.no_friends_found)
.setPositiveButton(android.R.string.ok, null);
AlertDialog dialog = builder.create();
dialog.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_recipients, menu);
mSendMenuItem = menu.getItem(0);
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_send) {
mComment = mCommentText.getText().toString();
if(mComment.isEmpty()){
mComment = "";
}
mLoadingRecipients.setVisibility(View.VISIBLE);
ParseObject message = createMessage();
if(message == null){
//error
mLoadingRecipients.setVisibility(View.INVISIBLE);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(R.string.error_file)
.setTitle(R.string.signup_error_title)
.setPositiveButton(android.R.string.ok,null);
AlertDialog dialog = builder.create();
dialog.show();
}
else {
send(message);
mLoadingRecipients.setVisibility(View.INVISIBLE);
finish();
}
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
if(l.getCheckedItemCount() > 0){
mSendMenuItem.setVisible(true);
}
else {
mSendMenuItem.setVisible(false);
}
}
protected ParseObject createMessage(){
ParseObject message = new ParseObject(ParseConstants.CLASS_MESSAGES);
message.put(ParseConstants.KEY_SENDERS_IDS , ParseUser.getCurrentUser().getObjectId());
message.put(ParseConstants.KEY_SENDER_NAME , ParseUser.getCurrentUser().getUsername());
message.put(ParseConstants.KEY_RECIPIENTS_IDS, getRecipientsIds());
message.put(ParseConstants.KEY_FILE_TYPE, mFileType);
message.put(ParseConstants.KEY_COMMENT_TEXT, mComment);
byte[] fileByte = FileHelper.getByteArrayFromFile(this, mMediaUri);
if(fileByte == null){
return null;
}
else {
if (mFileType.equals(ParseConstants.TYPE_IMAGE)){
fileByte = FileHelper.reduceImageForUpload(fileByte);
}
String fileName = FileHelper.getFileName(this, mMediaUri,mFileType);
ParseFile file = new ParseFile(fileName, fileByte);
message.put(ParseConstants.KEY_FILE, file);
return message;
}
}
protected ArrayList<String> getRecipientsIds(){
ArrayList<String> recipientsList = new ArrayList<>();
for(int i = 0; i<getListView().getCount() ; i++){
if(getListView().isItemChecked(i)){
recipientsList.add(mFriends.get(i).getObjectId());
}
}
return recipientsList;
}
protected void send(ParseObject message){
message.saveInBackground(new SaveCallback() {
@Override
public void done(ParseException e) {
if (e == null) {
//success
Toast.makeText(RecipientsActivity.this, R.string.success_message, Toast.LENGTH_LONG).show();
sendPushNotification();
} else {
AlertDialog.Builder builder = new AlertDialog.Builder(RecipientsActivity.this);
builder.setMessage(R.string.error_file)
.setTitle(R.string.signup_error_title)
.setPositiveButton(android.R.string.ok, null);
AlertDialog dialog = builder.create();
dialog.show();
}
}
});
}
protected void sendPushNotification (){
ParseQuery<ParseInstallation> query = ParseInstallation.getQuery();
query.whereContainedIn(ParseConstants.KEY_USER_ID, getRecipientsIds());
//send push notification
ParsePush push = new ParsePush();
push.setQuery(query);
push.setMessage(getString(R.string.push_string , ParseUser.getCurrentUser().getUsername()));
push.sendInBackground();
}
}
2 Answers
Harry James
14,780 PointsHey Kevin!
The "freeze" your talking about comes from this line here:
byte[] fileBytes = FileHelper.getByteArrayFromFile(this, mMediaUri);
Depending on the size of the file, it can take a long time to get all of the file bytes.
If you would like to "prevent" the freeze, you could set up an ASyncTask to get the bytes in the background.
Note that you do not want to run any code for creating the Parse file and attaching it to the message until the ASyncTask says it's complete. Only when it is complete should you do this and return the message. This will also mean you'll have to change your methods around a bit to make this possible.
If you get stuck along the way, give me a shout and I'll try to help out :)
Kevin Nguyen
77 PointsOk no problem Harry I did.
I am going to share the link just in case we find the solution and other people have to same problem.
https://teamtreehouse.com/forum/choose-pic-and-video-works-take-pic-and-video-crash
Kevin Nguyen
77 PointsKevin Nguyen
77 PointsThanks a bunch. I also have another quick question relating to the camera crashing when I take a photo. One of the users was testing this out and the app crashed when they tried to send a picture using the TAKE PICTURE action. When I tried to take a picture and send it using that option it works fine. The user has the new android lollipop upgrade and I do not. Does this matter?
Harry James
Harry James
14,780 PointsHarry James
14,780 PointsHey Kevin!
No, that shouldn't matter. I am using Lollipop on my device and the Take Photo option works fine.
Is this another Treehouse user having the issue? If so, feel free to link me over to the forum post and I'll take a look at the problem (Or if you'd rather try and solve it yourself for them - do so!).