Found a tutorial online for building a simple blockchain app on android studio but when I finished it has key missing declarations which are coming up as unused. My capabilities allow me to resolve most minor errors through the Run and Logcat monitors while debugging but a series of stacked issues like this seems to pose too large of an issue. Here are the pages that it specifies as missing declarations:
BlockChainManager
package com.example.blockchain.managers;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.example.blockchain.adapter.BlockAdapter;
import com.example.blockchain.models.BlockModel;
import java.util.ArrayList;
import java.util.List;
public class BlockChainManager {
private final int difficulty;
private final List<BlockModel> blocks;
public final BlockAdapter adapter;
public BlockChainManager(int difficulty, #NonNull Context context) {
this.difficulty = difficulty;
blocks = new ArrayList<>();
BlockModel block = new BlockModel(0,System.currentTimeMillis(),null,"Genesis Block");
block.mineBlock(difficulty);
blocks.add(block);
adapter = new BlockAdapter(blocks,context);
}
public BlockModel newBlock(String data){
BlockModel latestBlock = lastestBlock();
return new BlockModel(latestBlock.getIndex()+1,System.currentTimeMillis(),latestBlock.getHash(),data);
}
private BlockModel lastestBlock() {
return blocks.get(blocks.size()-1);
}
public void addBlock(BlockModel block){
if (block!= null){
block.mineBlock(difficulty);
blocks.add(block);
}
}
private boolean isFirstBlockValid(){
BlockModel firstBlock = blocks.get(0);
if (firstBlock.getIndex()!=0){
return false;
}
if (firstBlock.getPreviousHash()!=null){
return false;
}
return firstBlock.getHash()!=null &&
BlockModel.calculateHash_detail(firstBlock).equals(firstBlock.getHash());
}
private boolean isValidNewBlock(#Nullable BlockModel newBlock, #Nullable BlockModel previousBlock){
if (newBlock!=null && previousBlock!= null){
if (previousBlock.getIndex()+1!=newBlock.getIndex()){
return false;
}
if (newBlock.getPreviousHash()==null || !newBlock.getPreviousHash().equals(newBlock.getData())){
return false;
}
return newBlock.getHash()!=null &&
BlockModel.calculateHash_detail(newBlock).equals(newBlock.getHash());
}
return false;
}
public boolean isBlockChainValid(){
if (!isFirstBlockValid()){
return false;
}
for (int i = 1 ; i<blocks.size();i++){
BlockModel currentBlock = blocks.get(i);
BlockModel previousBlock = blocks.get(i-1);
if (!isValidNewBlock(currentBlock,previousBlock))
return false;
}
return true;
}
}
BlockModel
package com.example.blockchain.models;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class BlockModel {
private int index,nonce;
private long timestamp;
private String hash,previousHash,data;
public BlockModel(int index, long timestamp, String previousHash, String data) {
this.index = index;
this.timestamp = timestamp;
this.previousHash = previousHash;
this.data = data;
nonce = 0;
hash = BlockModel.calculateHash_detail(this);
}
public static String calculateHash_detail(BlockModel blockModel) {
if (blockModel!= null){
MessageDigest messageDigest;
try{
messageDigest = MessageDigest.getInstance("SHA-256");
}
catch (NoSuchAlgorithmException e){
return null;
}
String txt = blockModel.str();
final byte[] bytes = messageDigest.digest(txt.getBytes());
final StringBuilder builder = new StringBuilder();
for (final byte b: bytes){
String hex = Integer.toHexString(0xff & b);
if (hex.length()==1){
builder.append('0');
}
builder.append(hex);
}
return builder.toString();
}
return null;
}
private String str() {
return index + timestamp + previousHash + data + nonce;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
public int getNonce() {
return nonce;
}
public void setNonce(int nonce) {
this.nonce = nonce;
}
public long getTimestamp() {
return timestamp;
}
public void setTimestamp(long timestamp) {
this.timestamp = timestamp;
}
public String getHash() {
return hash;
}
public void setHash(String hash) {
this.hash = hash;
}
public String getPreviousHash() {
return previousHash;
}
public void setPreviousHash(String previousHash) {
this.previousHash = previousHash;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
public void mineBlock(int difficulty){
nonce = 0;
while(!getHash().substring(0,difficulty).equals(addZeros(difficulty))){
nonce++;
hash = BlockModel.calculateHash_detail(this);
}
}
private String addZeros(int difficulty) {
StringBuilder builder = new StringBuilder();
for (int i = 0 ; i<difficulty; i++) {
builder.append('0');
}
return builder.toString();
}
}
CipherUtils
package com.example.blockchain.utils;
import android.util.Base64;
import androidx.annotation.NonNull;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
public class CipherUtils {
private static final String PASSWORD = "Saf fur yoU";
private static final String ALGORITHM = "DES";
public static String encryptIt(#NonNull String value){
try{
DESKeySpec keySpec = new DESKeySpec(PASSWORD.getBytes(StandardCharsets.UTF_8));
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
SecretKey key = keyFactory.generateSecret(keySpec);
byte [] clearText = value.getBytes(StandardCharsets.UTF_8);
Cipher cipher = Cipher.getInstance("ALGORITHM");
cipher.init(Cipher.ENCRYPT_MODE,key);
return Base64.encodeToString(cipher.doFinal(clearText),Base64.DEFAULT);
}
catch (InvalidKeyException | InvalidKeySpecException | NoSuchAlgorithmException | BadPaddingException | NoSuchPaddingException | IllegalBlockSizeException e){
e.printStackTrace();
}
return value;
}
public static String decryptIt(#NonNull String value){
try{
DESKeySpec keySpec = new DESKeySpec(PASSWORD.getBytes(StandardCharsets.UTF_8));
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
SecretKey key = keyFactory.generateSecret(keySpec);
byte [] encryptedPwdBytes = Base64.decode(value,Base64.DEFAULT);
Cipher cipher = Cipher.getInstance("ALGORITHM");
cipher.init(Cipher.DECRYPT_MODE,key);
byte [] decryptedValueBytes = (cipher.doFinal(encryptedPwdBytes));
return new String(decryptedValueBytes);
}
catch (InvalidKeyException | InvalidKeySpecException | NoSuchAlgorithmException | BadPaddingException | NoSuchPaddingException | IllegalBlockSizeException e){
e.printStackTrace();
}
return value;
}
}
MainActivity
package com.example.blockchain;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.os.PowerManager;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
import com.example.blockchain.fragments.PowFragment;
import com.example.blockchain.databinding.ActivityMainBinding;
import com.example.blockchain.databinding.ContentMainBinding;
import com.example.blockchain.managers.BlockChainManager;
import com.example.blockchain.managers.SharedPreferencesManager;
import com.example.blockchain.utils.CipherUtils;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private ContentMainBinding viewBindingContent;
private ProgressDialog progressDialog;
private SharedPreferencesManager prefs;
private BlockChainManager blockChain;
private boolean isEncryptionActivated, isDarkActivated;
private static final String TAG_POW_DIALOG = "proof_of_work_dialog";
#Override
protected void onCreate(Bundle savedInstanceState) {
prefs = new SharedPreferencesManager(this);
isDarkActivated = prefs.isDarkTheme();
PowerManager powerManager = (PowerManager)getSystemService(POWER_SERVICE);
boolean isPowerSaveMode = false;
if (powerManager!=null){
isPowerSaveMode = powerManager.isPowerSaveMode();
}
if(isPowerSaveMode){
isPowerSaveMode = powerManager.isPowerSaveMode();
}else{
if (isDarkActivated){
AppCompatDelegate.setDefaultNightMode(
AppCompatDelegate.MODE_NIGHT_YES
);
}else{
AppCompatDelegate.setDefaultNightMode(
AppCompatDelegate.MODE_NIGHT_NO
);
}
}
super.onCreate(savedInstanceState);
final ActivityMainBinding viewBinding = ActivityMainBinding.inflate(getLayoutInflater());
viewBindingContent = ContentMainBinding.bind(viewBinding.contentMain.getRoot());
setContentView(R.layout.activity_main);
isEncryptionActivated = prefs.getEncryptionStatus();
viewBindingContent.recyclerContent.setHasFixedSize(true);
viewBindingContent.recyclerContent.setLayoutManager(new LinearLayoutManager(this, RecyclerView.VERTICAL,false));
showProgressDialog(getResources().getString(R.string.text_creating_block_chain));
new Thread(() -> runOnUiThread(() -> {
blockChain = new BlockChainManager(prefs.getPowValue(),this);
viewBindingContent.recyclerContent.setAdapter(blockChain.adapter);
cancelProgressDialog(progressDialog);
})).start();
viewBindingContent.btnSendData.setOnClickListener(this);
}
#Override
protected void onResume() {
super.onResume();
}
private void startBlockChain() {
showProgressDialog(getResources().getString(R.string.text_mining_blocks));
runOnUiThread(() -> {
if (blockChain != null && viewBindingContent.editMessage.getText() != null && viewBindingContent.recyclerContent.getAdapter() != null) {
String message = viewBindingContent.editMessage.getText().toString();
if (!message.isEmpty()) {
if (!isEncryptionActivated) {
blockChain.addBlock(blockChain.newBlock(message));
} else {
try {
blockChain.addBlock(blockChain.newBlock(CipherUtils.encryptIt(message).trim()));
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(this, "Something fishy happened", Toast.LENGTH_SHORT).show();
}
}
viewBindingContent.recyclerContent.scrollToPosition(blockChain.adapter.getItemCount() - 1);
if (blockChain.isBlockChainValid()) {
viewBindingContent.recyclerContent.getAdapter().notifyDataSetChanged();
viewBindingContent.editMessage.setText("");
} else {
Toast.makeText(this, "BlockChain Corrupted", Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(this, "Error empty data", Toast.LENGTH_SHORT).show();
}
cancelProgressDialog(progressDialog);
} else {
Toast.makeText(this, "Something wrong happened", Toast.LENGTH_SHORT).show();
}
});
}
#Override
public void onClick(View view) {
if (view.getId()==R.id.btn_send_data)
startBlockChain();
}
private void showProgressDialog(#NonNull String loadingMessage){
progressDialog = new ProgressDialog(MainActivity.this);
progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progressDialog.setMessage(loadingMessage);
progressDialog.setCancelable(false);
progressDialog.setMax(100);
progressDialog.show();
}
private void cancelProgressDialog(#NonNull ProgressDialog progressDialog){
if(progressDialog!=null){
progressDialog.cancel();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu1,menu);
return true;
}
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
MenuItem checkEncrypt = menu.findItem(R.id.action_encrypt);
checkEncrypt.setChecked(isEncryptionActivated);
MenuItem checkTheme = menu.findItem(R.id.action_dark);
checkTheme.setChecked(isDarkActivated);
return true;
}
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()){
case R.id.action_pow:
PowFragment powFragment = PowFragment.newInstance();
powFragment.show(this.getSupportFragmentManager(),TAG_POW_DIALOG);
break;
case R.id.action_encrypt:
isEncryptionActivated = !item.isChecked();
item.setChecked(isEncryptionActivated);
if (item.isChecked()){
Toast.makeText(this, "Message Encryption ON", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(this, "Message Encryption OFF", Toast.LENGTH_SHORT).show();
}
prefs.setEncryptionStatus(isEncryptionActivated);
return true;
case R.id.action_dark:
isDarkActivated =!item.isChecked();
item.setChecked(isDarkActivated);
prefs.setDarkTheme(isDarkActivated);
Intent intent = this.getPackageManager().getLaunchIntentForPackage(this.getPackageName());
startActivity(intent);
finish();
return true;
case R.id.action_exit:
finish();
break;
default:
return super.onOptionsItemSelected(item);
}
return super.onOptionsItemSelected(item);
}
}
PoWFragment
package com.example.blockchain.fragments;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import com.example.blockchain.R;
import com.example.blockchain.databinding.FragmentPowBinding;
import com.example.blockchain.managers.SharedPreferencesManager;
/**
* A simple {#link Fragment} subclass.
* Use the {#link PowFragment#newInstance} factory method to
* create an instance of this fragment.
*/
public class PowFragment extends DialogFragment implements View.OnClickListener {
private FragmentPowBinding viewBinding;
private Context mcontext;
private SharedPreferencesManager prefs;
public PowFragment() {
// Required empty public constructor
}
public static PowFragment newInstance() {
return new PowFragment();
}
#Override
public void onAttach(#NonNull Context context) {
super.onAttach(context);
mcontext = context.getApplicationContext();
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
viewBinding = FragmentPowBinding.inflate(getLayoutInflater(), container, false);
return viewBinding.getRoot();
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
prefs = new SharedPreferencesManager(mcontext);
viewBinding.edtSetPow.setText(String.valueOf(prefs.getPowValue()));
viewBinding.btnClose.setOnClickListener(this);
viewBinding.btnContinue.setOnClickListener(this);
}
#NonNull
#Override
public Dialog onCreateDialog(#Nullable Bundle savedInstanceState) {
Dialog dialog = super.onCreateDialog(savedInstanceState);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
if (dialog.getWindow() != null) {
dialog.getWindow().setLayout(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
}
return dialog;
}
#Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.btn_close:
dismiss();
break;
case R.id.btn_continue:
if (viewBinding.edtSetPow.getText() != null) {
String pow = viewBinding.edtSetPow.getText().toString();
prefs.setPowValue(Integer.parseInt(pow));
if (getActivity() != null) {
Intent intent = mcontext.getPackageManager().getLaunchIntentForPackage(mcontext.getPackageName());
startActivity(intent);
getActivity().finish();
} else {
dismiss();
}
break;
}
}
}
#Override
public void onDetach() {
super.onDetach();
viewBinding = null;
mcontext = null;
}
}
SharedPreferencesManager
package com.example.blockchain.managers;
import android.content.Context;
import android.content.SharedPreferences;
public class SharedPreferencesManager {
private final SharedPreferences sharedPreferences;
private final SharedPreferences.Editor editor;
private static final String PREFERENCES_DATA = "com.example.blockchain";
private static final String ENCRYPTION_STATUS = "encryption_status";
private static final String DARK_THEME = "dark_theme";
private static final String PROOF_OF_WORK = "proof_of_work";
public static final int DEFAULT_PROOF_OF_WORK = 2;
public SharedPreferencesManager(Context context) {
sharedPreferences = context.getSharedPreferences(PREFERENCES_DATA,Context.MODE_PRIVATE);
editor = sharedPreferences.edit();
editor.apply();
}
public void setPowValue(int powValue){
editor.putInt(PROOF_OF_WORK,powValue);
editor.commit();
}
public int getPowValue(){
return sharedPreferences.getInt(PROOF_OF_WORK,DEFAULT_PROOF_OF_WORK);
}
public void setEncryptionStatus(boolean isActivated){
editor.putBoolean(ENCRYPTION_STATUS,isActivated);
editor.commit();
}
public boolean getEncryptionStatus(){
return sharedPreferences.getBoolean(ENCRYPTION_STATUS,false);
}
public void setDarkTheme(boolean isActivated){
editor.putBoolean(DARK_THEME,isActivated);
editor.commit();
}
public boolean isDarkTheme(){
return sharedPreferences.getBoolean(DARK_THEME,false);
}
}
If for any reason the Manifest will help:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.blockchain">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme"
android:fullBackupContent="#xml/backup_descriptor">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
These errors seem to be centered around a specific class meant to integrate the BlockChain into the App FrameWork, but this has used its declarations:
Block Adapter
package com.example.blockchain.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
import com.example.blockchain.R;
import com.example.blockchain.models.BlockModel;
import com.example.blockchain.viewholder.RecyclerViewHolder;
import java.util.Date;
import java.util.List;
public class BlockAdapter extends RecyclerView.Adapter<RecyclerViewHolder> {
private final List<BlockModel> blocks;
private final Context mcontext;
private int lastPosition = -1;
public BlockAdapter(#Nullable List<BlockModel> blocks, #NonNull Context mcontext) {
this.blocks = blocks;
this.mcontext = mcontext;
}
#NonNull
#Override
public RecyclerViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
final View view = LayoutInflater.from(parent.getContext()).inflate(viewType,parent,false);
return new RecyclerViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull RecyclerViewHolder holder, int position) {
holder.txtIndex.setText(String.format(
mcontext.getString(R.string.title_block_number),blocks.get(position).getIndex()
));
holder.txtPreviousHash.setText(blocks.get(position).getPreviousHash()!=null ? blocks.get(position).getPreviousHash(): "Null");
holder.txtTimestamp.setText(String.valueOf(new Date(blocks.get(position).getTimestamp())));
holder.txtData.setText(blocks.get(position).getData());
holder.txtHash.setText(blocks.get(position).getHash());
setAnimation(holder.itemView,position);
}
private void setAnimation(View itemView, int position) {
if (position>lastPosition){
Animation animation = AnimationUtils.loadAnimation(mcontext,android.R.anim.fade_in);
itemView.startAnimation(animation);
lastPosition = position;
}
}
#Override
public int getItemViewType(int position) {
return R.layout.item_block_data;
}
#Override
public int getItemCount() {
return blocks == null ? 0:blocks.size();
}
}
Let me know if anything else might help resolve these issues.
Here is the link to the video however the advertised "FREE" learning actually requires $30 for the source code once you realize what you have received does not work: https://www.youtube.com/watch?v=c5E_yBMt7Io&t=1s
Since I'm not an idiot I did not send someone money simply because they shared a few chopped up videos and asked for it in an email, but the lengthy 7-part series to deceive people into obligatorily purchasing after the "FREE" learning is illegal misrepresentation as well as unethically conning people interested in the fledgling blockchain technologies.
Any help is greatly appreciated!
Related
Hi I'm following this video tutorial https://www.youtube.com/watch?v=wQN2eCO-M_Q&t=7717s (the part I suppose create this issue can be found at time 2:01:17)and I managed to make this code work without implementing the notifications, but it only works on the simulator.
When I try to debug it with my phone it gives me the following error
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.chat, PID: 7894
java.lang.RuntimeException: Could not deserialize object. Failed to convert value of type java.lang.Long to Timestamp (found in field 'timestamp')
On others real devices it works properly but on my real me 8 pro it does not
here is some code from my android studio:
ChatModel.java
package com.example.chat.model;
import com.google.firebase.Timestamp;
import java.sql.Time;
import java.util.Date;
public class ChatModel {
String message;
String user_name;
String messageID;
String user_image_url;
String chat_image;
Timestamp timestamp;
public ChatModel() {
}
public ChatModel(String message, String user_name, String messageID, String user_image_url, String chat_image, Timestamp timestamp) {
this.message = message;
this.user_name = user_name;
this.messageID = messageID;
this.user_image_url = user_image_url;
this.chat_image = chat_image;
this.timestamp = timestamp;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getUser_name() {
return user_name;
}
public void setUser_name(String user_name) {
this.user_name = user_name;
}
public String getMessageID() {
return messageID;
}
public void setMessageID(String messageID) {
this.messageID = messageID;
}
public String getUser_image_url() {
return user_image_url;
}
public void setUser_image_url(String user_image_url) {
this.user_image_url = user_image_url;
}
public String getChat_image() {
return chat_image;
}
public void setChat_image(String chat_image) {
this.chat_image = chat_image;
}
public Timestamp getTimestamp() {
return timestamp;
}
public void setTimestamp(Timestamp timestamp) {
this.timestamp = timestamp;
}
}
i have tried to change Timestamp with: long, Long, Date and Number.
But i wouldn't work anyways
MainActivity.java
package com.example.chat;
import static com.example.chat.cords.FirebaseCords.MAIN_CHAT_DATABASE;
import static com.example.chat.cords.FirebaseCords.mAuth;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import androidx.appcompat.widget.Toolbar;
import androidx.core.app.ActivityCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.example.chat.adapter.ChatAdapter;
import com.example.chat.cords.FirebaseCords;
import com.example.chat.model.ChatModel;
import com.example.chat.model.SaveState;
import com.firebase.ui.firestore.FirestoreRecyclerAdapter;
import com.firebase.ui.firestore.FirestoreRecyclerOptions;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.firestore.FieldValue;
import com.google.firebase.firestore.Query;
import com.theartofdev.edmodo.cropper.CropImage;
import com.theartofdev.edmodo.cropper.CropImageView;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Queue;
public class MainActivity extends AppCompatActivity {
#Override
public void onStart() {
super.onStart();
// Check if user is signed in (non-null) and update UI accordingly.
FirebaseUser currentUser = mAuth.getCurrentUser();
if (currentUser == null) {
startActivity(new Intent(this, LoginActivity.class));
finish();
}
chatAdapter.startListening();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.chat_room, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.logout:
mAuth.signOut();
startActivity((new Intent(this, LoginActivity.class)));
break;
}
return super.onOptionsItemSelected(item);
}
EditText chat_box;
RecyclerView chat_list;
ChatAdapter chatAdapter;
Uri imageUri;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
chat_box = findViewById(R.id.chat_box);
chat_list = findViewById(R.id.chat_list);
initChatList();
}
private void initChatList() {
chat_list.setHasFixedSize(true);
chat_list.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, true));
Query query = MAIN_CHAT_DATABASE.orderBy("timestamp", Query.Direction.DESCENDING);
FirestoreRecyclerOptions<ChatModel> option = new FirestoreRecyclerOptions.Builder<ChatModel>()
.setQuery(query, ChatModel.class)
.build();
chatAdapter = new ChatAdapter(option);
chat_list.setAdapter(chatAdapter);
chatAdapter.startListening();
}
public void addMessage(View view) {
String message = chat_box.getText().toString();
FirebaseUser user = mAuth.getCurrentUser();
if (!TextUtils.isEmpty(message)) {
/*Generate messageID using the current date. */
Date today = new Date();
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String messageID = format.format(today);
/*Getting user image from Google account*/
String user_image_url = "";
Uri photoUrl = user.getPhotoUrl();
String originalUrl = "s96-c/photo.jpg";
String resizeImageUrl = "s400-c/photo.jpg";
if (photoUrl!=null) {
String photoPath = photoUrl.toString();
user_image_url = photoPath.replace(originalUrl,resizeImageUrl);
}
HashMap<String, Object> messageObj = new HashMap<>();
messageObj.put("message", message);
messageObj.put("user_name", user.getDisplayName());
messageObj.put("timestamp",FieldValue.serverTimestamp());
messageObj.put("messageID", messageID);
messageObj.put("chat_image","");
messageObj.put("user_image_url", user_image_url);
MAIN_CHAT_DATABASE.document(messageID).set(messageObj).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Toast.makeText(MainActivity.this, "Message send", Toast.LENGTH_SHORT).show();
chat_box.setText("");
} else {
Toast.makeText(MainActivity.this, task.getException().getMessage(), Toast.LENGTH_SHORT).show();
}
}
});
}
}
public void OpenExplorer(View view) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) ==
PackageManager.PERMISSION_GRANTED) {
ChoseImage();
} else {
if(ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_EXTERNAL_STORAGE)) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 20);
} else {
Toast.makeText(this, "Storage Permission Needed", Toast.LENGTH_SHORT).show();
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 20);
}
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions,#NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 20) {
if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "Permission Granted", Toast.LENGTH_SHORT).show();
ChoseImage();
} else {
Toast.makeText(this, "Permission Denied", Toast.LENGTH_SHORT).show();
}
}
}
private void ChoseImage(){
CropImage.activity()
.setGuidelines(CropImageView.Guidelines.ON)
.start(MainActivity.this);
}
#Override
protected void onActivityResult(int requestCode, int resultCode,#Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE) {
CropImage.ActivityResult result = CropImage.getActivityResult(data);
Log.d("TAG", "onActivityResult:"+result);
if (resultCode == RESULT_OK) {
imageUri = result.getUri();
Log.d("TAG", "onActivityResult:"+imageUri);
startActivity(new Intent(MainActivity.this, ImageUploadPreview.class)
.putExtra("image_uri", imageUri.toString()));
} else if (requestCode == CropImage.CROP_IMAGE_ACTIVITY_RESULT_ERROR_CODE) {
Toast.makeText(this, result.getError().getMessage(),Toast.LENGTH_SHORT).show();
}
}
}
public void Finish(View view) {
long currentTime = new Date().getTime();
new SaveState(this).setClickTime(currentTime);
finish();
}
}
ChatAdapter.java
package com.example.chat.adapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.example.chat.R;
import com.firebase.ui.firestore.FirestoreRecyclerAdapter;
import com.firebase.ui.firestore.FirestoreRecyclerOptions;
import com.example.chat.model.ChatModel;
import org.w3c.dom.Text;
import de.hdodenhof.circleimageview.CircleImageView;
public class ChatAdapter extends FirestoreRecyclerAdapter<ChatModel, ChatAdapter.ChatViewHolder> {
public ChatAdapter (#NonNull FirestoreRecyclerOptions <ChatModel> options) {
super(options);
}
#Override
protected void onBindViewHolder (#NonNull ChatViewHolder chatViewHolder, int i, #NonNull ChatModel chatModel) {
chatViewHolder.message.setText(chatModel.getMessage());
Glide.with(chatViewHolder.user_image.getContext().getApplicationContext())
.load(chatModel.getUser_image_url())
.into(chatViewHolder.user_image);
if(!chatModel.getChat_image().equals("")){
Glide.with(chatViewHolder.chat_image.getContext().getApplicationContext())
.load(chatModel.getChat_image())
.into(chatViewHolder.chat_image);
chatViewHolder.chat_image.setVisibility(View.VISIBLE);
}else{
chatViewHolder.chat_image.setVisibility(View.GONE);
}
}
#NonNull
#Override
public ChatViewHolder onCreateViewHolder (#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.chat_item,parent,false);
return new ChatViewHolder(v);
}
class ChatViewHolder extends RecyclerView.ViewHolder {
TextView message;
CircleImageView user_image;
ImageView chat_image;
public ChatViewHolder(#NonNull View itemView) {
super(itemView);
message = itemView.findViewById(R.id.message);
user_image = itemView.findViewById(R.id.user_image);
chat_image = itemView.findViewById(R.id.chat_image);
}
}
}
Screenshoot of thedatabase structure:
here
I have no idea how to solve that error can someone help me?
If you need any more information comment i will add it as soon as i see the message thanks in advance.
I am trying to load the result of an API call into a recyclerView. I created a data model to hold the array of results (strings) to be used in populating the recyclerView Adapter. But once the JSON file is parsed, the application crashes on the call to "setValues" of the data model but the result displays accurately on the logcat.
my code is below:
MainActivity
package com.limitless.googlebooks;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.loader.app.LoaderManager;
import androidx.loader.content.Loader;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.net.NetworkInterface;
import java.util.ArrayList;
import static android.text.TextUtils.isEmpty;
public class MainActivity extends AppCompatActivity
implements LoaderManager.LoaderCallbacks<String> {
private EditText bookImput;
private RecyclerView recyclerView;
private ProgressBar progressBar;
private static Books books;
ArrayList<Books> booksArray;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bookImput = findViewById(R.id.bookInput);
progressBar = findViewById(R.id.progressBar);
recyclerView = findViewById(R.id.bookRecyclerView);
booksArray = new ArrayList<>();
BooksAdapter adapter = new BooksAdapter(booksArray);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
if(LoaderManager.getInstance(this).getLoader(0) != null){
LoaderManager.getInstance(this).initLoader(0,null, this);
}
}
public void searchBooks(View view) {
String queryText = bookImput.getText().toString();
InputMethodManager methodManager = (InputMethodManager)
getSystemService(Context.INPUT_METHOD_SERVICE);
if(methodManager != null){
methodManager.hideSoftInputFromWindow(view.getWindowToken(),
methodManager.HIDE_NOT_ALWAYS);
}
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = null;
if(connectivityManager != null){
networkInfo = connectivityManager.getActiveNetworkInfo();
}
if(networkInfo != null && !isEmpty(queryText) && networkInfo.isConnected()){
Bundle queryBundle = new Bundle();
queryBundle.putString("queryString", queryText);
LoaderManager.getInstance(this).restartLoader(0, queryBundle, this);
progressBar.setVisibility(View.VISIBLE);
}else {
if(isEmpty(queryText)){
Toast.makeText(this, R.string.emptyquery, Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(this, R.string.no_internet, Toast.LENGTH_SHORT).show();
}
}
}
#NonNull
#Override
public Loader<String> onCreateLoader(int id, #Nullable Bundle args) {
String queryString = "";
if(args != null){
queryString = args.getString("queryString");
}
return new BookLoader(this, queryString);
}
#Override
public void onLoadFinished(#NonNull Loader<String> loader, String data) {
try{
JSONObject jsonObject = new JSONObject(data);
JSONArray itemsArray = jsonObject.getJSONArray("items");
int i = 0;
String title = null;
String authors = null;
String publisher = null;
String date = null;
while(i < itemsArray.length() && title == null && authors == null && date == null){
JSONObject book = itemsArray.getJSONObject(i);
JSONObject volumeInfo = book.getJSONObject("volumeInfo");
try{
title = volumeInfo.getString("title");
authors = volumeInfo.getString("authors");
publisher = volumeInfo.getString("publisher");
date = volumeInfo.getString("publishedDate");
} catch (JSONException e) {
e.printStackTrace();
}
i++;
}
if(title != null && authors != null && date != null){
books.setBookName(title);
books.setAuthorsName(authors);
books.setPublisher(publisher);
books.setPublishedDate(date);
booksArray.add(books);
}else {
books.setBookName(String.valueOf(R.string.no_results));
books.setAuthorsName("");
books.setPublisher("");
books.setPublishedDate("");;
}
}catch (JSONException e){
books.setBookName(String.valueOf(R.string.error));
books.setAuthorsName("");
books.setPublisher("");
books.setPublishedDate("");
e.printStackTrace();
}
}
#Override
public void onLoaderReset(#NonNull Loader<String> loader) {
}
}
Data Model
package com.limitless.googlebooks;
public class Books {
private String bookName;
private String authorsName;
private String publisher;
private String publishedDate;
public Books(String bookName, String authorsName, String publisher, String publishedDate) {
this.bookName = bookName;
this.authorsName = authorsName;
this.publisher = publisher;
this.publishedDate = publishedDate;
}
public Books(){}
public String getBookName() {
return bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
public String getAuthorsName() {
return authorsName;
}
public void setAuthorsName(String authorsName) {
this.authorsName = authorsName;
}
public String getPublisher() {
return publisher;
}
public void setPublisher(String publisher) {
this.publisher = publisher;
}
public String getPublishedDate() {
return publishedDate;
}
public void setPublishedDate(String publishedDate) {
this.publishedDate = publishedDate;
}
}
Adapter Class
package com.limitless.googlebooks;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
public class BooksAdapter extends RecyclerView.Adapter<BooksAdapter.BooksHolder>{
ArrayList<Books> booksArrayList;
public BooksAdapter(ArrayList<Books> booksArray){
this.booksArrayList = booksArray;
}
#NonNull
#Override
public BooksHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
Context context = parent.getContext();
View itemView = LayoutInflater.from(context).inflate(R.layout.booklist, parent, false);
return new BooksHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull BooksHolder holder, int position) {
Books books = booksArrayList.get(position);
holder.bind(books);
}
#Override
public int getItemCount() {
return booksArrayList.size();
}
public class BooksHolder extends RecyclerView.ViewHolder {
private TextView bookName;
private TextView authorsName;
private TextView publisher;
private TextView publishedDate;
public BooksHolder(#NonNull View itemView) {
super(itemView);
bookName = itemView.findViewById(R.id.bookTitle);
authorsName = itemView.findViewById(R.id.authorsName);
publisher = itemView.findViewById(R.id.publisher);
publishedDate = itemView.findViewById(R.id.publishedDate);
}
public void bind(Books books){
bookName.setText(books.getBookName());
authorsName.setText(books.getAuthorsName());
publisher.setText(books.getPublisher());
publishedDate.setText(books.getPublishedDate());
}
}
}
In your MainActivity:
These
public class MainActivity extends AppCompatActivity
implements LoaderManager.LoaderCallbacks<String> {
....
private static Books books;
ArrayList<Books> booksArray;
Becomes:
public class MainActivity extends AppCompatActivity
implements LoaderManager.LoaderCallbacks<String> {
....
private Books books;
private ArrayList<Books> booksArray;
private BooksAdapter adapter;
In onCreate():
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
........
adapter = new BooksAdapter(booksArray);
........
........
}
Now in onLoadFinished():
This:
if(title != null && authors != null && date != null){
books.setBookName(title);
books.setAuthorsName(authors);
books.setPublisher(publisher);
books.setPublishedDate(date);
booksArray.add(books);
}else {
books.setBookName(String.valueOf(R.string.no_results));
books.setAuthorsName("");
books.setPublisher("");
books.setPublishedDate("");;
}
}catch (JSONException e){
books.setBookName(String.valueOf(R.string.error));
books.setAuthorsName("");
books.setPublisher("");
books.setPublishedDate("");
e.printStackTrace();
}
Becomes:
if(title != null && authors != null && date != null){
books = new Books(title,authors,publisher,date);
booksArray.add(books);
adapter.notifyDataSetChanged();
}else {
books = new Books(String.valueOf(R.string.no_results),"","","");
//if you want to add them to array add them, if not then don't
booksArray.add(books);
adapter.notifyDataSetChanged();
}
}catch (JSONException e){
books = new Books(String.valueOf(R.string.error),"","","");
//if you want to add them to array add them, if not then don't
booksArray.add(books);
adapter.notifyDataSetChanged();
e.printStackTrace();
}
Whenever I want to start my "NotenActivity", it Shows me this error:
Caused by: java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
at androidx.room.RoomDatabase.assertNotMainThread(RoomDatabase.java:209)
at androidx.room.RoomDatabase.query(RoomDatabase.java:237)
at com.example.mykolproject.persistance.dao.NoteDao_Impl.getnAll(NoteDao_Impl.java:121)
at com.example.mykolproject.NoteRepository.<init>(NoteRepository.java:23)
at com.example.mykolproject.NoteViewModel.<init>(NoteViewModel.java:20)
at java.lang.reflect.Constructor.newInstance0(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:200)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:135)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:103)
at com.example.mykolproject.NotenActivity.onCreate(NotenActivity.java:130)
at android.app.Activity.performCreate(Activity.java:7458)
at android.app.Activity.performCreate(Activity.java:7448)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1286)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3409)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3614)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:86)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2199)
at android.os.Handler.dispatchMessage(Handler.java:112)
at android.os.Looper.loop(Looper.java:216)
at android.app.ActivityThread.main(ActivityThread.java:7625)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987)
Here are my affected Activitys:
package com.example.mykolproject.persistance.dao;
import android.database.Cursor;
import androidx.room.EntityDeletionOrUpdateAdapter;
import androidx.room.EntityInsertionAdapter;
import androidx.room.RoomDatabase;
import androidx.room.RoomSQLiteQuery;
import androidx.sqlite.db.SupportSQLiteStatement;
import com.example.mykolproject.persistance.entities.Note;
import java.lang.Override;
import java.lang.String;
import java.lang.SuppressWarnings;
import java.util.ArrayList;
import java.util.List;
#SuppressWarnings("unchecked")
public final class NoteDao_Impl implements NoteDao {
private final RoomDatabase __db;
private final EntityInsertionAdapter __insertionAdapterOfNote;
private final EntityDeletionOrUpdateAdapter __deletionAdapterOfNote;
private final EntityDeletionOrUpdateAdapter __updateAdapterOfNote;
public NoteDao_Impl(RoomDatabase __db) {
this.__db = __db;
this.__insertionAdapterOfNote = new EntityInsertionAdapter<Note>(__db) {
#Override
public String createQuery() {
return "INSERT OR ABORT INTO `note_table`(`id`,`titlefach`,`noten`) VALUES (nullif(?, 0),?,?)";
}
#Override
public void bind(SupportSQLiteStatement stmt, Note value) {
stmt.bindLong(1, value.getId());
if (value.titlefach == null) {
stmt.bindNull(2);
} else {
stmt.bindString(2, value.titlefach);
}
if (value.getNoten() == null) {
stmt.bindNull(3);
} else {
stmt.bindString(3, value.getNoten());
}
}
};
this.__deletionAdapterOfNote = new EntityDeletionOrUpdateAdapter<Note>(__db) {
#Override
public String createQuery() {
return "DELETE FROM `note_table` WHERE `id` = ?";
}
#Override
public void bind(SupportSQLiteStatement stmt, Note value) {
stmt.bindLong(1, value.getId());
}
};
this.__updateAdapterOfNote = new EntityDeletionOrUpdateAdapter<Note>(__db) {
#Override
public String createQuery() {
return "UPDATE OR ABORT `note_table` SET `id` = ?,`titlefach` = ?,`noten` = ? WHERE `id` = ?";
}
#Override
public void bind(SupportSQLiteStatement stmt, Note value) {
stmt.bindLong(1, value.getId());
if (value.titlefach == null) {
stmt.bindNull(2);
} else {
stmt.bindString(2, value.titlefach);
}
if (value.getNoten() == null) {
stmt.bindNull(3);
} else {
stmt.bindString(3, value.getNoten());
}
stmt.bindLong(4, value.getId());
}
};
}
#Override
public void insert(Note note) {
__db.beginTransaction();
try {
__insertionAdapterOfNote.insert(note);
__db.setTransactionSuccessful();
} finally {
__db.endTransaction();
}
}
#Override
public void delete(Note note) {
__db.beginTransaction();
try {
__deletionAdapterOfNote.handle(note);
__db.setTransactionSuccessful();
} finally {
__db.endTransaction();
}
}
#Override
public void update(Note note) {
__db.beginTransaction();
try {
__updateAdapterOfNote.handle(note);
__db.setTransactionSuccessful();
} finally {
__db.endTransaction();
}
}
#Override
public List<Note> getnAll() {
final String _sql = "SELECT * FROM note_table";
final RoomSQLiteQuery _statement = RoomSQLiteQuery.acquire(_sql, 0);
final Cursor _cursor = __db.query(_statement);
try {
final int _cursorIndexOfId = _cursor.getColumnIndexOrThrow("id");
final int _cursorIndexOfTitlefach = _cursor.getColumnIndexOrThrow("titlefach");
final int _cursorIndexOfNoten = _cursor.getColumnIndexOrThrow("noten");
final List<Note> _result = new ArrayList<Note>(_cursor.getCount());
while(_cursor.moveToNext()) {
final Note _item;
final String _tmpTitlefach;
_tmpTitlefach = _cursor.getString(_cursorIndexOfTitlefach);
final String _tmpNoten;
_tmpNoten = _cursor.getString(_cursorIndexOfNoten);
_item = new Note(_tmpTitlefach,_tmpNoten);
final int _tmpId;
_tmpId = _cursor.getInt(_cursorIndexOfId);
_item.setId(_tmpId);
_result.add(_item);
}
return _result;
} finally {
_cursor.close();
_statement.release();
}
}
}
package com.example.mykolproject;
import android.app.Application;
import android.os.AsyncTask;
import androidx.lifecycle.LiveData;
import com.example.mykolproject.persistance.dao.NoteDao;
import com.example.mykolproject.persistance.entities.AppDatabase;
import com.example.mykolproject.persistance.entities.Note;
import java.util.List;
public class NoteRepository {
private NoteDao notenDao;
private LiveData<List<Note>> allNoten;
public NoteRepository(Application application) {
AppDatabase database = AppDatabase.getInstance(application);
notenDao = database.NoteDao();
allNoten = (LiveData<List<Note>>) notenDao.getnAll();
}
public void insert(LiveData<List<Note>> note) {
new InsertNoteAsyncTask(notenDao).execute((Runnable) note);
}
public void update(LiveData<List<Note>> note) {
new UpdateNoteAsyncTask(notenDao).execute((Runnable) note);
}
public void delete(LiveData<List<Note>> note) {
new DeleteNoteAsyncTask(notenDao).execute((Runnable) note);
}
public LiveData<List<Note>> getAllNoten() {
return getAllNoten();
}
private static class InsertNoteAsyncTask extends AsyncTask<Note, Void, Void> {
private NoteDao noteDao;
private InsertNoteAsyncTask(NoteDao noteDao) {
this.noteDao = noteDao;
}
#Override
protected Void doInBackground(Note... noten) {
noteDao.insert(noten[0]);
return null;
}
}
private static class UpdateNoteAsyncTask extends AsyncTask<Note, Void, Void> {
private NoteDao noteDao;
private UpdateNoteAsyncTask(NoteDao noteDao) {
this.noteDao = noteDao;
}
#Override
protected Void doInBackground(Note... noten) {
noteDao.update(noten[0]);
return null;
}
}
private static class DeleteNoteAsyncTask extends AsyncTask<Note, Void, Void> {
private NoteDao noteDao;
private DeleteNoteAsyncTask(NoteDao noteDao) {
this.noteDao = noteDao;
}
#Override
protected Void doInBackground(Note... noten) {
noteDao.delete(noten[0]);
return null;
}
}
}
package com.example.mykolproject;
import android.app.Application;
import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import com.example.mykolproject.persistance.entities.Note;
import java.util.List;
public class NoteViewModel extends AndroidViewModel {
private NoteRepository repository;
private LiveData<List<Note>> allNoten;
public NoteViewModel(#NonNull Application application) {
super(application);
repository = new NoteRepository(application);
allNoten = repository.getAllNoten();
}
public void insert(Note note) {
repository.insert(allNoten);
}
public void update(Note note) {
repository.update(allNoten);
}
public void delete(Note note) {
repository.delete(allNoten);
}
public LiveData<List<Note>> getAllNotes() {
return allNoten;
}
}
package com.example.mykolproject;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.example.mykolproject.persistance.entities.Note;
import java.util.List;
public class NotenActivity extends AppCompatActivity {
public String TAG = "NotenActivity";
public static final String NOTEN_MESSAGE = "com.example.MyOLProject.NOTEN";
private RecyclerView recyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager layoutManager;
public static final int ADD_NOTE_REQUEST = 1;
public static final int EDIT_NOTE_REQUEST = 2;
private NoteViewModel noteViewModel;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_noten);
// final EditText editFach = findViewById(R.id.edit_fach);
recyclerView = (RecyclerView) findViewById(R.id.notenList);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
Button btnAddNoten = findViewById(R.id.btn_addNote);
btnAddNoten.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.i(TAG, "onClick: AddNoten");
startAddNoten();
}
});
ImageButton btnFach = findViewById(R.id.ibFach);
btnFach.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
Log.i(TAG,"onClick: Fach");
startFach();
}
});
ImageButton btnHome = findViewById(R.id.ibHome);
btnHome.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
Log.i(TAG,"onClick: Home");
startHome();
}
});
ImageButton btnHausaufgaben = findViewById(R.id.ibHausaufgaben);
btnHausaufgaben.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
Log.i(TAG,"onClick: Hausaufgaben");
startHausaufgaben();
}
});
ImageButton btnKalender = findViewById(R.id.ibInfo);
btnKalender.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
Log.i(TAG,"onClick: Kalender");
startKalender();
}
});
Button buttonAddNote = findViewById(R.id.btn_addNote);
buttonAddNote.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(NotenActivity.this, AddEditNoteActivity.class);
startActivityForResult(intent, ADD_NOTE_REQUEST);
}
});
RecyclerView recyclerView = findViewById(R.id.notenList);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setHasFixedSize(true);
final NotenListAdapter adapter = new NotenListAdapter();
recyclerView.setAdapter(adapter);
noteViewModel = ViewModelProviders.of(this).get(NoteViewModel.class);
noteViewModel.getAllNotes().observe(this, new Observer<List<Note>>() {
#Override
public void onChanged(#Nullable List<Note> noten) {
adapter.setNotes(noten);
}
});
new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0,
ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
#Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false;
}
#Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
noteViewModel.delete(adapter.getNoteAt(viewHolder.getAdapterPosition()));
Toast.makeText(NotenActivity.this, "Note deleted", Toast.LENGTH_SHORT).show();
}
}).attachToRecyclerView(recyclerView);
adapter.setOnItemClickListener(new NotenListAdapter.OnItemClickListener() {
#Override
public void onItemClick(Note note) {
Intent intent = new Intent(NotenActivity.this, AddEditNoteActivity.class);
intent.putExtra(AddEditNoteActivity.EXTRA_ID, note.getId());
intent.putExtra(AddEditNoteActivity.EXTRA_TITLE, note.getTitleFach());
intent.putExtra(AddEditNoteActivity.EXTRA_DESCRIPTION, note.getNoten());
startActivityForResult(intent, EDIT_NOTE_REQUEST);
}
});
}
private void startAddNoten(){
Intent addNotenIntent = new Intent(this,AddNotenActivity.class);
startActivity(addNotenIntent);
}
private void startFach(){
Intent fachIntent = new Intent(this,FachActivity.class);
startActivity(fachIntent);
}
private void startHome(){
Intent homeIntent = new Intent(this,MainActivity.class);
startActivity(homeIntent);
}
private void startHausaufgaben(){
Intent hausaufgabenIntent = new Intent(this,HausaufgabenActivity.class);
startActivity(hausaufgabenIntent);
}
private void startKalender(){
Intent kalenderIntent = new Intent(this,InfoActivity.class);
startActivity(kalenderIntent);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == ADD_NOTE_REQUEST && resultCode == RESULT_OK) {
String title = data.getStringExtra(AddEditNoteActivity.EXTRA_TITLE);
String description = data.getStringExtra(AddEditNoteActivity.EXTRA_DESCRIPTION);
Note note = new Note(title, description);
noteViewModel.insert(note);
Toast.makeText(this, "Note saved", Toast.LENGTH_SHORT).show();
} else if (requestCode == EDIT_NOTE_REQUEST && resultCode == RESULT_OK) {
int id = data.getIntExtra(AddEditNoteActivity.EXTRA_ID, -1);
if (id == -1) {
Toast.makeText(this, "Note can't be updated", Toast.LENGTH_SHORT).show();
return;
}
String title = data.getStringExtra(AddEditNoteActivity.EXTRA_TITLE);
String description = data.getStringExtra(AddEditNoteActivity.EXTRA_DESCRIPTION);
Note note = new Note(title, description);
note.setId(id);
noteViewModel.update(note);
Toast.makeText(this, "Note updated", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Note not saved", Toast.LENGTH_SHORT).show();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.main_menu, menu);
return true;
}
/* #Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.delete_all_notes:
noteViewModel.deleteAllNotes();
Toast.makeText(this, "All notes deleted", Toast.LENGTH_SHORT).show();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}*/
}
If you Need any other activities just let me know. My "NotenActivity" is like my MainActivity.
Thank you very much !
Try using some RxJava, that can probably help you out.
But since you're using Room, LiveData, and ViewModel you can probably try using this AppExecutor class. This usually helps me out when I'm doing Database and Network operations.
Also be careful when running on the UI/Main Thread, for Database operations with lots of data its always best practice to do it on a separate thread.
import android.os.Looper;
import android.support.annotation.NonNull;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
public class AppExecutors {
private static final Object LOCK = new Object();
private static AppExecutors sInstance;
private final Executor diskIO;
private final Executor mainThread;
private final Executor networkIO;
private AppExecutors(Executor diskIO, Executor networkIO, Executor mainThread) {
this.diskIO = diskIO;
this.networkIO = networkIO;
this.mainThread = mainThread;
}
public static AppExecutors getInstance() {
if (sInstance == null) {
synchronized (LOCK) {
sInstance = new AppExecutors(Executors.newSingleThreadExecutor(),
Executors.newFixedThreadPool(3),
new MainThreadExecutor());
}
}
return sInstance;
}
public Executor diskIO() {
return diskIO;
}
public Executor mainThread() {
return mainThread;
}
public Executor networkIO() {
return networkIO;
}
private static class MainThreadExecutor implements Executor {
private Handler mainThreadHandler = new Handler(Looper.getMainLooper());
#Override
public void execute(#NonNull Runnable command) {
mainThreadHandler.post(command);
}
}
}
//Then you can do something like this.
```AppExecutors.getInstance().getDiskIO.execute(()->database.NoteDao().getnAll());```
Maybe you could look on widely accepted solution of this problem, it could bring you to solution of your problem too...
I am using glide for displaying album art but somehow I am not able to display it. I want to add listener to glide for locating errors but its not working. It shows error saying :
listener(com.bumptech.glide.request.RequestListener) in com.bumptech.glide.DrawableRequestBuilder cannot be applied to (anonymous com.bumptech.glide.request.RequestListener)
PlayListActivity.java :
package com.example.dell_1.myapp3;
import android.app.Activity;
import android.database.Cursor;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.design.widget.Snackbar;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.Toast;
import java.io.File;
import java.io.IOException;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.resource.drawable.GlideDrawable;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.target.Target;
public class PlayListActivity extends Activity {
private String[] mAudioPath;
private MediaPlayer mMediaPlayer;
private String[] mMusicList;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_play_list);
mMediaPlayer = new MediaPlayer();
ListView mListView = (ListView) findViewById(R.id.list);
mMusicList = getAudioList();
ArrayAdapter<String> mAdapter = new ArrayAdapter<>(this,
android.R.layout.simple_list_item_1, mMusicList);
mListView.setAdapter(mAdapter);
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View view, int arg2,
long arg3) {
try {
playSong(mAudioPath[arg2]);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
private String[] getAudioList() {
final Cursor mCursor = getContentResolver().query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
new String[]{MediaStore.Audio.Media.DISPLAY_NAME, MediaStore.Audio.Media.DATA}, null, null,
"LOWER(" + MediaStore.Audio.Media.TITLE + ") ASC");
int count = mCursor.getCount();
String[] songs = new String[count];
mAudioPath = new String[count];
int i = 0;
if (mCursor.moveToFirst()) {
do {
songs[i] = mCursor.getString(mCursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME));
mAudioPath[i] = mCursor.getString(mCursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA));
i++;
} while (mCursor.moveToNext());
}
mCursor.close();
return songs;
}
private void playSong(String path) throws IllegalArgumentException,
IllegalStateException, IOException {
setContentView(R.layout.activity_android_building_music_player);
Log.d("ringtone", "playSong :: " + path);
mMediaPlayer.reset();
mMediaPlayer.setDataSource(path);
//mMediaPlayer.setLooping(true);
mMediaPlayer.prepare();
mMediaPlayer.start();
asd();
}
public void asd(){
File music = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC);
// Tested with music from Windows 7's c:\Users\Public\Music\Sample Music
String mAudioPath = new File(music, "Maid with the Flaxen Hair.mp3").getAbsolutePath();
ImageView imageView = (ImageView) findViewById(R.id.coverart);
Glide
.with(this)
.load(new AudioCover(mAudioPath))
.placeholder(R.drawable.adele1)
.error(R.drawable.adele1)
.listener(new RequestListener<Uri, GlideDrawable>() {
#Override public boolean onException(Exception e, Uri model, Target<GlideDrawable> target, boolean isFirstResource) {
return false;
}
#Override public boolean onResourceReady(GlideDrawable resource, Uri model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
// easy
return false;
// impossible?
}
})
.into(imageView)
;
}
}
AudioCover.java :
package com.example.dell_1.myapp3;
import android.content.Context;
import android.media.MediaMetadataRetriever;
import com.bumptech.glide.*;
import com.bumptech.glide.load.data.DataFetcher;
import com.bumptech.glide.load.model.GenericLoaderFactory;
import com.bumptech.glide.load.model.ModelLoader;
import com.bumptech.glide.load.model.ModelLoaderFactory;
import com.bumptech.glide.load.model.stream.StreamModelLoader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
public class AudioCover {
final String path;
public AudioCover(String path) {
this.path = path;
}
}
class AudioCoverLoader implements StreamModelLoader<AudioCover> {
#Override public DataFetcher<InputStream> getResourceFetcher(AudioCover model, int width, int height) {
return new AudioCoverFetcher(model);
}
static class Factory implements ModelLoaderFactory<AudioCover, InputStream> {
#Override public ModelLoader<AudioCover, InputStream> build(Context context, GenericLoaderFactory factories) {
return new AudioCoverLoader();
}
#Override public void teardown() {
}
}
}
class AudioCoverFetcher implements DataFetcher<InputStream> {
private final AudioCover model;
private FileInputStream stream;
public AudioCoverFetcher(AudioCover model) {
this.model = model;
}
#Override public String getId() {
return model.path;
}
#Override public InputStream loadData(Priority priority) throws Exception {
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
try {
retriever.setDataSource(model.path);
byte[] picture = retriever.getEmbeddedPicture();
if (picture != null) {
return new ByteArrayInputStream(picture);
} else {
return fallback(model.path);
}
} finally {
retriever.release();
}
}
private static final String[] FALLBACKS = {"cover.jpg", "album.jpg", "folder.jpg"};
private InputStream fallback(String path) throws FileNotFoundException {
File parent = new File(path).getParentFile();
for (String fallback : FALLBACKS) {
// TODO make it smarter by enumerating folder contents and filtering for files
// example algorithm for that: http://askubuntu.com/questions/123612/how-do-i-set-album-artwork
File cover = new File(parent, fallback);
if (cover.exists()) {
return stream = new FileInputStream(cover);
}
}
return null;
}
#Override public void cleanup() {
// already cleaned up in loadData and ByteArrayInputStream will be GC'd
if (stream != null) {
try {
stream.close();
} catch (IOException ignore) {
// can't do much about it
}
}
}
#Override public void cancel() {
// cannot cancel
}
}
RequestListener<T, R> expects T to be the model you provided in load(), in your case T = ? super AudioCover (documentation):
// ...
.listener(new RequestListener<AudioCover, GlideDrawable>() {
#Override
public boolean onException(Exception e, AudioCover model, Target<GlideDrawable> target, boolean isFirstResource) {
return false;
}
#Override
public boolean onResourceReady(GlideDrawable resource, AudioCover model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
return false;
}
})
// ...
Note that since version 4.0.0-RC0 RequestListener<T, R> was deprecated in favor of RequestListener<R>, find more information in the new javadoc.
Adding RequestListner
Glide.with(this)
.load(url)
.listener(new RequestListener < Uri, GlideDrawable > () {
#Override public boolean onException(Exception e, Uri model, Target < GlideDrawable > target, boolean isFirstResource) {
return false;
}
#Override public boolean onResourceReady(GlideDrawable resource, Uri model, Target < GlideDrawable > target, boolean isFromMemoryCache, boolean isFirstResource) {
// easy
return false;
// impossible?
}
})
.into(imageView);
I'm designing a listview that displays food information list from php server.
the url I passed is a php file after I convert it to json file. the list is not shown and whent I press refresh from menu I keep getting
(app stopped working) ..
here is FoodView.java Activity
import android.content.Context;
import android.os.AsyncTask;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.w3c.dom.Text;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import alsaad.layla.mysqldemo.Models.FoodModel;
import static android.R.attr.resource;
import static android.content.Context.LAYOUT_INFLATER_SERVICE;
public class FoodView extends AppCompatActivity {
private ListView lvFood;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_food_view);
lvFood = (ListView) findViewById(R.id.lvFood);
}
public class JSONTask extends AsyncTask<String, String, List<FoodModel>> {
#Override
protected List<FoodModel> doInBackground(String... params) {
HttpURLConnection httpURLConnection = null;
BufferedReader reader = null;
try {
URL url = new URL(params[0]);
httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.connect();
InputStream inputStream = httpURLConnection.getInputStream();
reader = new BufferedReader(new InputStreamReader(inputStream));
StringBuffer buffer = new StringBuffer();
String line = "";
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
String finalJson = buffer.toString();
JSONArray parentArray = new JSONArray(finalJson);
List<FoodModel> foodModelList = new ArrayList<>();
for (int i = 0; i < parentArray.length(); i++) {
JSONObject finalObject = parentArray.getJSONObject(i);
FoodModel foodModel = new FoodModel();
foodModel.setFood(finalObject.getString("name"));
//foodModel.setStatus(finalObject.getString("status"));
foodModel.setAmount(finalObject.getInt("amount"));
foodModel.setDescription(finalObject.getString("description"));
foodModel.setDate(finalObject.getInt("exDate"));
foodModelList.add(foodModel);
}
return foodModelList;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} finally {
if (httpURLConnection != null) {
httpURLConnection.disconnect();
}
}
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(List<FoodModel> result) {
super.onPostExecute(result);
FoodAdapter adapter = new FoodAdapter(getApplicationContext(), R.layout.row, result);
lvFood.setAdapter(adapter);
}}
public class FoodAdapter extends ArrayAdapter {
private List<FoodModel> foodModelList;
private int resource;
private LayoutInflater inflater;
public FoodAdapter(Context context, int resource, List<FoodModel> objects) {
super(context, resource, objects);
foodModelList = objects;
this.resource = resource;
inflater = (LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = inflater.inflate(resource, null);
}
ImageView ivIcon;
TextView foodName, txt_amount, txt_desc, txt_date, txt_status;
ivIcon = (ImageView) convertView.findViewById(R.id.ivIcon);
foodName = (TextView) convertView.findViewById(R.id.foodName);
txt_amount = (TextView) convertView.findViewById(R.id.txt_amount);
txt_desc = (TextView) convertView.findViewById(R.id.txt_desc);
// txt_status = (TextView) convertView.findViewById(R.id.txt_status);
txt_date = (TextView) convertView.findViewById(R.id.txt_date);
foodName.setText(foodModelList.get(position).getFood());
txt_amount.setText("Amount: " + foodModelList.get(position).getAmount());
txt_desc.setText(foodModelList.get(position).getDescription());
// txt_status.setText(foodModelList.get(position).getStatus());
txt_date.setText("Date: " + foodModelList.get(position).getDate());
return convertView;
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.navigation_drawer, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_refresh) {
new JSONTask().execute("http://10.0.3.2/MySqlDemo/food.php");
return true;
}
return super.onOptionsItemSelected(item);
}
}
FoodModel.java
public class FoodModel {
private String food;
//private enum status;
private int amount;
private String image;
private String description;
private int date;
public int getDate() {
return date;
}
public void setDate(int date) {
this.date = date;
}
public String getFood() {
return food;
}
public void setFood(String food) {
this.food = food;
}
//public String getStatus() {
// return status;
// }
// public void setStatus(String status) {
// this.status = status;
//}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public int getAmount() {
return amount;
}
public void setAmount(int amount) {
this.amount = amount;
}
}
the logcat error:
02-20 05:06:08.084 4514-4514/alsaad.layla.mysqldemo E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.NullPointerException
at android.widget.ArrayAdapter.getCount(ArrayAdapter.java:330)
at android.widget.ListView.setAdapter(ListView.java:462)
at alsaad.layla.mysqldemo.FoodView$JSONTask.onPostExecute(FoodView.java:128)
at alsaad.layla.mysqldemo.FoodView$JSONTask.onPostExecute(FoodView.java:54)
at android.os.AsyncTask.finish(AsyncTask.java:631)
at android.os.AsyncTask.access$600(AsyncTask.java:177)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5041)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
at dalvik.system.NativeStart.main(Native Method)
It seems like you are getting an exception in your for loop that's why it goes into an exception and returns null, so it shows a null pointer exception. Please replace getString() with optSting() and getInt() with optInt().
Solution:- Please put break point in your for loop and find it out otherwise use below option.
for (int i = 0; i < parentArray.length(); i++) {
JSONObject finalObject = parentArray.getJSONObject(i);
FoodModel foodModel = new FoodModel();
foodModel.setFood(finalObject.optString("name"));
//foodModel.setStatus(finalObject.optString("status"));
foodModel.setAmount(finalObject.optInt("amount"));
foodModel.setDescription(finalObject.optString("description"));
foodModel.setDate(finalObject.optInt("exDate"));
foodModelList.add(foodModel);
}
return null; replace with return new ArrayList<>(); to get from crash.
The method getCount() within the ArrayAdater returns the lenght of the object list atached to the adapter:
/**
* {#inheritDoc}
*/
public int getCount() {
return mObjects.size();
}
As you are using a custom ArrayAdapter i think you must Override this function to make it returns the size of your own objects list:
public int getCount() {
return foodModelList.size();
}
Why are you using ArrayAdapter instead i would suggest you to use BaseAdapter
It is the issue when you object is not able to get instance of ArrayAdpter and hence returning null pointer exception at getCount()