Merge remote-tracking branch 'origin/master' into felix

This commit is contained in:
Felix Atsma
2017-06-26 10:51:36 +02:00
11 changed files with 391 additions and 97 deletions

View File

@@ -26,10 +26,11 @@ dependencies {
}) })
compile 'com.android.support:appcompat-v7:25.3.1' compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.android.support:design:25.3.1' compile 'com.android.support:design:25.3.1'
compile 'com.google.firebase:firebase-database:11.0.1'
compile 'com.google.firebase:firebase-auth:11.0.1'
compile 'com.android.support.constraint:constraint-layout:1.0.2' compile 'com.android.support.constraint:constraint-layout:1.0.2'
compile 'com.android.support:support-v4:25.3.1' compile 'com.android.support:support-v4:25.3.1'
compile 'com.google.firebase:firebase-database:11.0.1'
compile 'com.google.firebase:firebase-auth:11.0.1'
compile 'com.google.firebase:firebase-storage:11.0.1' compile 'com.google.firebase:firebase-storage:11.0.1'
// FirebaseUI Storage only // FirebaseUI Storage only

View File

@@ -16,6 +16,8 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.RelativeLayout; import android.widget.RelativeLayout;
import nl.myhyvesbookplus.tagram.controller.UploadClass;
/** /**
* A simple {@link Fragment} subclass. * A simple {@link Fragment} subclass.
* Activities that contain this fragment must implement the * Activities that contain this fragment must implement the

View File

@@ -3,12 +3,11 @@ package nl.myhyvesbookplus.tagram;
import android.app.FragmentManager; import android.app.FragmentManager;
import android.app.FragmentTransaction; import android.app.FragmentTransaction;
import android.content.Intent; import android.content.Intent;
import android.hardware.Camera; import android.graphics.Bitmap;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.design.widget.BottomNavigationView; import android.support.design.widget.BottomNavigationView;
import android.app.Fragment;
import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AppCompatActivity;
import android.util.Log; import android.util.Log;
import android.view.MenuItem; import android.view.MenuItem;
@@ -16,7 +15,10 @@ import android.view.View;
import com.google.firebase.auth.FirebaseAuth; import com.google.firebase.auth.FirebaseAuth;
public class MainActivity extends AppCompatActivity implements CameraFragment.OnFragmentInteractionListener, ProfileFragment.OnFragmentInteractionListener, TimelineFragment.OnFragmentInteractionListener { import nl.myhyvesbookplus.tagram.controller.UploadClass;
import nl.myhyvesbookplus.tagram.model.BitmapPost;
public class MainActivity extends AppCompatActivity implements CameraFragment.OnFragmentInteractionListener, ProfileFragment.OnFragmentInteractionListener, TimelineFragment.OnFragmentInteractionListener, UploadClass.ProfilePictureUpdatedListener {
final static private String TAG = "MainScreen"; final static private String TAG = "MainScreen";
FirebaseAuth mAuth; FirebaseAuth mAuth;
@@ -32,25 +34,25 @@ public class MainActivity extends AppCompatActivity implements CameraFragment.On
case nl.myhyvesbookplus.tagram.R.id.navigation_timeline: case nl.myhyvesbookplus.tagram.R.id.navigation_timeline:
Log.d(TAG, "onNavigationItemSelected: Timeline"); Log.d(TAG, "onNavigationItemSelected: Timeline");
TimelineFragment timeline = new TimelineFragment(); TimelineFragment timeline = new TimelineFragment();
transaction.replace(R.id.content, timeline); transaction.replace(R.id.content, timeline)
transaction.addToBackStack(null); .addToBackStack(null)
transaction.commit(); .commit();
return true; return true;
case nl.myhyvesbookplus.tagram.R.id.navigation_camera: case nl.myhyvesbookplus.tagram.R.id.navigation_camera:
Log.d(TAG, "onNavigationItemSelected: Camera"); Log.d(TAG, "onNavigationItemSelected: Camera");
CameraFragment camera = new CameraFragment(); CameraFragment camera = new CameraFragment();
transaction.replace(R.id.content, camera); transaction.replace(R.id.content, camera)
transaction.addToBackStack(null); .addToBackStack(null)
transaction.commit(); .commit();
return true; return true;
case nl.myhyvesbookplus.tagram.R.id.navigation_profile: case nl.myhyvesbookplus.tagram.R.id.navigation_profile:
Log.d(TAG, "onNavigationItemSelected: Profile"); Log.d(TAG, "onNavigationItemSelected: Profile");
ProfileFragment profile = new ProfileFragment(); ProfileFragment profile = new ProfileFragment();
transaction.replace(R.id.content, profile); transaction.replace(R.id.content, profile)
transaction.addToBackStack(null); .addToBackStack(null)
transaction.commit(); .commit();
return true; return true;
} }
return false; return false;
@@ -76,7 +78,6 @@ public class MainActivity extends AppCompatActivity implements CameraFragment.On
FragmentTransaction transaction = getFragmentManager().beginTransaction(); FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.content, fragment); transaction.replace(R.id.content, fragment);
transaction.commit(); transaction.commit();
} }
@Override @Override
@@ -92,11 +93,31 @@ public class MainActivity extends AppCompatActivity implements CameraFragment.On
public void logOutOnClick(View view) { public void logOutOnClick(View view) {
FirebaseAuth.getInstance().signOut(); FirebaseAuth.getInstance().signOut();
goToLogin(); goToLogin();
this.finish();
} }
protected void goToLogin() { protected void goToLogin() {
Intent goToLogIn = new Intent(this, LoginActivity.class); Intent goToLogIn = new Intent(this, LoginActivity.class);
startActivity(goToLogIn); startActivity(goToLogIn);
this.finish();
} }
public void testCreatePost(View view) {
UploadClass uploadClass = new UploadClass(this);
Bitmap bitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ALPHA_8);
BitmapPost bitmapPost = new BitmapPost(bitmap, "Dit is een Test!");
uploadClass.uploadPicture(bitmapPost);
}
@Override
public void ProfilePictureUpdated(Boolean success) {
Log.d(TAG, "ProfilePictureUpdated: Ja ik luister naar je!");
FragmentManager man = getFragmentManager();
ProfileFragment frag = (ProfileFragment) man.findFragmentById(R.id.content);
FragmentTransaction transaction = man.beginTransaction();
transaction.detach(frag)
.attach(frag)
.commit();
Log.d(TAG, "ProfilePictureUpdated: Done reloading fragment");
}
} }

View File

@@ -1,19 +1,20 @@
package nl.myhyvesbookplus.tagram; package nl.myhyvesbookplus.tagram;
import android.app.Fragment;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.app.Fragment; import android.provider.MediaStore;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.Button; import android.widget.Button;
import android.widget.ImageButton; import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import com.bumptech.glide.Glide; import com.bumptech.glide.Glide;
@@ -25,9 +26,9 @@ import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.storage.FirebaseStorage; import com.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.StorageReference; import com.google.firebase.storage.StorageReference;
import org.w3c.dom.Text; import nl.myhyvesbookplus.tagram.controller.UploadClass;
import static android.content.ContentValues.TAG; import static android.app.Activity.RESULT_OK;
/** /**
* A simple {@link Fragment} subclass. * A simple {@link Fragment} subclass.
@@ -38,25 +39,25 @@ import static android.content.ContentValues.TAG;
* create an instance of this fragment. * create an instance of this fragment.
*/ */
public class ProfileFragment extends Fragment implements View.OnClickListener { public class ProfileFragment extends Fragment implements View.OnClickListener {
static final int REQUEST_IMAGE_CAPTURE = 1;
final static private String TAG = "ProfileFragment";
// TODO: Rename parameter arguments, choose names that match // TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1"; private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2"; private static final String ARG_PARAM2 = "param2";
private static Uri downloadUrl;
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
/// Views ///
protected Button changePwdButton; protected Button changePwdButton;
protected ImageButton profilePicButton; protected ImageButton profilePicButton;
/// Views ///
protected StorageReference httpsReference; protected StorageReference httpsReference;
protected TextView profileName; protected TextView profileName;
protected ImageView profilePicture; protected ImageView profilePicture;
private OnFragmentInteractionListener mListener;
protected FirebaseUser user; protected FirebaseUser user;
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private OnFragmentInteractionListener mListener;
/// Required empty public constructor /// /// Required empty public constructor ///
@@ -90,9 +91,6 @@ public class ProfileFragment extends Fragment implements View.OnClickListener {
} }
user = FirebaseAuth.getInstance().getCurrentUser(); user = FirebaseAuth.getInstance().getCurrentUser();
if (user != null && user.getPhotoUrl() != null) {
httpsReference = FirebaseStorage.getInstance().getReferenceFromUrl(user.getPhotoUrl().toString());
}
} }
/** /**
@@ -120,11 +118,16 @@ public class ProfileFragment extends Fragment implements View.OnClickListener {
View view = inflater.inflate(R.layout.fragment_profile, container, false); View view = inflater.inflate(R.layout.fragment_profile, container, false);
findViews(view); findViews(view);
if (user != null && user.getPhotoUrl() != null) {
httpsReference = FirebaseStorage.getInstance().getReferenceFromUrl(user.getPhotoUrl().toString());
}
if (httpsReference != null) { if (httpsReference != null) {
Glide.with(this).using(new FirebaseImageLoader()).load(httpsReference).into(profilePicture); Glide.with(this).using(new FirebaseImageLoader()).load(httpsReference).into(profilePicture);
} }
// TODO Remove check for getDisplayName if all users are required to enter a displayName anyways. profilePicture.invalidate();
if (user != null && user.getDisplayName() != null) { if (user != null && user.getDisplayName() != null) {
profileName.setText(user.getDisplayName()); profileName.setText(user.getDisplayName());
} }
@@ -161,9 +164,38 @@ public class ProfileFragment extends Fragment implements View.OnClickListener {
* Performs profile picture change action. * Performs profile picture change action.
*/ */
public void profilePicOnClick() { public void profilePicOnClick() {
Log.d(TAG, "profilePicOnClick: JE KAN NOG GEEN FOTO UPLOADEN"); // Log.d(TAG, "profilePicOnClick: JE KAN NOG GEEN FOTO UPLOADEN");
dispatchTakePictureIntent();
} }
/**
* Starts new intent for access to the built-in camera of device.
*/
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getActivity().getPackageManager()) != null) {
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
/**
* Grabs the image just taken by the built-in camera and pushes this image to the user account.
* @param requestCode
* @param resultCode
* @param data
*/
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
Bundle extras = data.getExtras();
Bitmap imageBitmap = (Bitmap) extras.get("data");
UploadClass uploadClass = new UploadClass(getActivity());
uploadClass.uploadProfilePicture(imageBitmap);
}
}
// TODO Make this function into its own class for modularity. // TODO Make this function into its own class for modularity.
/** /**
* Performs password reset action. * Performs password reset action.
@@ -221,4 +253,6 @@ public class ProfileFragment extends Fragment implements View.OnClickListener {
// TODO: Update argument type and name // TODO: Update argument type and name
void onFragmentInteraction(Uri uri); void onFragmentInteraction(Uri uri);
} }
} }

View File

@@ -1,62 +0,0 @@
package nl.myhyvesbookplus.tagram;
import android.graphics.Bitmap;
import android.net.Uri;
import android.support.annotation.NonNull;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.StorageReference;
import com.google.firebase.storage.UploadTask;
import java.io.ByteArrayOutputStream;
import java.util.Random;
/**
* Created by marijnjansen on 20/06/2017.
*/
public class UploadClass {
private StorageReference mStorageRef;
public UploadClass() {
String name = Integer.toString(new Random().nextInt(10000));
mStorageRef = FirebaseStorage.getInstance().getReference().child("images/" + name);
}
private byte[] bitmapToBytes(Bitmap bitmap) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
return baos.toByteArray();
}
public void uploadPicture(Bitmap bitmap) {
UploadTask uploadTask = mStorageRef.putBytes(bitmapToBytes(bitmap));
uploadTask.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
}
})
.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
@Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
// Handle successful uploads on complete
Uri downloadUrl = taskSnapshot.getMetadata().getDownloadUrl();
}
});
}
private String getUserUid() {
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user != null) {
return user.getUid();
}
return "";
}
}

View File

@@ -0,0 +1,28 @@
package nl.myhyvesbookplus.tagram.controller;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.StorageReference;
import nl.myhyvesbookplus.tagram.model.UriPost;
/**
* Created by marijnjansen on 23/06/2017.
*/
public class DownloadClass {
private static final String TAG = "DownloadClass";
private StorageReference mStorageRef;
private DatabaseReference mDataRef;
public DownloadClass() {
mStorageRef = FirebaseStorage.getInstance().getReference();
mDataRef = FirebaseDatabase.getInstance().getReference();
}
public UriPost[] getPosts() {
UriPost[] posts = new UriPost[10];
return posts;
}
}

View File

@@ -0,0 +1,132 @@
package nl.myhyvesbookplus.tagram.controller;
import android.content.Context;
import android.graphics.Bitmap;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.util.Log;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.auth.UserProfileChangeRequest;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.StorageReference;
import com.google.firebase.storage.UploadTask;
import java.io.ByteArrayOutputStream;
import nl.myhyvesbookplus.tagram.model.BitmapPost;
import nl.myhyvesbookplus.tagram.model.UriPost;
import static java.lang.System.currentTimeMillis;
/**
* Class that does all the photo uploading things.
*/
public class UploadClass {
private static final String TAG = "UploadClass";
private StorageReference mStorageRef;
private DatabaseReference mDataRef;
private ProfilePictureUpdatedListener mListener;
public UploadClass(Context context) {
mStorageRef = FirebaseStorage.getInstance().getReference();
mDataRef = FirebaseDatabase.getInstance().getReference();
mListener = (ProfilePictureUpdatedListener) context;
}
/// Helpers ///
private byte[] bitmapToBytes(Bitmap bitmap) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
return baos.toByteArray();
}
private String getUserUid() {
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user != null) {
return user.getUid();
}
return "";
}
/// Post Uploads ///
public void uploadPicture(final BitmapPost post) {
final String name = getUserUid() + currentTimeMillis();
UploadTask uploadTask = mStorageRef.child("posts").child(name + ".jpg").putBytes(bitmapToBytes(post.getBitmap()));
uploadTask.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.d(TAG, "onFailure: Upload Failed");
}
})
.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
@Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
// Handle successful uploads on complete
Log.d(TAG, "onSuccess: Upload Success!");
Uri downloadUrl = taskSnapshot.getMetadata().getDownloadUrl();
putPostInDatabase(post.getUriPost(downloadUrl), name);
}
});
}
private void putPostInDatabase(UriPost post, String name) {
DatabaseReference ref = mDataRef.child("posts").child(name);
ref.setValue(post)
.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d(TAG, "onComplete: Added post to database");
} else {
Log.d(TAG, "onComplete: " + task.getException().getLocalizedMessage());
}
}
});
}
/// Profile picture ///
public void uploadProfilePicture(Bitmap picture) {
byte[] uploadPhoto = bitmapToBytes(picture);
UploadTask photoUpload = mStorageRef.child("profile").child(getUserUid() + "_" + currentTimeMillis()).putBytes(uploadPhoto);
photoUpload.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
@Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Uri downloadUrl = taskSnapshot.getDownloadUrl();
updateProfilePictureInUser(downloadUrl);
}
});
}
private void updateProfilePictureInUser(Uri url) {
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
UserProfileChangeRequest request = new UserProfileChangeRequest.Builder()
.setPhotoUri(url)
.build();
user.updateProfile(request)
.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
Log.d(TAG, "onComplete: Updated profile picture");
mListener.ProfilePictureUpdated(true);
}
});
}
public interface ProfilePictureUpdatedListener {
void ProfilePictureUpdated(Boolean success);
}
}

View File

@@ -0,0 +1,35 @@
package nl.myhyvesbookplus.tagram.model;
import android.graphics.Bitmap;
import android.net.Uri;
import java.util.Date;
/**
* BitmapPost is a Class for a Post with a Bitmap as an image.
*/
public class BitmapPost extends Post {
private Bitmap photo;
public BitmapPost(Bitmap photo, String comment, Date date, int nietSlechts, String poster) {
super(comment, date, nietSlechts, poster);
this.photo = photo;
}
public BitmapPost(Bitmap photo, String comment) {
super(comment);
this.photo = photo;
}
public Bitmap getBitmap() {
return photo;
}
public UriPost getUriPost(Uri url) {
return new UriPost(url, getComment(), getDate(), getNietSlechts(), getPoster());
}
public void setPhoto(Bitmap photo) {
this.photo = photo;
}
}

View File

@@ -0,0 +1,63 @@
package nl.myhyvesbookplus.tagram.model;
import com.google.firebase.auth.FirebaseAuth;
import java.util.Date;
/**
* Post is a Class for a Post with a Bitmap as an image.
*/
abstract class Post {
private Date date;
private String comment;
private int nietSlechts;
private String poster;
Post() {
// Default constructor required for calls to Post.getValue(User.class)
}
Post(String comment, Date date, int nietSlechts, String poster) {
this.date = date;
this.comment = comment;
this.nietSlechts = nietSlechts;
this.poster = poster;
}
Post(String comment) {
this(comment, new Date(), 0, FirebaseAuth.getInstance().getCurrentUser().getUid());
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
public int getNietSlechts() {
return nietSlechts;
}
public void setNietSlechts(int nietSlechts) {
this.nietSlechts = nietSlechts;
}
public String getPoster() {
return poster;
}
public void setPoster(String poster) {
this.poster = poster;
}
}

View File

@@ -0,0 +1,35 @@
package nl.myhyvesbookplus.tagram.model;
import android.net.Uri;
import java.util.Date;
/**
* UriPost is a Class for a Post with a Uri as an image.
*/
public class UriPost extends Post {
private String photo;
public UriPost() {
// Default constructor required for calls to DataSnapshot.getValue(UriPost.class)
}
public UriPost(Uri photo, String comment, Date date, int nietSlechts, String poster) {
super(comment, date, nietSlechts, poster);
this.photo = photo.toString();
}
public UriPost(String photo, String comment) {
super(comment);
this.photo = photo;
}
public String getUri() {
return photo;
}
public void setPhoto(String photo) {
this.photo = photo;
}
}

View File

@@ -9,5 +9,10 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:text="@string/hello_blank_fragment" /> android:text="@string/hello_blank_fragment" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Test bitmap upload"
android:onClick="testCreatePost"/>
</FrameLayout> </FrameLayout>