How can I save user messages and history to room database - java

I am developing a chat app and I want to save user chat history and messages using room database. By this, when the users start the app they can see their previous history and messages.
Below my User.java model class where implemented user model properties.
#Entity
public class User implements IChatUser {
#PrimaryKey(autoGenerate = true)
private Integer id;
#ColumnInfo(name = "name")
String name;
#Ignore
Bitmap icon;
public User() {
}
public User(int id, String name, Bitmap icon) {
this.id = id;
this.name = name;
this.icon = icon;
}
#Override
public String getId() {
return this.id.toString();
}
#Override
public String getName() {
return this.name;
}
public void setId(Integer id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
#Override
public Bitmap getIcon() {
return this.icon;
}
#Override
public void setIcon(Bitmap icon) {
this.icon = icon;
}
}
UserDao.java
#Dao
public interface UserDao {
#Query("SELECT * FROM user")
List<User> getUsers();
#Insert
void insert(User user);
#Delete
void delete(User user);
#Update
void update(User user);
}
UserRoomDatabase.java
#Database(entities = {User.class}, version = 1)
public abstract class UserRoomDatabase extends RoomDatabase {
public abstract UserDao userDao();
}
MessengerActivity.java
public class MessengerActivity extends Activity{
#VisibleForTesting
protected static final int RIGHT_BUBBLE_COLOR = R.color.colorPrimaryDark;
#VisibleForTesting
protected static final int LEFT_BUBBLE_COLOR = R.color.gray300;
#VisibleForTesting
protected static final int BACKGROUND_COLOR = R.color.blueGray400;
#VisibleForTesting
protected static final int SEND_BUTTON_COLOR = R.color.blueGray500;
#VisibleForTesting
protected static final int SEND_ICON = R.drawable.ic_action_send;
#VisibleForTesting
protected static final int OPTION_BUTTON_COLOR = R.color.teal500;
#VisibleForTesting
protected static final int RIGHT_MESSAGE_TEXT_COLOR = Color.WHITE;
#VisibleForTesting
protected static final int LEFT_MESSAGE_TEXT_COLOR = Color.BLACK;
#VisibleForTesting
protected static final int USERNAME_TEXT_COLOR = Color.WHITE;
#VisibleForTesting
protected static final int SEND_TIME_TEXT_COLOR = Color.WHITE;
#VisibleForTesting
protected static final int DATA_SEPARATOR_COLOR = Color.WHITE;
#VisibleForTesting
protected static final int MESSAGE_STATUS_TEXT_COLOR = Color.WHITE;
#VisibleForTesting
protected static final String INPUT_TEXT_HINT = "New message..";
#VisibleForTesting
protected static final int MESSAGE_MARGIN = 5;
private ChatView mChatView;
private MessageList mMessageList;
private ArrayList<User> mUsers;
private int mReplyDelay = -1;
Realm realm;
private static final int READ_REQUEST_CODE = 100;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_messenger);
initUsers();
mChatView = findViewById(R.id.chat_view);
//Load saved messages
loadMessages(realm);
//Set UI parameters if you need
mChatView.setRightBubbleColor(ContextCompat.getColor(this,RIGHT_BUBBLE_COLOR));
mChatView.setLeftBubbleColor(ContextCompat.getColor(this, LEFT_BUBBLE_COLOR));
mChatView.setBackgroundColor(ContextCompat.getColor(this, BACKGROUND_COLOR));
mChatView.setSendButtonColor(ContextCompat.getColor(this, SEND_BUTTON_COLOR));
mChatView.setSendIcon(SEND_ICON);
mChatView.setOptionIcon(R.drawable.ic_account_circle);
mChatView.setOptionButtonColor(OPTION_BUTTON_COLOR);
mChatView.setRightMessageTextColor(RIGHT_MESSAGE_TEXT_COLOR);
mChatView.setLeftMessageTextColor(LEFT_MESSAGE_TEXT_COLOR);
mChatView.setUsernameTextColor(USERNAME_TEXT_COLOR);
mChatView.setSendTimeTextColor(SEND_TIME_TEXT_COLOR);
mChatView.setDateSeparatorColor(DATA_SEPARATOR_COLOR);
mChatView.setMessageStatusTextColor(MESSAGE_STATUS_TEXT_COLOR);
mChatView.setInputTextHint(INPUT_TEXT_HINT);
mChatView.setMessageMarginTop(MESSAGE_MARGIN);
mChatView.setMessageMarginBottom(MESSAGE_MARGIN);
mChatView.setMaxInputLine(5);
mChatView.setUsernameFontSize(getResources().getDimension(R.dimen.font_small));
mChatView.setInputType(InputType.TYPE_TEXT_FLAG_CAP_SENTENCES);
mChatView.setInputTextColor(ContextCompat.getColor(this, R.color.red500));
mChatView.setInputTextSize(TypedValue.COMPLEX_UNIT_SP, 20);
mChatView.setOnBubbleClickListener(new Message.OnBubbleClickListener() {
#Override
public void onClick(Message message) {
mChatView.updateMessageStatus(message, MyMessageStatusFormatter.STATUS_SEEN);
Toast.makeText(
MessengerActivity.this,
"click : " + message.getUser().getName() + " - " + message.getText(),
Toast.LENGTH_SHORT
).show();
}
});
mChatView.setOnIconClickListener(new Message.OnIconClickListener() {
#Override
public void onIconClick(Message message) {
Toast.makeText(
MessengerActivity.this,
"click : icon " + message.getUser().getName(),
Toast.LENGTH_SHORT
).show();
}
});
mChatView.setOnIconLongClickListener(new Message.OnIconLongClickListener() {
#Override
public void onIconLongClick(Message message) {
Toast.makeText(
MessengerActivity.this,
"Removed this message \n" + message.getText(),
Toast.LENGTH_SHORT
).show();
mChatView.getMessageView().remove(message);
}
});
//Click Send Button
mChatView.setOnClickSendButtonListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
initUsers();
//new message
Message message = new Message.Builder()
.setUser(mUsers.get(0))
.setRight(true)
.setText(mChatView.getInputText())
.hideIcon(true)
.setStatusIconFormatter(new MyMessageStatusFormatter(MessengerActivity.this))
.setStatusTextFormatter(new MyMessageStatusFormatter(MessengerActivity.this))
.setStatusStyle(Message.Companion.getSTATUS_ICON())
.setStatus(MyMessageStatusFormatter.STATUS_DELIVERED)
.build();
//Set to chat view
mChatView.send(message);
//Add message list
mMessageList.add(message);
//Reset edit text
mChatView.setInputText("");
receiveMessage(message.getText());
}
});
//Click option button
mChatView.setOnClickOptionButtonListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
showDialog();
}
});
}
private void openGallery() {
Intent intent;
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
intent = new Intent(Intent.ACTION_GET_CONTENT);
} else {
intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
}
intent.setType("image/*");
startActivityForResult(intent, READ_REQUEST_CODE);
}
private void receiveMessage(String sendText) {
//Ignore hey
if (!sendText.contains("hey")) {
//Receive message
final Message receivedMessage = new Message.Builder()
.setUser(mUsers.get(1))
.setRight(false)
.setText(ChatBot.INSTANCE.talk(mUsers.get(0).getName(), sendText))
.setStatusIconFormatter(new MyMessageStatusFormatter(MessengerActivity.this))
.setStatusTextFormatter(new MyMessageStatusFormatter(MessengerActivity.this))
.setStatusStyle(Message.Companion.getSTATUS_ICON())
.setStatus(MyMessageStatusFormatter.STATUS_DELIVERED)
.build();
if (sendText.equals( Message.Type.PICTURE.name())) {
receivedMessage.setText("Nice!");
}
// This is a demo bot
// Return within 3 seconds
if (mReplyDelay < 0) {
mReplyDelay = (new Random().nextInt(4) + 1) * 1000;
}
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
mChatView.receive(receivedMessage);
//Add message list
mMessageList.add(receivedMessage);
}
}, mReplyDelay);
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode != READ_REQUEST_CODE || resultCode != RESULT_OK || data == null) {
return;
}
Uri uri = data.getData();
try {
Bitmap picture = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
Message message = new Message.Builder()
.setRight(true)
.setText(Message.Type.PICTURE.name())
.setUser(mUsers.get(0))
.hideIcon(true)
.setPicture(picture)
.setType(Message.Type.PICTURE)
.setStatusIconFormatter(new MyMessageStatusFormatter(MessengerActivity.this))
.setStatusStyle(Message.Companion.getSTATUS_ICON())
.setStatus(MyMessageStatusFormatter.STATUS_DELIVERED)
.build();
mChatView.send(message);
//Add message list
mMessageList.add(message);
receiveMessage(Message.Type.PICTURE.name());
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(this, getString(R.string.error), Toast.LENGTH_SHORT).show();
}
}
private void initUsers() {
mUsers = new ArrayList<>();
//User id
int myId = 0;
//User icon
Bitmap myIcon = BitmapFactory.decodeResource(getResources(), R.drawable.face_2);
//User name
String myName = "Michael";
int yourId = 1;
Bitmap yourIcon = BitmapFactory.decodeResource(getResources(), R.drawable.face_1);
String yourName = "Emily";
final User me = new User(myId, myName, myIcon);
final User you = new User(yourId, yourName, yourIcon);
mUsers.add(me);
mUsers.add(you);
}
/**
* Load saved messages
* #param realm
*/
private void loadMessages(Realm realm) {
List<Message> messages = new ArrayList<>();
mMessageList = AppData.getMessageList(this);
if (mMessageList == null) {
mMessageList = new MessageList();
} else {
for (int i = 0; i < mMessageList.size(); i++) {
Message message = mMessageList.get(i);
//Set extra info because they were removed before save messages.
for (IChatUser user : mUsers) {
if (message.getUser().getId().equals(user.getId())) {
message.getUser().setIcon(user.getIcon());
}
}
if (!message.isDateCell() && message.isRight()) {
message.hideIcon(true);
}
message.setStatusStyle(Message.Companion.getSTATUS_ICON_RIGHT_ONLY());
message.setStatusIconFormatter(new MyMessageStatusFormatter(this));
message.setStatus(MyMessageStatusFormatter.STATUS_DELIVERED);
messages.add(message);
}
}
MessageView messageView = mChatView.getMessageView();
messageView.init(messages);
messageView.setSelection(messageView.getCount() - 1);
}
#Override
public void onResume() {
super.onResume();
initUsers();
}
#Override
public void onPause() {
super.onPause();
//Save message
mMessageList = new MessageList();
mMessageList.setMessages(mChatView.getMessageView().getMessageList());
AppData.putMessageList(this, mMessageList);
}
#VisibleForTesting
public ArrayList<User> getUsers() {
return mUsers;
}
public void setReplyDelay(int replyDelay) {
mReplyDelay = replyDelay;
}
private void showDialog() {
final String[] items = {
getString(R.string.send_picture),
getString(R.string.clear_messages)
};
new AlertDialog.Builder(this)
.setTitle(getString(R.string.options))
.setItems(items, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int position) {
switch (position) {
case 0 :
openGallery();
break;
case 1:
mChatView.getMessageView().removeAll();
break;
}
}
})
.show();
}
}

You should create a new room database to store your messages. It's table should look like this:
id
message
sendingUser
receivingUser
0
Hello how are you?
John
David
1
Thanks, im good.
David
John
2
good to hear that!
John
David
First create a new Message class. This class should look like this:
#Entity(tableName = "message_table")
data class Message(
#PrimaryKey(autoGenerate = true)
var id: Int,
#ColumnInfo(name= "message")
var message: String,
#ColumnInfo(name = "sendingUser")
var sendingUser: String,
#ColumnInfo(name = "receivingUser")
var receivingUser: String
)
Then create your MessageDatabase, like this:
#Database(entities = [Message::class], version = 1)
abstract class MessageDatabase: RoomDatabase() {
abstract fun messageDao(): MessageDao
}
Next create your MessageDao
#Dao
interface MessageDao {
#Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insert(message: Message)
#Query("SELECT ALL * FROM message_table WHERE sendingUser= :sendingUser")
suspend fun getMessageListFromSender(sendingUser: String): MutableList<Message>
#Query("SELECT ALL * FROM message_table")
suspend fun getMessageList(): MutableList<Message>
#Delete
suspend fun delete(message: Message)
#Update
suspend fun update(message: Message)
}
At last you can initialize your room database like this:
private val roomDb = Room.databaseBuilder(
getApplication(),
MessageDatabase::class.java, "message_database"
).build()
private val messageDao = roomDb.messageDao()
Use messageDao, to make operations with the database, this example shows you how to get message list from a certain sender:
suspend fun getMessageListFromSender(sendingUser: String): MutableList<Message> {
var list : MutableList<Message>
with (messageDao) {
list = this.getMessageListFromSender(sendingUser)
}
return list
}
viewModelScope.launch {
getMessageListFromSender("John")
}

Related

How to retrieve data from database using hashmap?

I have this recyclerview, when I click on an item I want to get the data in the red square from database.
And I want to show it like that
This is how I save it :
Save.setOnClickListener(new View.OnClickListener() {
#RequiresApi(api = Build.VERSION_CODES.GINGERBREAD)
#Override
public void onClick(View v) {
String refernce = TextRef.getEditText().getText().toString();
String nompdv = textNomPdv.getEditText().getText().toString();
String etat = textEtatCommande.getEditText().getText().toString();
String datecommande = TextDateCommande.getEditText().getText().toString();
String produitcommande = textProduit.getEditText().getText().toString();
String qntcommande = editTextProduitQnt.getEditText().getText().toString();
DatabaseReference newPost = reference.child(refernce);
newPost.child("refernce").setValue(refernce);
newPost.child("nompdv").setValue(nompdv);
newPost.child("etat").setValue(etat);
newPost.child("datecommande").setValue(datecommande);
newPost.child("user_id").setValue(uid);
Map<String, Object> values = new HashMap<>();
values.put(produitcommande, qntcommande);
DatabaseReference produitRef = reference.child(refernce).child("produit");
produitRef.updateChildren(values);
This is how I send data from first activity (recyclerview) :
v.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(view.getContext(), Order_detail.class);
int pos = v.getAdapterPosition();
if (pos != RecyclerView.NO_POSITION) {
Order clickedDataItem = listArray.get(pos);
intent.putExtra("nompdv", clickedDataItem.getNompdv());
intent.putExtra("reference", clickedDataItem.getRefernce());
intent.putExtra("datecommande", clickedDataItem.getDatecommande());
intent.putExtra("etat", clickedDataItem.getEtat());
}
view.getContext().startActivity(intent);
}
});
How to do to get the products and their quantities when clicking on an item in recyclerview?
Update : This my Order class :
public class Order implements Serializable {
public String refernce, nompdv, etat, datecommande, produitcommande, qntcommande;
String user_id;
public Order(){}
public Order(String refernce, String nompdv, String etat, String datecommande, String produitcommande, String qntcommande, String user_id) {
this.refernce = refernce;
this.nompdv = nompdv;
this.etat = etat;
this.datecommande = datecommande;
this.produitcommande = produitcommande;
this.qntcommande = qntcommande;
this.user_id = user_id;
}
public String getRefernce() {
return refernce;
}
public void setRefernce(String refernce) {
this.refernce = refernce;
}
public String getNompdv() {
return nompdv;
}
public void setNompdv(String nompdv) {
this.nompdv = nompdv;
}
public String getEtat() {
return etat;
}
public void setEtat(String etat) {
this.etat = etat;
}
public String getDatecommande() {
return datecommande;
}
public void setDatecommande(String datecommande) {
this.datecommande = datecommande;
}
public String getProduitcommande() {
return produitcommande;
}
public void setProduitcommande(String produitcommande) {
this.produitcommande = produitcommande;
}
public String getQntcommande() {
return qntcommande;
}
public void setQntcommande(String qntcommande) {
this.qntcommande = qntcommande;
}
public String getUser_id() {
return user_id;
}
public void setUser_id(String user_id) {
this.user_id = user_id;
}
}
The form how I save data
Update 2 :
This the Adapter for the recyclerview :
public class CommandeAdapter extends
RecyclerView.Adapter<CommandeAdapter.CommandeViewHolder> {
List<Order> listArray;
public CommandeAdapter(List<Order> List) {
this.listArray = List;
}
#NonNull
#Override
public CommandeAdapter.CommandeViewHolder onCreateViewHolder(#NonNull #NotNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.commande_model, parent, false);
return new CommandeViewHolder(v);
}
#Override
public void onBindViewHolder(#NonNull #NotNull CommandeAdapter.CommandeViewHolder holder, int position) {
CommandeViewHolder v = (CommandeViewHolder) holder;
final Order dataa = listArray.get(position);
v.nom_pdv.setText(dataa.getNompdv());
v.date.setText(dataa.getDatecommande());
v.etat.setText(dataa.getEtat());
v.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(view.getContext(), Order_detail.class);
int pos = v.getAdapterPosition();
if (pos != RecyclerView.NO_POSITION) {
Order clickedDataItem = listArray.get(pos);
intent.putExtra("nompdv", clickedDataItem.getNompdv());
intent.putExtra("reference", clickedDataItem.getRefernce());
intent.putExtra("datecommande", clickedDataItem.getDatecommande());
intent.putExtra("etat", clickedDataItem.getEtat());
}
}
view.getContext().startActivity(intent);
}
});
}
public class CommandeViewHolder extends RecyclerView.ViewHolder {
TextView nom_pdv, date, etat;
public CommandeViewHolder(#NonNull #NotNull View itemView) {
super(itemView);
nom_pdv = itemView.findViewById(R.id.namepdv);
date = itemView.findViewById(R.id.dateliv);
etat = itemView.findViewById(R.id.etat);
}
}
#Override
public int getItemCount() {
return listArray.size();
}}
And this is activity detail :
public class Order_detail extends AppCompatActivity {
TextView namepdv, refcommande, datecommande, etat, produitcmnd, qnt;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_commande_detail2);
namepdv = findViewById(R.id.nompdv);
refcommande = findViewById(R.id.refcommande);
datecommande = findViewById(R.id.datecommande);
etat = findViewById(R.id.etatcommande);
// --------------------- //
namepdv.setText(getIntent().getStringExtra("nompdv"));
refcommande.setText(getIntent().getStringExtra("reference"));
datecommande.setText(getIntent().getStringExtra("datecommande"));
etat.setText(getIntent().getStringExtra("etat"));
}}
From your question I am assuming that keys under produit are random.
So when you will retrieve order details produit will be a Hashmap. Declare produit as Hashmap<String,String> in Order class.
You can print those keys and values.
for(Map.Entry<String, String> e : clickedDataItem.getproduit().entrySet()) {
// print e.getKey() e.getValue()
}

Android PagedList not showing data from local if offline?

I have done various ways, but to no avail
DataSource
public class NetReqDataSourceFactory extends DataSource.Factory {
private static final String TAG = NetReqDataSourceFactory.class.getSimpleName();
private MutableLiveData<NetReqPageKeyedDataSource> networkStatus;
private NetReqPageKeyedDataSource moviesPageKeyedDataSource;
public NetReqDataSourceFactory(Context context, String status) {
this.networkStatus = new MutableLiveData<>();
moviesPageKeyedDataSource = new NetReqPageKeyedDataSource(context, status);
}
#Override
public DataSource create() {
networkStatus.postValue(moviesPageKeyedDataSource);
return moviesPageKeyedDataSource;
}
public MutableLiveData<NetReqPageKeyedDataSource> getNetworkStatus() {
return networkStatus;
}
public ReplaySubject<ReqDataList> getData() {
return moviesPageKeyedDataSource.getData();
}
}
PageKeyedDataSource
public class NetReqPageKeyedDataSource extends PageKeyedDataSource<String, ReqDataList> {
private static final String TAG = NetReqPageKeyedDataSource.class.getSimpleName();
private final MutableLiveData networkState;
private final ReplaySubject<ReqDataList> moviesObservable;
private final ConnectionServer connectionServer;
private final String status;
private final MasterRepository repository;
NetReqPageKeyedDataSource(Context context, String status) {
networkState = new MutableLiveData();
connectionServer = new ConnectionServer(Util.getApiWithAuth(context, (new ArrayList<ReqDataList>()).getClass(), new ReqJsonDeserializer()));
moviesObservable = ReplaySubject.create();
this.status = status;
this.repository = MasterRepository.getInstance(context);
}
public MutableLiveData getNetworkState() {
return networkState;
}
public ReplaySubject<ReqDataList> getData() {
return moviesObservable;
}
#Override
public void loadInitial(#NonNull LoadInitialParams<String> params, #NonNull final LoadInitialCallback<String, ReqDataList> callback) {
Log.i(TAG, "Loading Initial Rang, Count " + params.requestedLoadSize);
Log.i(TAG, "Loading Initial, Status " + status);
networkState.postValue(NetworkState.FIRST_LOADING);
connectionServer.getReqByPage(1, status).enqueue(new Callback<ArrayList<ReqDataList>>() {
#Override
public void onResponse(Call<ArrayList<ReqDataList>> call, Response<ArrayList<ReqDataList>> response) {
if (response.isSuccessful()) {
callback.onResult(response.body(), Integer.toString(1), Integer.toString(2));
networkState.postValue(NetworkState.LOADED);
if (response.body().size() > 0) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
response.body().forEach(moviesObservable::onNext);
} else {
for (ReqDataList data : response.body()) {
moviesObservable.onNext(data);
}
}
} else {
networkState.postValue(new NetworkState(NetworkState.Status.FIRST_FAILED, "Nothing here yet, pull to refresh & try again"));
}
} else {
Log.e("API CALL", response.message());
networkState.postValue(new NetworkState(NetworkState.Status.FIRST_FAILED, response.message()));
}
}
#Override
public void onFailure(Call<ArrayList<ReqDataList>> call, Throwable t) {
String errorMessage;
if (t.getMessage() == null) {
errorMessage = "unknown error";
} else {
errorMessage = t.getMessage();
}
networkState.postValue(new NetworkState(NetworkState.Status.FIRST_FAILED, errorMessage));
callback.onResult(new ArrayList<>(), Integer.toString(1), Integer.toString(2));
}
});
}
#Override
public void loadAfter(#NonNull LoadParams<String> params, final #NonNull LoadCallback<String, ReqDataList> callback) {
Log.i(TAG, "Loading page " + params.key );
networkState.postValue(NetworkState.LOADING);
final AtomicInteger page = new AtomicInteger(0);
try {
page.set(Integer.parseInt(params.key));
}catch (NumberFormatException e){
e.printStackTrace();
}
Call<ArrayList<ReqDataList>> callBack = connectionServer.getReqByPage(page.get(), status);
callBack.enqueue(new Callback<ArrayList<ReqDataList>>() {
#Override
public void onResponse(Call<ArrayList<ReqDataList>> call, Response<ArrayList<ReqDataList>> response) {
if (response.isSuccessful()) {
callback.onResult(response.body(), Integer.toString(page.get() + 1));
networkState.postValue(NetworkState.LOADED);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
response.body().forEach(moviesObservable::onNext);
} else {
for (ReqDataList data : response.body()) {
moviesObservable.onNext(data);
}
}
} else {
networkState.postValue(new NetworkState(NetworkState.Status.FAILED, response.message()));
Log.e("API CALL", response.message());
}
}
#Override
public void onFailure(Call<ArrayList<ReqDataList>> call, Throwable t) {
String errorMessage;
if (t.getMessage() == null) {
errorMessage = "unknown error";
} else {
errorMessage = t.getMessage();
}
networkState.postValue(new NetworkState(NetworkState.Status.FAILED, errorMessage));
callback.onResult(new ArrayList<>(), Integer.toString(page.get()));
}
});
}
#Override
public void loadBefore(#NonNull LoadParams<String> params, #NonNull LoadCallback<String, ReqDataList> callback) {
}
}
PagedList.Config
public class ReqNetwork {
final private static String TAG = ReqNetwork.class.getSimpleName();
final private LiveData<PagedList<ReqDataList>> moviesPaged;
final private LiveData<NetworkState> networkState;
public ReqNetwork(NetReqDataSourceFactory dataSourceFactory, PagedList.BoundaryCallback<ReqDataList> boundaryCallback) {
PagedList.Config pagedListConfig = (new PagedList.Config.Builder())
.setEnablePlaceholders(false)
.setInitialLoadSizeHint(20)
.setPageSize(10)
.build();
networkState = Transformations.switchMap(
dataSourceFactory.getNetworkStatus(),
(Function<NetReqPageKeyedDataSource, LiveData<NetworkState>>) NetReqPageKeyedDataSource::getNetworkState
);
Executor executor = Executors.newFixedThreadPool(3);
LivePagedListBuilder livePagedListBuilder = new LivePagedListBuilder(dataSourceFactory, pagedListConfig);
moviesPaged = livePagedListBuilder.
setFetchExecutor(executor).
setBoundaryCallback(boundaryCallback).
build();
}
public LiveData<PagedList<ReqDataList>> getPagedMovies() {
return moviesPaged;
}
public LiveData<NetworkState> getNetworkState() {
return networkState;
}
}
LocalDataSource
public class DbReqDataSourceFactory extends DataSource.Factory {
private static final String TAG = DbReqDataSourceFactory.class.getSimpleName();
private DbReqPageKeyedDataSource moviesPageKeyedDataSource;
public DbReqDataSourceFactory(ReqDataDao dao, String filterStatus) {
moviesPageKeyedDataSource = new DbReqPageKeyedDataSource(dao, filterStatus);
}
#Override
public DataSource create() {
return moviesPageKeyedDataSource;
}
}
LocalPageKeyedDataSource
public class DbReqPageKeyedDataSource extends PageKeyedDataSource<String, ReqDataList> {
public static final String TAG = DbReqPageKeyedDataSource.class.getSimpleName();
private final ReqDataDao dataDao;
private String filterStatus;
public DbReqPageKeyedDataSource(ReqDataDao dao, String status) {
dataDao = dao;
filterStatus = status;
}
#Override
public void loadInitial(#NonNull LoadInitialParams<String> params, #NonNull final LoadInitialCallback<String, ReqDataList> callback) {
Log.i(TAG, "Loading Initial Rang, Count " + params.requestedLoadSize);
Log.w(TAG, "loadInitial: " + filterStatus);
List<ReqDataList> data = null;
if (filterStatus == null) {
data = dataDao.getListAll();
} else {
data = dataDao.getListAllByStatus(filterStatus);
}
if(data.size() != 0) {
callback.onResult(data, "0", "1");
}
}
#Override
public void loadAfter(#NonNull LoadParams<String> params, final #NonNull LoadCallback<String, ReqDataList> callback) {
}
#Override
public void loadBefore(#NonNull LoadParams<String> params, #NonNull LoadCallback<String, ReqDataList> callback) {
}
}
Repository
public LiveData<PagedList<ReqDataList>> getDataReqPage(Context context, String status){
initReqPageDao(status);
NetReqDataSourceFactory dataSourceFactory = new NetReqDataSourceFactory(context, status);
network = new ReqNetwork(dataSourceFactory, reqBoundaryCallback);
reqLiveDataMerger = new MediatorLiveData<>();
reqLiveDataMerger.addSource(network.getPagedMovies(), value -> {
reqLiveDataMerger.setValue(value);
Log.d(TAG, value.toString());
});
dataSourceFactory.getData().
observeOn(Schedulers.io()).
subscribe(item -> {
ReqData reqData = new ReqData();
reqData.req_sid = item.req_sid;
reqData.req_uid = item.req_uid;
reqData.req_total = item.req_total;
reqData.req_pemda = item.req_pemda;
reqData.req_lon = item.req_lon;
reqData.req_lat = item.req_lat;
reqData.req_address = item.req_address;
reqData.req_remark = item.req_remark;
reqData.address_id = item.address_id;
reqData.post_by = item.post_by;
reqData.post_date = item.post_date;
reqData.update_by = item.update_by;
reqData.update_date = item.update_date;
reqData.post_status = 1;
database.dataReqDao().insert(reqData);
});
return reqLiveDataMerger;
}
public void initReqPageDao(String status) {
PagedList.Config pagedListConfig = (new PagedList.Config.Builder()).setEnablePlaceholders(false)
.setInitialLoadSizeHint(Integer.MAX_VALUE).setPageSize(Integer.MAX_VALUE).build();
Executor executor = Executors.newFixedThreadPool(3);
DbReqDataSourceFactory dataSourceFactory = new DbReqDataSourceFactory(database.dataReqDao(), status);
LivePagedListBuilder livePagedListBuilder = new LivePagedListBuilder(dataSourceFactory, pagedListConfig);
reqPaged = livePagedListBuilder.setFetchExecutor(executor).build();
}
private PagedList.BoundaryCallback<ReqDataList> reqBoundaryCallback = new PagedList.BoundaryCallback<ReqDataList>() {
#Override
public void onZeroItemsLoaded() {
super.onZeroItemsLoaded();
reqLiveDataMerger.addSource(getReqData(), value -> {
reqLiveDataMerger.setValue(value);
reqLiveDataMerger.removeSource(getReqData());
});
}
};
public LiveData<PagedList<ReqDataList>> getReqData() {
return reqPaged;
}
ViewModel
public LiveData<PagedList<ReqDataList>> getReqDataPaged(String status) {
return getRepository().getDataReqPage(getContext(), status);
}
public LiveData<NetworkState> getNetworkState() {
return getRepository().getNetworkState();
}
Did you guys find my fault?
I load data using a Fragment inside the ViewPager
public class ReqListFragment extends BaseFragment<FragmentReqListBinding, ReqListViewModel> implements ReqListViewModel.Navigator {
#Inject
ConnectionServer server;
#Inject
MasterRepository repository;
private FragmentReqListBinding binding;
private ReqListViewModel viewModel;
private String status;
private boolean hasLoaded = false;
#Override
public int getBindingVariable() {
return 0;
}
#Override
public int getLayoutId() {
return R.layout.fragment_req_list;
}
#Override
public ReqListViewModel getViewModel() {
return viewModel;
}
public ReqListFragment newInstance(String status) {
ReqListFragment fragment = new ReqListFragment();
Bundle bundle = new Bundle();
bundle.putString(Constants.STATUS, status);
fragment.setArguments(bundle);
return fragment;
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return super.onCreateView(inflater, container, savedInstanceState);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
AndroidSupportInjection.inject(this);
binding = getViewDataBinding();
viewModel = ViewModelProviders.of(this, new ReqListViewModel.ModelFactory(getBaseActivity(), server, repository)).get(ReqListViewModel.class);
viewModel.setNavigator(this);
status = getArguments().getString(Constants.STATUS);
viewModel.filterStatus.postValue(status);
if (status.equals(Constants.ALL)) {
loadData(status);
}
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
binding.swipe.setColorSchemeColors(getResources().getColor(R.color.colorPrimary), getResources().getColor(R.color.colorApprovedBg));
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getBaseActivity());
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
binding.recyclerView.setLayoutManager(linearLayoutManager);
binding.swipe.setOnRefreshListener(()->loadData(status));
}
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if(getView() != null && isVisibleToUser && !hasLoaded && !status.equals(Constants.ALL)) {
loadData(status);
}
}
private void loadData(String status) {
binding.shimmerViewContainer.startShimmer();
binding.shimmerViewContainer.setVisibility(View.VISIBLE);
final ReqListAdapter pageListAdapter = new ReqListAdapter(viewModel);
viewModel.getReqDataPaged(status).observe(this, pageListAdapter::submitList);
viewModel.getNetworkState().observe(this, networkState -> {
pageListAdapter.setNetworkState(networkState);
binding.setState(networkState);
});
binding.recyclerView.setAdapter(pageListAdapter);
hasLoaded = true;
}
#Override
public void onItemClick(String item) {
Intent intent = new Intent(getBaseActivity(), ReqViewActivity.class);
intent.putExtra(Constants.SID, item);
startActivity(intent);
}
}
In other conditions I succeed if I move the code initReqPageDao to the RoomDatabase class,
but i am confused about sending status for filter
Thank you all for your help, I hope I find the error and a solution

Unable to save ArrayList value in Shared Preference in Andorid

Can any one help me whats wrong in my code
unable to save ArrayList document value in shared Preference
getting null value in Debug of Array List Document
please help me
Thanks in advance
here is my JSON response
{
"errCode": 0,
"message": "Success",
"responseDestinationDocument": [
{
"name": "United Arab Emirates",
"document": [
{
"name": "Passport Front",
"id": "2",
"notes": [
{
"name": "Upload colored passport copies."
},
{
"name": "Passport should be valid 6 months from the date of entry in Sri Lanka."
},
{
"name": "DDDDDDD"
}
]
},
{
"name": "Passport Back",
"id": "3",
"notes": [
{
"name": "Upload colored passport copy."
}
]
},
{
"name": "Photograph",
"id": "4",
"notes": [
{
"name": "Upload photograph with white background"
}
]
}
]
}
]
}
I want to save ArrayList document value in shared Preference
Here is activity code
public class UploadDocumentsActivity extends AppCompatActivity {
private MyCustomAdapter myCustomAdapter;
protected ViewDialog viewDialog;
String destination_id, start_date, end_date, no_of_travellers, destination_name, package_id, radioSexButton, booking_id, count_index;
private List<ResponseBookingDocument> responseBookingDocumentArrayList;
private List<Document> document1ArrayList;
Document document1;
private RecyclerView recyclerView_Identity;
private static final int SELECT_PICTURE = 100;
private static final int STORAGE_PERMISSION_CODE = 123;
final Handler handler = new Handler();
final int delay = 1000; //milliseconds
private ImageView imageView1;
String selectedImagePath;
private Uri filePath_1;
private boolean isOnTag = false;
Bitmap bitmap;
preivate ArrayList<String> nameList = new ArrayList<>();
preivate ArrayList<String> idList = new ArrayList<>();
TextView continueTextView;
private Runnable mToast = new Runnable() {
#Override
public void run() {
// documentRequiredCall();
handler.postDelayed(this, 1000);
}
};
ResponseBookInfo responseBookInfo;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_upload_documents);
viewDialog = new ViewDialog(this);
viewDialog.setCancelable(false);
// Log.e("document1", document1.getId() + "");
try {
document1 = PrefUtils.getDocId(UploadDocumentsActivity.this);
Log.e("document1", document1.getId() + "");
} catch (Exception e) {
e.printStackTrace();
}
Intent i = getIntent();
destination_id = i.getStringExtra("destination_id");
package_id = i.getStringExtra("package_id");
radioSexButton = i.getStringExtra("radioSexButton");
booking_id = i.getStringExtra("booking_id");
count_index = i.getStringExtra("count_index");
Log.e("BookING", booking_id + "");
destination_name = i.getStringExtra("destination_name");
start_date = i.getStringExtra("start_date");
end_date = i.getStringExtra("end_date");
no_of_travellers = i.getStringExtra("no_of_travellers");
recyclerView_Identity = findViewById(R.id.recyclerView_Identity);
continueTextView = findViewById(R.id.continueTextView);
LinearLayoutManager layoutManager = new LinearLayoutManager(UploadDocumentsActivity.this);
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView_Identity.setLayoutManager(layoutManager);
recyclerView_Identity.setHasFixedSize(true);
continueTextView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(UploadDocumentsActivity.this, ApplicationFormActivity.class);
i.putExtra("booking_id", booking_id);
i.putExtra("count_index", count_index);
i.putExtra("start_date", start_date);
i.putExtra("end_date", end_date);
startActivity(i);
}
});
documentRequiredCall();
//
Log.e("Values", destination_id + " " + package_id + " " + end_date + " " + no_of_travellers + " " + count_index + "");
}
public void documentRequiredCall() {
Call<DocumentFetchModel> call = RetrofitClient
.getInstance().getApi().documentFetchModel(booking_id, count_index);
showProgressDialog();
call.enqueue(new Callback<DocumentFetchModel>() {
#Override
public void onResponse(Call<DocumentFetchModel> call, retrofit2.Response<DocumentFetchModel> response) {
final DocumentFetchModel documentFetchModel = response.body();
hideProgressDialog();
PrefUtils.setDocId(documentFetchModel.getResponseBookingDocument().get(0).getDocument(), UploadDocumentsActivity.this);
int size = documentFetchModel.getResponseBookingDocument().get(0).getDocument().size();
for (int i = 0; i < size; i++) {
nameList.add(documentFetchModel.getResponseBookingDocument().get(0).getDocument().get(i).getName());
idList.add(documentFetchModel.getResponseBookingDocument().get(0).getDocument().get(i).getId());
}
//here is app preference class saving the values
AppPreference.setNameList(this, nameList);
AppPreference.setIdList(this, idLIst);
if (documentFetchModel.getErrCode().booleanValue() == true) {
responseBookingDocumentArrayList = new ArrayList<ResponseBookingDocument>();
try {
Log.e("Booking_Document", new Gson().toJson(response.body()));
document1ArrayList = documentFetchModel.getResponseBookingDocument().get(0).getDocument();
myCustomAdapter = new MyCustomAdapter(document1ArrayList);
recyclerView_Identity.setAdapter(myCustomAdapter);
myCustomAdapter.notifyDataSetChanged();
} catch (Exception e) {
e.printStackTrace();
}
} else {
Toast.makeText(UploadDocumentsActivity.this, documentFetchModel.getMessage() + "", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(Call<DocumentFetchModel> call, Throwable t) {
hideProgressDialog();
Toast.makeText(UploadDocumentsActivity.this, t.getMessage() + "", Toast.LENGTH_LONG).show();
Log.e("Error", t.getMessage() + "");
}
});
}
protected void hideProgressDialog() {
viewDialog.dismiss();
}
protected void showProgressDialog() {
viewDialog.show();
}
protected void showProgressDialog(String message) {
showProgressDialog();
}
public class MyCustomAdapter extends RecyclerView.Adapter<MyCustomAdapter.MyViewHolder> {
private List<Document> moviesList;
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView textTitle;
public ImageView imageUpload, imageFetch;
private List<Note> noteArrayList;
private MyCustomAdapter2 myCustomAdapter2;
private RecyclerView recyclerView_Identity_Bullets;
public MyViewHolder(View view) {
super(view);
textTitle = view.findViewById(R.id.textTitle);
imageUpload = view.findViewById(R.id.imageUpload);
imageFetch = view.findViewById(R.id.imageFetch);
recyclerView_Identity_Bullets = view.findViewById(R.id.recyclerView_Identity_Bullets);
LinearLayoutManager layoutManager2 = new LinearLayoutManager(UploadDocumentsActivity.this);
layoutManager2.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView_Identity_Bullets.setLayoutManager(layoutManager2);
recyclerView_Identity_Bullets.setHasFixedSize(true);
}
}
public MyCustomAdapter(List<Document> moviesList) {
this.moviesList = moviesList;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_upload_document, parent, false);
return new MyCustomAdapter.MyViewHolder(itemView);
}
public void clear() {
int size = this.moviesList.size();
if (size > 0) {
for (int i = 0; i < size; i++) {
this.moviesList.remove(0);
}
this.notifyItemRangeRemoved(0, size);
}
}
#Override
public void onBindViewHolder(final MyViewHolder holder, final int position) {
final Document datum = moviesList.get(position);
holder.textTitle.setText(datum.getName() + "");
holder.noteArrayList = datum.getNotes();
holder.myCustomAdapter2 = new MyCustomAdapter2(holder.noteArrayList);
holder.recyclerView_Identity_Bullets.setAdapter(holder.myCustomAdapter2);
if (datum.getImageName().equals("")) {
holder.imageFetch.setVisibility(View.GONE);
holder.imageUpload.setVisibility(View.VISIBLE);
holder.imageUpload.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(UploadDocumentsActivity.this, datum.getId(), Toast.LENGTH_SHORT).show();
}
});
} else {
holder.imageUpload.setVisibility(View.GONE);
holder.imageFetch.setVisibility(View.VISIBLE);
Picasso.with(UploadDocumentsActivity.this).load(datum.getImageName() + "").into(holder.imageFetch);
}
}
#Override
public int getItemCount() {
return moviesList.size();
}
}
public class MyCustomAdapter2 extends RecyclerView.Adapter<MyCustomAdapter2.MyViewHolder> {
private List<Note> moviesList;
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView textBullet;
public MyViewHolder(View view) {
super(view);
textBullet = view.findViewById(R.id.textBullet);
}
}
public MyCustomAdapter2(List<Note> moviesList) {
this.moviesList = moviesList;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_upload_bullets_and_image, parent, false);
return new MyViewHolder(itemView);
}
public void clear() {
int size = this.moviesList.size();
if (size > 0) {
for (int i = 0; i < size; i++) {
this.moviesList.remove(0);
}
this.notifyItemRangeRemoved(0, size);
}
}
#Override
public void onBindViewHolder(MyViewHolder holder, final int position) {
final Note datum = moviesList.get(position);
holder.textBullet.setText(" \u25CF " + datum.getName() + "");
Log.e("textBullet", datum.getName() + "");
}
#Override
public int getItemCount() {
return moviesList.size();
}
}
#Override
public void onStart() {
super.onStart();
mToast.run();
}
#Override
public void onStop() {
super.onStop();
handler.removeCallbacks(mToast);
}
}
Here is Model Class
public class DocumentFetchModel {
#SerializedName("errCode")
#Expose
private Boolean errCode;
#SerializedName("message")
#Expose
private String message;
#SerializedName("responseBookingDocument")
#Expose
private List<ResponseBookingDocument> responseBookingDocument = null;
public Boolean getErrCode() {
return errCode;
}
public void setErrCode(Boolean errCode) {
this.errCode = errCode;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public List<ResponseBookingDocument> getResponseBookingDocument() {
return responseBookingDocument;
}
public void setResponseBookingDocument(List<ResponseBookingDocument> responseBookingDocument) {
this.responseBookingDocument = responseBookingDocument;
}
}
public class ResponseBookingDocument {
#SerializedName("name")
#Expose
private String name;
#SerializedName("document")
#Expose
private List<Document> document = null;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Document> getDocument() {
return document;
}
public void setDocument(List<Document> document) {
this.document = document;
}
}
public class DocumentFetchModel {
#SerializedName("errCode")
#Expose
private Boolean errCode;
#SerializedName("message")
#Expose
private String message;
#SerializedName("responseBookingDocument")
#Expose
private List<ResponseBookingDocument> responseBookingDocument = null;
public Boolean getErrCode() {
return errCode;
}
public void setErrCode(Boolean errCode) {
this.errCode = errCode;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public List<ResponseBookingDocument> getResponseBookingDocument() {
return responseBookingDocument;
}
public void setResponseBookingDocument(List<ResponseBookingDocument> responseBookingDocument) {
this.responseBookingDocument = responseBookingDocument;
}
}
Here is ComplexPreference
public class ComplexPreferences {
private static ComplexPreferences complexPreferences;
private Context context;
private SharedPreferences preferences;
private SharedPreferences.Editor editor;
private static Gson GSON = new Gson();
Type typeOfObject = new TypeToken<Object>() {
}.getType();
private ComplexPreferences(Context context, String namePreferences, int mode) {
this.context = context;
if (namePreferences == null || namePreferences.equals("")) {
namePreferences = "complex_preferences";
}
preferences = context.getSharedPreferences(namePreferences, mode);
editor = preferences.edit();
}
public static ComplexPreferences getComplexPreferences(Context context,
String namePreferences, int mode) {
// if (complexPreferences == null) {
complexPreferences = new ComplexPreferences(context,
namePreferences, mode);
// }
return complexPreferences;
}
public void putObject(String key, Object object) {
if(object == null){
throw new IllegalArgumentException("object is null");
}
if(key.equals("") || key == null){
throw new IllegalArgumentException("key is empty or null");
}
editor.putString(key, GSON.toJson(object));
}
public void commit() {
editor.commit();
}
public void clearObject() {
editor.clear();
}
public <T> T getObject(String key, Class<T> a) {
String gson = preferences.getString(key, null);
if (gson == null) {
return null;
} else {
try{
return GSON.fromJson(gson, a);
} catch (Exception e) {
throw new IllegalArgumentException("Object storaged with key " + key + " is instanceof other class");
}
}
}
}
Here is PrefUtils Class
public class PrefUtils {
public static DocumentFetchModel getDoc(Context ctx) {
ComplexPreferences complexPreferences = ComplexPreferences.getComplexPreferences(ctx, "get_doc", 0);
DocumentFetchModel currentUser = complexPreferences.getObject("docs", DocumentFetchModel.class);
return currentUser;
}
public static void setDoc(DocumentFetchModel currentUser, Context ctx) {
ComplexPreferences complexPreferences = ComplexPreferences.getComplexPreferences(ctx, "get_doc", 0);
complexPreferences.putObject("docs", currentUser);
complexPreferences.commit();
}
}
you can save list in sharedpreference like this:-
public class AppPreferences {
private static SharedPreferences mPrefs;
private static SharedPreferences.Editor mPrefsEditor;
public static Set<String> getName(Context ctx) {
mPrefs = PreferenceManager.getDefaultSharedPreferences(ctx);
return mPrefs.getStringSet("nameList", null);
}
public static void setName(Context ctx, ArrayList<String> value) {
mPrefs = PreferenceManager.getDefaultSharedPreferences(ctx);
mPrefsEditor = mPrefs.edit();
Set<String> set = new HashSet<>();
set.addAll(value);
mPrefsEditor.putStringSet("nameList", set);
mPrefsEditor.commit();
}
public static void clearNameList(Context ctx) {
mPrefs = PreferenceManager.getDefaultSharedPreferences(ctx);
mPrefsEditor = mPrefs.edit();
Set<String> set = new HashSet<>();
mPrefsEditor.putStringSet("nameList", set);
mPrefsEditor.commit();
}
}
to set list :-
setCamEval(activity, list);
to get list :-
getCamEval(this);

Errors when trying to save strings, ints and spinner values to room persistence database in Android Studio

I'm trying to create a database within my step counting program that is able to save a user's details: Name, Age, Gender, Average Stride Length, Weight and Height in Android Studio. However I keep encountering errors that I am unable to locate or solve. Apologies if it is a rookie mistake; I am not in possession of a great deal of experience for Android Studio or the Room Persistence Library. Here is the code in question:
UserDetails.java:
#Entity(tableName = "user details")
public class UserDetails extends AppCompatActivity {
#NonNull
//each value for the primary key will be assigned a unique,
// automatically generated UserID
#PrimaryKey (autoGenerate = true)
#ColumnInfo(name = "ID")
public int UserID;
#ColumnInfo(name = "Name")
public String UserName;
#ColumnInfo(name = "Age")
public int UserAge;
#ColumnInfo(name = "Gender")
public String UserGender;
#ColumnInfo(name = "Average Stride Length")
public int UserAveStride;
#ColumnInfo(name = "Weight")
public int UserWeight;
#ColumnInfo(name = "Height")
public int UserHeight;
public UserDetails() {
}
#Ignore
public UserDetails(String userName, int userAge, String userGender, int
userAveStride, int userWeight, int userHeight) {
UserName = userName;
UserAge = userAge;
UserGender = userGender;
UserAveStride = userAveStride;
UserWeight = userWeight;
UserHeight = userHeight;
}
public int getUserID() {
return UserID;
}
public void setUserID(int userID) {
UserID = userID;
}
public String getUserName() {
return UserName;
}
public void setUserName(String userName) {
UserName = userName;
}
public int getUserAge() {
return UserAge;
}
public void setUserAge(int userAge) {
UserAge = userAge;
}
public String getUserGender() {
return UserGender;
}
public void setUserGender(String userGender) {
UserGender = userGender;
}
public int getUserAveStride() {
return UserAveStride;
}
public void setUserAveStride(int userAveStride) {
UserAveStride = userAveStride;
}
public int getUserWeight() {
return UserWeight;
}
public void setUserWeight(int userWeight) {
UserWeight = userWeight;
}
public int getUserHeight() {
return UserHeight;
}
public void setUserHeight(int userHeight) {
UserHeight = userHeight;
}
#Override
public String toString(){
return new
StringBuilder(UserName).append("\n").append(UserAge).append("\n")
.append(UserGender).append("\n").append(UserAveStride).append("\n")
.append(UserWeight).append("\n").append(UserHeight).toString();
}
DbContent.java
public class DbContent extends AppCompatActivity {
private ListView lstUser;
private FloatingActionButton fab;
//array adapter
List<UserDetails> userList;
ArrayAdapter adapter;
//database
private CompositeDisposable compositeDisposable;
private UserRepository userRepository;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_db_content);
//init
compositeDisposable = new CompositeDisposable();
//init view
lstUser = findViewById(R.id.lstUsers);
fab = findViewById(R.id.fab);
adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1,
userList);
registerForContextMenu(lstUser);
lstUser.setAdapter(adapter);
//creating database
Database database = Database.getmInstance(this);
userRepository =
UserRepository.getmInstance(UserDataSource.getmInstance(database.userDao()));
//load all data from database
loadData();
//getting values from user inputs
final EditText name = findViewById(R.id.nameInput);
final EditText age = findViewById(R.id.ageInput);
final Spinner gender = findViewById(R.id.genderDropDown);
final EditText aveStride = findViewById(R.id.strideInput);
final EditText weight = findViewById(R.id.weightInput);
final EditText height = findViewById(R.id.heightInput);
//converting to strings
final String nameStr = name.getText().toString();
final String ageStr = age.getText().toString();
final String genderStr = gender.getSelectedItem().toString();
final String aveStrideStr = aveStride.getText().toString();
final String weightStr = weight.getText().toString();
final String heightStr = height.getText().toString();
//converting string to int where needed
final int ageInt = Integer.parseInt(ageStr);
final int aveStrideInt = Integer.parseInt(aveStrideStr);
final int weightInt = Integer.parseInt(weightStr);
final int heightInt = Integer.parseInt(heightStr);
//Event
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//Add new
Disposable disposable = (Disposable) io.reactivex
.Observable.create(new ObservableOnSubscribe<Object>() {
#Override
public void subscribe(ObservableEmitter<Object> e) throws
Exception {
UserDetails userDetails = new UserDetails(nameStr,
ageInt,
genderStr, aveStrideInt, weightInt, heightInt);
userRepository.insertUser(userDetails);
e.onComplete();
}
})
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(new Consumer() {
#Override
public void accept(Object o) throws Exception {
Toast.makeText(DbContent.this,
"Data added", Toast.LENGTH_SHORT).show();
}
}, new Consumer<Throwable>() {
#Override
public void accept(Throwable throwable) throws Exception {
Toast.makeText(DbContent.this,
"" + throwable.getMessage(), Toast.LENGTH_SHORT).show();
}
//Refreshing data
}, new Action() {
#Override
public void run() throws Exception {
loadData();
}
}
);
}
});
}
private void loadData() {
//Using RXJava
Disposable disposable = userRepository.getAllDetails()
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(new Consumer<List<UserDetails>>() {
#Override
public void accept(List<UserDetails> userDetails) throws Exception {
OnGetAllDetailsSuccess(userDetails);
}
}, new Consumer<Throwable>() {
#Override
public void accept(Throwable throwable) throws Exception {
Toast.makeText(DbContent.this, ""+throwable.getMessage(), Toast.LENGTH_SHORT).show();
}
});
compositeDisposable.add(disposable);
}
private void OnGetAllDetailsSuccess(List<UserDetails> userDetails) {
userList.clear();
userList.addAll(userDetails);
adapter.notifyDataSetChanged();
}
}
Database.java
#android.arch.persistence.room.Database(entities = {UserDetails.class},
version = DATABASE_VERSION)
public abstract class Database extends RoomDatabase {
public static final int DATABASE_VERSION=1;
public static final String DATABASE_NAME ="Database-Room";
public abstract UserDao userDao();
private static Database mInstance;
public static Database getmInstance(Context context)
{
if (mInstance == null){
mInstance = Room.databaseBuilder(context,Database.class,DATABASE_NAME)
.fallbackToDestructiveMigration()
.build();
}
return mInstance;
}
}
UserDataSource.java
public class UserDataSource implements IUserDataSource {
private UserDao userDao;
private static UserDataSource mInstance;
public UserDataSource(UserDao userDao) {
this.userDao = userDao;
}
public static UserDataSource getmInstance(UserDao userDao) {
if(mInstance == null){
mInstance = new UserDataSource(userDao);
}
return mInstance;
}
#Override
public Flowable<UserDetails> getUserById(int userId) {
return userDao.getUserById(userId);
}
#Override
public Flowable<List<UserDetails>> getAllDetails() {
return userDao.getAllDetails();
}
#Override
public void insertUser(UserDetails... userDetails) {
userDao.insertUser(userDetails);
}
#Override
public void updateUser(UserDetails... userDetails) {
userDao.updateUser(userDetails);
}
#Override
public void deleteUser(UserDetails userDetails) {
userDao.deleteUser(userDetails);
}
}
UserRepository.java
public class UserRepository implements IUserDataSource {
private IUserDataSource mLocalDataSource;
private static UserRepository mInstance;
public UserRepository(IUserDataSource mLocalDataSource) {
this.mLocalDataSource = mLocalDataSource;
}
public static UserRepository getmInstance(IUserDataSource mLocalDataSource) {
if(mInstance == null){
mInstance = new UserRepository(mLocalDataSource);
}
return mInstance;
}
#Override
public Flowable<UserDetails> getUserById(int userId) {
return mLocalDataSource.getUserById(userId);
}
#Override
public Flowable<List<UserDetails>> getAllDetails() {
return mLocalDataSource.getAllDetails();
}
#Override
public void insertUser(UserDetails... userDetails) {
mLocalDataSource.insertUser(userDetails);
}
#Override
public void updateUser(UserDetails... userDetails) {
mLocalDataSource.updateUser(userDetails);
}
#Override
public void deleteUser(UserDetails userDetails) {
mLocalDataSource.deleteUser(userDetails);
}
}
UserDao.java
#Dao
public interface UserDao {
#Query("SELECT * FROM `user details` WHERE id=:userId")
Flowable<UserDetails> getUserById(int userId);
#Query("SELECT * FROM `user details`")
Flowable<List<UserDetails>> getAllDetails();
#Insert
void insertUser(UserDetails... userDetails);
#Update
void updateUser(UserDetails... userDetails);
#Delete
void deleteUser(UserDetails userDetails);
}
IUserDataSource.java
public interface IUserDataSource {
Flowable<UserDetails> getUserById(int userId);
Flowable<List<UserDetails>> getAllDetails();
void insertUser(UserDetails... userDetails);
void updateUser(UserDetails... userDetails);
void deleteUser(UserDetails userDetails);
}
The errors are:
Cannot figure out how to save this field into database. You can consider adding a type converter for it.
Cannot find getter for field.
Cannot find setter for field.
Cannot figure out how to read this field from a cursor.
Cannot find getter for field.
Cannot find setter for field.
I appreciate any help greatly as I have spent a number of hours trying to fix this and this project is one fifth of my grade; it is due in soon and I need to spend time finishing other features and testing it rather than spending hours trying to fix errors. Thank you.
I believe that the errors you are trying to describe are similar to :-
The cause of these would be that you have made your UserDetails a subclass of the AppCompatActivity class by encoding extends AppCompatActivity
Instead of :-
#Entity(tableName = "user details")
public class UserDetails extends AppCompatActivity { ..........
You should have :-
#Entity(tableName = "user details")
public class UserDetails { ........
Note the dots represent the rest of the code, they are not intended to be coded, they are for the sake of brevity.

Data not being stored when using Spring JPA with android

I am developing an app which would talk to the server which is developed using spring. I got to a point where we i was getting data from the google api and wanted to pass it to the spring server. But when i do pass it, the server accepts it but the data is not being stored in the mysql database.
Here is the code I am using:
This is the main spring application + controller:
#EnableJpaRepositories(basePackageClasses = StudentRepository.class)
#SpringBootApplication
public class Demo3Application {
public static void main(String[] args) {
SpringApplication.run(Demo3Application.class, args);
}
}
#RestController
class StudentController
{
#Autowired
public StudentRepository students;
#RequestMapping(value = "/getstudent", method = RequestMethod.GET)
public #ResponseBody List<Student> fetchStudents()
{
if(students.count() == 0)
{
Vector<VideoList> no_video = new Vector<VideoList>();
VideoList no_v = new VideoList("No Videos found", null, null, null);
no_video.add(no_v);
return no_video;
return null;
}
return null;
}
#RequestMapping(value = "/poststudent" , method = RequestMethod.POST)
public #ResponseBody String putStudents(#RequestBody Student v )
{
students.save(v);
return "Student Successfully Added";
}
#RequestMapping(value = "/searchstudent/{str}" , method = RequestMethod.GET)
public #ResponseBody String searchStudent(
#PathVariable("str") String searchQuery
)
{
if(students.existsByEmail(searchQuery)){
List<Student> sList = students.findEmail(searchQuery,new PageRequest(0, 1));
Student s = sList.get(0);
String str = "";
Vector<CourseList> c = s.getCourses();
Iterator<CourseList> it = c.iterator();
while(it.hasNext()){
str.concat(it.next().toString());
str.concat("\n");
}
return str;
}
return null ;
}
#RequestMapping(value = "/addcourse" , method = RequestMethod.POST)
public #ResponseBody String postCourse(#RequestParam String email, #RequestParam String course){
List<Student> sList = students.findEmail(email,new PageRequest(0, 1));
Student s = sList.get(0);
CourseList c = new CourseList();
c.setName(course);
s.addCourse(c);
students.save(s);
return null;
}
}
This is the Student class:
#Entity
#Table(name = "table1")
public class Student {
private String name;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private int id;
private String email;
private Vector<CourseList> courses = new Vector<CourseList>();//CourseList is just a class to store data about various courses.
public Student(){}
public String getName(){
return name;
}
public String getEmail(){
return email;
}
public Vector<CourseList> getCourses(){
return courses;
}
public void setName(String name){
this.name = name;
}
public void setEmail(String email){
this.email = email;
}
public void setCourses(Vector<CourseList> courses){
this.courses = courses;
}
public void addCourse(CourseList c){
courses.add(c);
}
}
This is my repository:
#Repository
#Transactional
public interface StudentRepository extends CrudRepository<Student,String>{
#Query("SELECT s FROM Student s WHERE email = ?1")
public List<Student> findEmail(String searchQuery, Pageable pageable);
#Query("SELECT CASE WHEN COUNT(s) > 0 THEN 'true' ELSE 'false' END FROM Student s WHERE s.email = ?1")
public boolean existsByEmail(String searchQuery);
}
This is my application.properties file:
spring.datasource.url: jdbc:mysql://localhost/mydb
spring.datasource.driverClassName: com.mysql.jdbc.Driver
spring.datasource.username: root
spring.datasource.password:root
# Specify the DBMS
spring.jpa.database = MYSQL
# Show or not log for each sql query
spring.jpa.show-sql = true
# Hibernate ddl auto (create, create-drop, update)
spring.jpa.hibernate.ddl-auto = update
# Naming strategy
spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy
# Use spring.jpa.properties.* for Hibernate native properties (the prefix is
# stripped before adding them to the entity manager)
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
And finally here is the android code to test the above:
public class MainActivity extends Activity implements OnClickListener,
ConnectionCallbacks, OnConnectionFailedListener {
private static final int RC_SIGN_IN = 0;
// Logcat tag
private static final String TAG = "MainActivity";
// Profile pic image size in pixels
private static final int PROFILE_PIC_SIZE = 400;
// Google client to interact with Google API
private GoogleApiClient mGoogleApiClient;
/**
* A flag indicating that a PendingIntent is in progress and prevents us
* from starting further intents.
*/
private boolean mIntentInProgress;
private boolean mSignInClicked;
private ConnectionResult mConnectionResult;
private SignInButton btnSignIn;
private Button btnSignOut;
private ImageView imgProfilePic;
private TextView txtName, txtEmail, course;
private LinearLayout llProfileLayout;
private Button SC;
private String personName;
private String personPhotoUrl;
private String personGooglePlusProfile;
private String email;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnSignIn = (SignInButton) findViewById(R.id.btn_sign_in);
btnSignOut = (Button) findViewById(R.id.btn_sign_out);
imgProfilePic = (ImageView) findViewById(R.id.imgProfilePic);
txtName = (TextView) findViewById(R.id.txtName);
course = (TextView) findViewById(R.id.txtCourses);
txtEmail = (TextView) findViewById(R.id.txtEmail);
llProfileLayout = (LinearLayout) findViewById(R.id.llProfile);
SC=(Button)findViewById(R.id.Scourse);
// Button click listeners
btnSignIn.setOnClickListener(this);
btnSignOut.setOnClickListener(this);
SC.setOnClickListener(this);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).addApi(Plus.API)
.addScope(Plus.SCOPE_PLUS_LOGIN).build();
}
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
protected void onStop() {
super.onStop();
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
/**
* Method to resolve any signin errors
* */
private void resolveSignInError() {
if (mConnectionResult.hasResolution()) {
try {
mIntentInProgress = true;
mConnectionResult.startResolutionForResult(this, RC_SIGN_IN);
} catch (SendIntentException e) {
mIntentInProgress = false;
mGoogleApiClient.connect();
}
}
}
#Override
public void onConnectionFailed(ConnectionResult result) {
if (!result.hasResolution()) {
GooglePlayServicesUtil.getErrorDialog(result.getErrorCode(), this,
0).show();
return;
}
if (!mIntentInProgress) {
// Store the ConnectionResult for later usage
mConnectionResult = result;
if (mSignInClicked) {
// The user has already clicked 'sign-in' so we attempt to
// resolve all
// errors until the user is signed in, or they cancel.
resolveSignInError();
}
}
}
#Override
protected void onActivityResult(int requestCode, int responseCode,
Intent intent) {
if (requestCode == RC_SIGN_IN) {
if (responseCode != RESULT_OK) {
mSignInClicked = false;
}
mIntentInProgress = false;
if (!mGoogleApiClient.isConnecting()) {
mGoogleApiClient.connect();
}
}
}
#Override
public void onConnected(Bundle arg0) {
mSignInClicked = false;
Toast.makeText(this, "User is connected!", Toast.LENGTH_LONG).show();
// Get user's information
getProfileInformation();
// Update the UI after signin
updateUI(true);
}
/**
* Updating the UI, showing/hiding buttons and profile layout
* */
private void updateUI(boolean isSignedIn) {
if (isSignedIn) {
btnSignIn.setVisibility(View.GONE);
btnSignOut.setVisibility(View.VISIBLE);
llProfileLayout.setVisibility(View.VISIBLE);
getCourses();
SC.setVisibility(View.VISIBLE);
} else {
btnSignIn.setVisibility(View.VISIBLE);
btnSignOut.setVisibility(View.GONE);
llProfileLayout.setVisibility(View.GONE);
course.setText(" ");
SC.setVisibility(View.GONE);
}
}
private void getCourses(){
new StudentSearch().execute();
}
private class StudentSearch extends AsyncTask<String, Void, String >
{
String content = "";
#Override
protected String doInBackground(String... urls) {
HttpClient httpClient = new DefaultHttpClient();
HttpGet httpget = new HttpGet("http://192.168.49.8:8080/searchstudent/"+email);
StringBuffer studentString = new StringBuffer();
try {
HttpResponse response = httpClient.execute(httpget);
InputStream responseString = response.getEntity().getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(responseString));
String res = "";
if ((res = reader.readLine()) == null) {
studentString.append("");
HttpPost httpPost = new HttpPost("http://192.168.49.8:8080/poststudent/");
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put("name", personName);
jsonObject.put("email", email);
} catch (JSONException e) {
e.printStackTrace();
}
try {
StringEntity se = new StringEntity(jsonObject.toString());
se.setContentType("application/json;charset=UTF-8");
se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json;charset=UTF-8"));
httpPost.setEntity(se);
} catch (UnsupportedEncodingException e) {
// writing error to Log
e.printStackTrace();
}
} else {
studentString.append(res);
studentString.append("\n");
while ((res = reader.readLine()) != null) {
studentString.append(res);
studentString.append("\n");
}
}
}
catch(Exception e)
{
e.printStackTrace();
}
return studentString.toString();
}
#Override
protected void onPostExecute(String s) {
if (!s.isEmpty()){
course.setText("Courses Taken:\n"+s);}
else
course.setText("No Courses Taken!");
}
}
/**
* Fetching user's information name, email, profile pic
* */
private void getProfileInformation() {
try {
if (Plus.PeopleApi.getCurrentPerson(mGoogleApiClient) != null) {
Person currentPerson = Plus.PeopleApi
.getCurrentPerson(mGoogleApiClient);
personName = currentPerson.getDisplayName();
personPhotoUrl = currentPerson.getImage().getUrl();
personGooglePlusProfile = currentPerson.getUrl();
email = Plus.AccountApi.getAccountName(mGoogleApiClient);
Log.e(TAG, "Name: " + personName + ", plusProfile: "
+ personGooglePlusProfile + ", email: " + email
+ ", Image: " + personPhotoUrl);
txtName.setText(personName);
txtEmail.setText(email);
// by default the profile url gives 50x50 px image only
// we can replace the value with whatever dimension we want by
// replacing sz=X
personPhotoUrl = personPhotoUrl.substring(0,
personPhotoUrl.length() - 2)
+ PROFILE_PIC_SIZE;
new LoadProfileImage(imgProfilePic).execute(personPhotoUrl);
} else {
Toast.makeText(getApplicationContext(),
"Person information is null", Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onConnectionSuspended(int arg0) {
mGoogleApiClient.connect();
updateUI(false);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
return true;
}
/**
* Button on click listener
* */
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_sign_in:
// Signin button clicked
signInWithGplus();
break;
case R.id.btn_sign_out:
// Signout button clicked
signOutFromGplus();
break;
case R.id.Scourse:
{
Intent intent=new Intent(MainActivity.this,SelectCourse.class);
startActivity(intent);
break;
}
}
}
/**
* Sign-in into google
* */
private void signInWithGplus() {
if (!mGoogleApiClient.isConnecting()) {
mSignInClicked = true;
resolveSignInError();
}
}
/**
* Sign-out from google
* */
private void signOutFromGplus() {
if (mGoogleApiClient.isConnected()) {
Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
mGoogleApiClient.disconnect();
mGoogleApiClient.connect();
updateUI(false);
}
}
/**
* Background Async task to load user profile picture from url
* */
private class LoadProfileImage extends AsyncTask<String, Void, Bitmap> {
ImageView bmImage;
public LoadProfileImage(ImageView bmImage) {
this.bmImage = bmImage;
}
protected Bitmap doInBackground(String... urls) {
String urldisplay = urls[0];
Bitmap mIcon11 = null;
try {
InputStream in = new java.net.URL(urldisplay).openStream();
mIcon11 = BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return mIcon11;
}
protected void onPostExecute(Bitmap result) {
bmImage.setImageBitmap(result);
}
}
}
I am a total newbie when it comes to developing spring code and would really appreciate some help.

Categories

Resources