I am creating an app similar to a notes app. I have an activity that is called AddEditUserActivity, and, as its name implies, it adds OR edits a user (the object that I created). When I click on a user on the RecyclerView, I am supposed to go to the AddEditUserActivity and see the 5 fields full with the info of the selected user with the title of the activity as "Edit User". When I create a new user, I am supposed to go to the same activity, but with the fields empty, and "Add User" as the title. Creating a user works fine, but when I try to edit it, the activity appears with "Add User" as a title and all the fields empty.
The strange thing is that I implemented some Toast messages like "User updated" and "User Created", and they show when they are supposed to. I think that the problem is in the MainActivity. When I click on a user, I putExtra to an Intent and then call startActivityForResult(EDIT_USER_REQUEST, intent). In the AddEditUserActivity, inside onCreate, I specified that if the intent has a specific extra (the id) then it means that I am updating the user. But it ignores that part. So I would really appreciate it if you could help me.
Here is my MainActivity:
package com.example.citadelentrance;
import androidx.annotation.NonNull;
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 android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import java.util.List;
public class MainActivity extends AppCompatActivity {
public static final int ADD_USER_REQUEST = 1;
public static final int EDIT_USER_REQUEST = 2;
private UserViewModel userViewModel;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FloatingActionButton addUserButton = findViewById(R.id.button_add_user);
addUserButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, AddEditUserActivity.class);
startActivityForResult(intent, ADD_USER_REQUEST);
}
});
RecyclerView recyclerView = findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setHasFixedSize(true);
final UserAdapter adapter = new UserAdapter();
recyclerView.setAdapter(adapter);
userViewModel = ViewModelProviders.of(this).get(UserViewModel.class);
userViewModel.getAllUsers().observe(this, new Observer<List<User>>() {
#Override
public void onChanged(#Nullable List<User> users) {
adapter.submitList(users);
}
});
new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT) {
#Override
public boolean onMove(#NonNull RecyclerView recyclerView, #NonNull RecyclerView.ViewHolder viewHolder, #NonNull RecyclerView.ViewHolder target) {
return false;
}
#Override
public void onSwiped(#NonNull RecyclerView.ViewHolder viewHolder, int direction) {
userViewModel.delete(adapter.getUserAt(viewHolder.getAdapterPosition()));
Toast.makeText(MainActivity.this, "User deleted", Toast.LENGTH_SHORT).show();
}
}).attachToRecyclerView(recyclerView);
adapter.setOnItemClickListener(new UserAdapter.OnItemClickListener() {
#Override
public void onItemClick(User user) {
Intent intent = new Intent(MainActivity.this, AddEditUserActivity.class);
intent.putExtra(AddEditUserActivity.EXTRA_ID, user.getId());
intent.putExtra(AddEditUserActivity.EXTRA_NAME, user.getName());
intent.putExtra(AddEditUserActivity.EXTRA_FAMILY, user.getFamily());
intent.putExtra(AddEditUserActivity.EXTRA_LICENSE_PLATE, user.getLicensePlate());
intent.putExtra(AddEditUserActivity.EXTRA_DOCUMENT, user.getDocument());
intent.putExtra(AddEditUserActivity.EXTRA_ADDRESS, user.getAddress());
intent.putExtra(AddEditUserActivity.EXTRA_TIME, user.getTime());
startActivityForResult(intent, EDIT_USER_REQUEST);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == ADD_USER_REQUEST && resultCode == RESULT_OK) {
assert data != null;
String name = data.getStringExtra(AddEditUserActivity.EXTRA_NAME);
String family = data.getStringExtra(AddEditUserActivity.EXTRA_FAMILY);
String licensePlate = data.getStringExtra(AddEditUserActivity.EXTRA_LICENSE_PLATE);
String document = data.getStringExtra(AddEditUserActivity.EXTRA_DOCUMENT);
String address = data.getStringExtra(AddEditUserActivity.EXTRA_ADDRESS);
String time = data.getStringExtra(AddEditUserActivity.EXTRA_TIME);
User user = new User(
name,
family,
licensePlate,
document,
address,
time
);
userViewModel.insert(user);
Toast.makeText(this, "User saved", Toast.LENGTH_SHORT).show();
} else if (requestCode == EDIT_USER_REQUEST && resultCode == RESULT_OK) {
assert data != null;
int id = data.getIntExtra(AddEditUserActivity.EXTRA_ID, -1);
if (id == -1) {
Toast.makeText(this, "User couldn't be updated", Toast.LENGTH_SHORT).show();
return;
}
String name = data.getStringExtra(AddEditUserActivity.EXTRA_NAME);
String family = data.getStringExtra(AddEditUserActivity.EXTRA_FAMILY);
String licensePlate = data.getStringExtra(AddEditUserActivity.EXTRA_LICENSE_PLATE);
String document = data.getStringExtra(AddEditUserActivity.EXTRA_DOCUMENT);
String address = data.getStringExtra(AddEditUserActivity.EXTRA_ADDRESS);
String time = data.getStringExtra(AddEditUserActivity.EXTRA_TIME);
User user = new User(
name,
family,
licensePlate,
document,
address,
time
);
user.setId(id);
userViewModel.update(user);
Toast.makeText(this, "User updated", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "User not saved", Toast.LENGTH_SHORT).show();
}
}
}
And here the AddEditUserActivity:
package com.example.citadelentrance;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import java.time.LocalDateTime;
import java.util.Objects;
public class AddEditUserActivity extends AppCompatActivity {
public static final String EXTRA_ID = "com.example.citadelentrance.EXTRA_ID";
public static final String EXTRA_NAME = "com.example.citadelentrance.EXTRA_NAME";
public static final String EXTRA_FAMILY = "com.example.citadelentrance.EXTRA_FAMILY";
public static final String EXTRA_LICENSE_PLATE = "com.example.citadelentrance.EXTRA_LICENSE_PLATE";
public static final String EXTRA_DOCUMENT = "com.example.citadelentrance.EXTRA_DOCUMENT";
public static final String EXTRA_ADDRESS = "com.example.citadelentrance.EXTRA_ADDRESS";
public static final String EXTRA_TIME = "com.example.citadelentrance.EXTRA_TIME";
private EditText editTextName, editTextFamily,
editTextLicensePlate, editTextDocument, editTextAddress;
private TextView textViewTime;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_user);
editTextName = findViewById(R.id.edit_text_name);
editTextFamily = findViewById(R.id.edit_text_family);
editTextLicensePlate = findViewById(R.id.edit_text_license_plate);
editTextDocument = findViewById(R.id.edit_text_document);
editTextAddress = findViewById(R.id.edit_text_address);
textViewTime = findViewById(R.id.text_view_time);
Objects.requireNonNull(getSupportActionBar()).setHomeAsUpIndicator(R.drawable.ic_close);
Intent intent = new Intent();
if (intent.hasExtra(EXTRA_ID)) {
setTitle("Edit User");
editTextName.setText(intent.getStringExtra(EXTRA_NAME));
editTextFamily.setText(intent.getStringExtra(EXTRA_FAMILY));
editTextLicensePlate.setText(intent.getStringExtra(EXTRA_LICENSE_PLATE));
editTextDocument.setText(intent.getStringExtra(EXTRA_DOCUMENT));
editTextAddress.setText(intent.getStringExtra(EXTRA_ADDRESS));
textViewTime.setText(intent.getStringExtra(EXTRA_TIME));
} else {
setTitle("Add User");
textViewTime.setText(LocalDateTimeConverter.toDateString(LocalDateTime.now()));
Log.println(Log.ASSERT, "CS50x", "Add user activity");
}
}
private void saveUser() {
String name = getTextFromEdit(editTextName);
String family = getTextFromEdit(editTextFamily);
String licensePlate = getTextFromEdit(editTextLicensePlate);
String document = getTextFromEdit(editTextDocument);
String address = getTextFromEdit(editTextAddress);
String time = textViewTime.toString();
if (name.isEmpty() || family.isEmpty() || licensePlate.isEmpty() ||
document.isEmpty() || address.isEmpty()) {
Toast.makeText(this, "Please don't leave empty fields", Toast.LENGTH_SHORT).show();
return;
}
Intent data = new Intent();
data.putExtra(EXTRA_NAME, name);
data.putExtra(EXTRA_FAMILY, family);
data.putExtra(EXTRA_LICENSE_PLATE, licensePlate);
data.putExtra(EXTRA_DOCUMENT, document);
data.putExtra(EXTRA_ADDRESS, address);
data.putExtra(EXTRA_TIME, time);
int id = getIntent().getIntExtra(EXTRA_ID, -1);
if (id != -1) {
data.putExtra(EXTRA_ID, id);
Log.println(Log.ASSERT, "CS50x", "id != -1");
}
setResult(RESULT_OK, data);
finish();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.menu_save_user, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
if (item.getItemId() == R.id.save_user) {
saveUser();
return true;
}
return super.onOptionsItemSelected(item);
}
private String getTextFromEdit(EditText editText) {
return editText.getText().toString().trim();
}
}
#arget's comment is correct - you need to change this:
Intent intent = new Intent();
to this
Intent intent = getIntent();
or use it directly instead.
Another thing, why don't you make the user class implement Parcelable, and pass the user around instead of all its properties? It would make the code a cleaner.
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 completely new to Android and just learned Object-oriented programming. My project requires me to build something on open-source code. I am really struggling with this special case. Two fragments are under activity_main, one of them is TerminalFragment. I added a menuItem (R.id.plot) in it and set if the user clicks this Item that will lead him from TerminalFragment to activity_main2. Due to receive(byte data) and TerminalFragment still on active, the data is still printing out by receiveText.append(TextUtil.toCaretString(msg, newline.length() != 0)); in activity_main.
Now, I want to convert the data to String and send it to activity_main2 for display in recyclerview and plotting graph. I am trying to use putextra and getextra but not sure how to access data from getextra in activity_main2. In my testing, the recyclerview just showed "John". Is something missing in my method? Does anyone have a better idea? Much Appreciated.
TerminalFragment
package de.kai_morich.simple_bluetooth_le_terminal;
import android.app.Activity;
import android.app.AlertDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.text.Editable;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.method.ScrollingMovementMethod;
import android.text.style.ForegroundColorSpan;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import android.widget.EditText;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
public class TerminalFragment extends Fragment implements ServiceConnection, SerialListener {
private MenuItem menuItem;
private enum Connected { False, Pending, True }
private String deviceAddress;
private SerialService service;
private TextView receiveText;
private TextView sendText;
private TextUtil.HexWatcher hexWatcher;
private Connected connected = Connected.False;
private boolean initialStart = true;
private boolean hexEnabled = false;
private boolean pendingNewline = false;
private String newline = TextUtil.newline_crlf;
private String output;
/*
* Lifecycle
*/
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
//Register with activity
// You must inform the system that your app bar fragment is participating in the population of the options menu.
// tells the system that your fragment would like to receive menu-related callbacks.
setRetainInstance(true);
deviceAddress = getArguments().getString("device");
}
#Override
public void onDestroy() {
if (connected != Connected.False)
disconnect();
getActivity().stopService(new Intent(getActivity(), SerialService.class));
super.onDestroy();
}
#Override
public void onStart() {
super.onStart();
if(service != null)
service.attach(this);
else
getActivity().startService(new Intent(getActivity(), SerialService.class)); // prevents service destroy on unbind from recreated activity caused by orientation change
}
#Override
public void onStop() {
if(service != null && !getActivity().isChangingConfigurations())
service.detach();
super.onStop();
}
#SuppressWarnings("deprecation") // onAttach(context) was added with API 23. onAttach(activity) works for all API versions
#Override
public void onAttach(#NonNull Activity activity) {
super.onAttach(activity);
getActivity().bindService(new Intent(getActivity(), SerialService.class), this, Context.BIND_AUTO_CREATE);
}
#Override
public void onDetach() {
try { getActivity().unbindService(this); } catch(Exception ignored) {}
super.onDetach();
}
#Override
public void onResume() {
super.onResume();
if(initialStart && service != null) {
initialStart = false;
getActivity().runOnUiThread(this::connect);
}
}
#Override
public void onServiceConnected(ComponentName name, IBinder binder) {
service = ((SerialService.SerialBinder) binder).getService();
service.attach(this);
if(initialStart && isResumed()) {
initialStart = false;
getActivity().runOnUiThread(this::connect);
}
}
#Override
public void onServiceDisconnected(ComponentName name) {
service = null;
}
/*
* UI
*/
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_terminal, container, false);
receiveText = view.findViewById(R.id.receive_text); // TextView performance decreases with number of spans
receiveText.setTextColor(getResources().getColor(R.color.colorRecieveText)); // set as default color to reduce number of spans
receiveText.setMovementMethod(ScrollingMovementMethod.getInstance());
sendText = view.findViewById(R.id.send_text);
hexWatcher = new TextUtil.HexWatcher(sendText);
hexWatcher.enable(hexEnabled);
sendText.addTextChangedListener(hexWatcher);
sendText.setHint(hexEnabled ? "HEX mode" : "");
View sendBtn = view.findViewById(R.id.send_btn);
sendBtn.setOnClickListener(v -> send(sendText.getText().toString()));
return view;
}
#Override
public void onCreateOptionsMenu(#NonNull Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_terminal, menu);
menu.findItem(R.id.hex).setChecked(hexEnabled);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.clear) {
receiveText.setText("");
return true;
} if (id == R.id.plot){
Intent intent = new Intent(getActivity(), MainActivity2.class);
startActivity(intent);
//receive.;
return true;
}else if (id == R.id.newline) {
String[] newlineNames = getResources().getStringArray(R.array.newline_names);
String[] newlineValues = getResources().getStringArray(R.array.newline_values);
int pos = java.util.Arrays.asList(newlineValues).indexOf(newline);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Newline");
builder.setSingleChoiceItems(newlineNames, pos, (dialog, item1) -> {
newline = newlineValues[item1];
dialog.dismiss();
});
builder.create().show();
return true;
} else if (id == R.id.hex) {
hexEnabled = !hexEnabled;
sendText.setText("");
hexWatcher.enable(hexEnabled);
sendText.setHint(hexEnabled ? "HEX mode" : "");
item.setChecked(hexEnabled);
return true;
} else {
return super.onOptionsItemSelected(item);
}
}
/*
* Serial + UI
*/
private void connect() {
try {
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
BluetoothDevice device = bluetoothAdapter.getRemoteDevice(deviceAddress);
status("connecting...");
connected = Connected.Pending;
SerialSocket socket = new SerialSocket(getActivity().getApplicationContext(), device);
service.connect(socket);
} catch (Exception e) {
onSerialConnectError(e);
}
}
private void disconnect() {
connected = Connected.False;
service.disconnect();
}
private void send(String str) {
if(connected != Connected.True) {
Toast.makeText(getActivity(), "not connected", Toast.LENGTH_SHORT).show();
return;
}
try {
String msg;
byte[] data;
if(hexEnabled) {
StringBuilder sb = new StringBuilder();
TextUtil.toHexString(sb, TextUtil.fromHexString(str));
TextUtil.toHexString(sb, newline.getBytes());
msg = sb.toString();
data = TextUtil.fromHexString(msg);
} else {
msg = str;
data = (str + newline).getBytes();
}
SpannableStringBuilder spn = new SpannableStringBuilder(msg + '\n');
spn.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.colorSendText)), 0, spn.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
receiveText.append(spn);
service.write(data);
} catch (Exception e) {
onSerialIoError(e);
}
}
private void receive(byte[] data) {
if(hexEnabled) {
receiveText.append("Hello" + TextUtil.toHexString(data) + '\n');
} else {
String msg = new String(data);
if(newline.equals(TextUtil.newline_crlf) && msg.length() > 0) {
// don't show CR as ^M if directly before LF
msg = msg.replace(TextUtil.newline_crlf, TextUtil.newline_lf);
// special handling if CR and LF come in separate fragments
if (pendingNewline && msg.charAt(0) == '\n') {
Editable edt = receiveText.getEditableText();
if (edt != null && edt.length() > 1)
edt.replace(edt.length() - 2, edt.length(), "");
}
pendingNewline = msg.charAt(msg.length() - 1) == '\r';
}
receiveText.append(TextUtil.toCaretString(msg, newline.length() != 0)); //print out data
output = receiveText.toString(); // CharSequence to String
Intent intent = new Intent(getActivity(), MainActivity2.class);
intent.putExtra("output",output); // send data to next activity, MainActivity2
}
}
private void status(String str) {
SpannableStringBuilder spn = new SpannableStringBuilder(str + '\n');
spn.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.colorStatusText)), 0, spn.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
receiveText.append(spn);
}
/*
* SerialListener
*/
#Override
public void onSerialConnect() {
status("connected");
connected = Connected.True;
}
#Override
public void onSerialConnectError(Exception e) {
status("connection failed: " + e.getMessage());
disconnect();
}
#Override
public void onSerialRead(byte[] data) {// receive data
receive(data); // send data to printout
}
#Override
public void onSerialIoError(Exception e) {
status("connection lost: " + e.getMessage());
disconnect();
}
}
MainActivity2.java (new activity)
package de.kai_morich.simple_bluetooth_le_terminal;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.Toast;
import java.util.ArrayList;
public class MainActivity2 extends AppCompatActivity {
Fragment CustomFragment;
private ArrayList<Data> dataList;
private RecyclerView recyclerView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
Toolbar toolbar = findViewById(R.id.toolbar2);
setSupportActionBar(toolbar);
recyclerView = findViewById(R.id.dataflow);
dataList = new ArrayList<>();
String data;
if (savedInstanceState == null) {
Bundle extra = getIntent().getExtras();
if (extra == null) {
data = null;
receiveData(data);
} else {
data = extra.getString("output");
receiveData(data);
}
} else {
data = (String) savedInstanceState.getSerializable("output");
receiveData(data);
}
setAdapter();
}
private void receiveData(String data){
String Data = data;
dataList.add(new Data("John"));
dataList.add(new Data(Data));
}
private void setAdapter() {
recyclerAdapter adapter = new recyclerAdapter(dataList);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(layoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(adapter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_plot, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.dataplot:
Toast.makeText(this, "dataplot", Toast.LENGTH_SHORT).show();
replaceFragment(new DataPlotFragment());
return true;
case R.id.fft:
Toast.makeText(this, "FFT", Toast.LENGTH_SHORT).show();
replaceFragment(new FftFragment());
return true;
case R.id.data:
Toast.makeText(this, "DATA", Toast.LENGTH_SHORT).show();
finish();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private void replaceFragment(Fragment fragment){
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.plotframelayout,fragment);
fragmentTransaction.commit();
}
}
I realized I also need to add getText() in receive(). However, the recycler view won't update itself, it just captures what it has in the recyclerview of activity_main with TerminalFragment when the user click the menuItem (id,plot). Either getextrastring() or using bundle able to pass the data to Mainactivity2.
I think I need to add something else to keep adding data to the recyclerview of activity_main2 from activity_main.
onOptionsItemSelected of TerminalFragment
if (id == R.id.plot){
Intent intent = new Intent(getActivity(), MainActivity2.class);
intent.putExtra("output",output); //output
startActivity(intent);
return true;
}
receive() of TerminalFragment
private void receive(byte[] data) {
if(hexEnabled) {
receiveText.append("Hello" + TextUtil.toHexString(data) + '\n');
} else {
String msg = new String(data);
if(newline.equals(TextUtil.newline_crlf) && msg.length() > 0) {
// don't show CR as ^M if directly before LF
msg = msg.replace(TextUtil.newline_crlf, TextUtil.newline_lf);
// special handling if CR and LF come in separate fragments
if (pendingNewline && msg.charAt(0) == '\n') {
Editable edt = receiveText.getEditableText();
if (edt != null && edt.length() > 1)
edt.replace(edt.length() - 2, edt.length(), "");
}
pendingNewline = msg.charAt(msg.length() - 1) == '\r';
}
receiveText.append(TextUtil.toCaretString(msg, newline.length() != 0)); //print out data
output = receiveText.getText().toString(); // CharSequence to String
}
}
OnCreate of mainActivity2
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
Toolbar toolbar = findViewById(R.id.toolbar2);
setSupportActionBar(toolbar);
recyclerView = findViewById(R.id.dataflow);
dataList = new ArrayList<>();
String data;
Bundle extras = getIntent().getExtras();
if (extras != null)
{
data = extras.getString("output");
receiveData(data);
}
setAdapter();
}
i am working on android studio developing mobile application. i have a payment feature and i integrated PayPal sandbox and when user clicks check out the PayPal page appears. however, when any buyers tries to log in using the appeared page it "incorrect username/password. please try again" although i am sure it is correct and tried multiple accounts and one of them has a valid real credit card but same output. I wonder why this happens? please can someone help me as soon as possible.
this what appears when user tries to log in:
screen shot of PayPal error message
three java classes are related to payment part are provided:
confirmOrder.java:
package com.example.my1stapplication;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.Button;
import android.content.Intent;
import com.example.my1stapplication.config.Config;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.paypal.android.sdk.payments.PayPalConfiguration;
import com.paypal.android.sdk.payments.PayPalPayment;
import com.paypal.android.sdk.payments.PayPalPaymentDetails;
import com.paypal.android.sdk.payments.PayPalService;
import com.paypal.android.sdk.payments.PaymentActivity;
import com.paypal.android.sdk.payments.PaymentConfirmation;
import android.text.TextUtils;
import android.widget.Toast;
import org.json.JSONException;
import java.io.Serializable;
import java.util.HashMap;
import java.math.BigDecimal;
public class confirmOrder extends AppCompatActivity {
EditText district, streetName, houseNo, phoneNo;
Button checkout;
DatabaseReference ordersref= FirebaseDatabase.getInstance().getReference("Orders");
final HashMap<String, Object> ordersMap=new HashMap<>();
public static final int PAYPAL_REQUEST_CODE=7171;
private static PayPalConfiguration config = new PayPalConfiguration().environment(PayPalConfiguration.ENVIRONMENT_SANDBOX).clientId(Config.PAYPAL_CLIENT_ID);
//Double totalPrice=getIntent().getDoubleExtra("totalPrice",0);
#Override
protected void onDestroy() {
stopService(new Intent(this, PayPalService.class));
super.onDestroy();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_confirm_order);
Double totalPrice=getIntent().getDoubleExtra("totalPrice",0);
Intent intent = new Intent(this, PayPalService.class);
intent.putExtra(PayPalService.EXTRA_PAYPAL_CONFIGURATION,config);
startService(intent);
district = (EditText) findViewById(R.id.district);
streetName = (EditText) findViewById(R.id.streetName);
houseNo = (EditText) findViewById(R.id.houseNo);
phoneNo = (EditText) findViewById(R.id.phoneNo);
checkout = (Button) findViewById(R.id.checkout);
String buyerID = getIntent().getStringExtra("buyerID");
// Double totalPrice=getIntent().getDoubleExtra("totalPrice",0);
//HashMap cart=(HashMap) getIntent().getSerializableExtra("cart");
checkout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String district1 = district.getText().toString();
String streetName1 = district.getText().toString();
String houseNo1 = district.getText().toString();
String phoneNo1 = district.getText().toString();
if (!TextUtils.isEmpty(district1) && !TextUtils.isEmpty(district1)
&& !TextUtils.isEmpty(district1) && !TextUtils.isEmpty(district1)) {
Double totalPrice = getIntent().getDoubleExtra("totalPrice", 0);
HashMap<String, Object> cart = (HashMap<String, Object>) getIntent().getSerializableExtra("cart");
String Orderid = ordersref.push().getKey();
ordersMap.put("orderID", Orderid);
ordersMap.put("totalPrice", (totalPrice));
ordersMap.put("buyerID", FirebaseAuth.getInstance().getCurrentUser().getUid());
ordersMap.put("district", district1);
ordersMap.put("streetName", streetName1);
ordersMap.put("houseNo", houseNo1);
ordersMap.put("phoneNo", phoneNo1);
ordersMap.put("paied", false);
ordersMap.put("shipped", false);
ordersMap.put("takenFromOwner", false);
//ordersMap.put("inCart", adapter);
ordersref.child(Orderid).updateChildren(ordersMap);
ordersref.child(Orderid).child("cart").updateChildren(cart);
processPayment();
} else {
Toast.makeText(getApplicationContext(), "please enter all fields", Toast.LENGTH_LONG).show();
}
}
});
}
private void processPayment(){
Double totalPrice=getIntent().getDoubleExtra("totalPrice",0);
PayPalPayment payPalPayment =new PayPalPayment(new BigDecimal(totalPrice),"USD", "Pay for the material/s" , PayPalPayment.PAYMENT_INTENT_SALE);
Intent intent = new Intent(this, PaymentActivity.class);
intent.putExtra(PayPalService.EXTRA_PAYPAL_CONFIGURATION,config);
intent.putExtra(PaymentActivity.EXTRA_PAYMENT,payPalPayment);
startActivityForResult(intent,PAYPAL_REQUEST_CODE);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
Double totalPrice=getIntent().getDoubleExtra("totalPrice",0);
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PAYPAL_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
PaymentConfirmation confirmation = data.getParcelableExtra(PaymentActivity.EXTRA_RESULT_CONFIRMATION);
if (confirmation != null) {
try {
String paymentDetails = confirmation.toJSONObject().toString(4);
startActivity(new Intent(this, PaymentDetails.class).putExtra("PaymentDetails", paymentDetails).putExtra("PaymentAmount", totalPrice));
} catch (JSONException e) {
e.printStackTrace();
}
} else if (resultCode == Activity.RESULT_CANCELED) {
Toast.makeText(this, "Cancel", Toast.LENGTH_SHORT).show();
}
} else if (resultCode == PaymentActivity.RESULT_EXTRAS_INVALID) {
Toast.makeText(this, "Invalid Payment", Toast.LENGTH_SHORT).show();
}
}
}
}
PaymentDetails.java:
package com.example.my1stapplication;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
import org.json.JSONObject;
import android.content.Intent;
import org.json.JSONException;
public class PaymentDetails extends AppCompatActivity {
TextView txtId,txtAmount,txtStatus;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_payment_details);
txtId = (TextView)findViewById(R.id.txtId);
txtStatus = (TextView)findViewById(R.id.txtStatus);
txtAmount = (TextView)findViewById(R.id.txtAmount);
Intent intent=getIntent();
try{
JSONObject jsonObject = new JSONObject(intent.getStringExtra("PaymentDetails"));
showDetails(jsonObject.getJSONObject("response"),intent.getStringExtra("PaymentAmount"));
}
catch (JSONException e){
e.printStackTrace();
}
}
private void showDetails(JSONObject response , String paymentAmount) throws JSONException {
try {
txtId.setText(response.getString("id"));
txtStatus.setText(response.getString("status"));
txtAmount.setText("SR"+paymentAmount);
}
catch(JSONException e){
e.printStackTrace();
}
}
}
Config.java:
package com.example.my1stapplication.config;
public class Config {
public static final String PAYPAL_CLIENT_ID = "AR1bLXBzCYYWa4BCkEyTTcbijrtWPh9u15b3sxQbHQZ-ymhEonDq9zwMo1CqqM95fwHPp-pNjbRF99Am";
}
In order to log into a PayPal Sandbox page, you must use a PayPal Sandbox ( www.sandbox.paypal.com ) account , not a live ( www.paypal.com ) account.
You can create as many PayPal Sandbox accounts as you need within https://www.paypal.com/signin?returnUri=https%3A%2F%2Fdeveloper.paypal.com%2Fdeveloper%2Faccounts
Their email identifiers are fictitious and can be anything not previously used in sandbox. No real emails are ever sent to those addresses; instead, there is a Notifications tab on the left of developer.paypal.com
Hello I am making a teacher assistant app, the app uses SQLite database and allows teacher to take attendance by adding updating and removing students, the student ID is generated everytime a new student is added, now here is the thing how to display error message if the input from the teacher doesn't match a student ID in database instead of making my app crash.
StudentOperations
package com.appcreator.isa.theteacherassistantapp.Database;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import com.appcreator.isa.theteacherassistantapp.Model.Student;
import java.util.ArrayList;
import java.util.List;
public class StudentOperations
{
public static final String LOGTAG = "STD_MNGMNT_SYS";
SQLiteOpenHelper dbhandler;
SQLiteDatabase database;
private static final String[] allColumns = {
StudentDatabaseHandler.COLUMN_SID,
StudentDatabaseHandler.COLUMN_EID,
StudentDatabaseHandler.COLUMN_FIRST_NAME,
StudentDatabaseHandler.COLUMN_LAST_NAME,
StudentDatabaseHandler.COLUMN_STUDY,
StudentDatabaseHandler.COLUMN_ATTENDANCE
};
public StudentOperations(Context context)
{
dbhandler = new StudentDatabaseHandler(context);
}
public void open()
{
Log.i(LOGTAG,"Database Opened");
database = dbhandler.getWritableDatabase();
}
public void close()
{
Log.i(LOGTAG, "Database Closed");
dbhandler.close();
}
public Student addStudent(Student Student)
{
ContentValues values = new ContentValues();
values.put(StudentDatabaseHandler.COLUMN_EID, Student.getEnrlomentID());
values.put(StudentDatabaseHandler.COLUMN_FIRST_NAME,Student.getFirstname());
values.put(StudentDatabaseHandler.COLUMN_LAST_NAME,Student.getLastname());
values.put(StudentDatabaseHandler.COLUMN_STUDY, Student.getStudy());
values.put(StudentDatabaseHandler.COLUMN_ATTENDANCE, Student.getAttendance());
long insertSID = database.insert(StudentDatabaseHandler.TABLE_STUDENTS,null,values);
Student.setStudentID(insertSID);
return Student;
}
// Getting single Student
public Student getStudent(long id)
{
Cursor cursor = database.query(StudentDatabaseHandler.TABLE_STUDENTS,allColumns,StudentDatabaseHandler.COLUMN_SID + "=?",new String[]{String.valueOf(id)},null,null, null, null);
if (cursor != null)
cursor.moveToFirst();
Student e = new Student(Long.parseLong(cursor.getString(0)),cursor.getString(1),cursor.getString(2),cursor.getString(3),cursor.getString(4),cursor.getString(5));
// return Student
return e;
}
public List<Student> getAllStudents()
{
Cursor cursor = database.query(StudentDatabaseHandler.TABLE_STUDENTS,allColumns,null,null,null, null, null);
List<Student> students = new ArrayList<>();
if(cursor.getCount() > 0)
{
while(cursor.moveToNext())
{
Student student = new Student();
student.setStudentID(cursor.getLong(cursor.getColumnIndex(StudentDatabaseHandler.COLUMN_SID)));
student.setEnrlomentID(cursor.getString(cursor.getColumnIndex(StudentDatabaseHandler.COLUMN_EID)));
student.setFirstname(cursor.getString(cursor.getColumnIndex(StudentDatabaseHandler.COLUMN_FIRST_NAME)));
student.setLastname(cursor.getString(cursor.getColumnIndex(StudentDatabaseHandler.COLUMN_LAST_NAME)));
student.setStudy(cursor.getString(cursor.getColumnIndex(StudentDatabaseHandler.COLUMN_STUDY)));
student.setAttendance(cursor.getString(cursor.getColumnIndex(StudentDatabaseHandler.COLUMN_ATTENDANCE)));
students.add(student);
}
}
// return All Students
return students;
}
// Updating Student
public int updateStudent(Student student)
{
ContentValues values = new ContentValues();
values.put(StudentDatabaseHandler.COLUMN_EID, student.getEnrlomentID());
values.put(StudentDatabaseHandler.COLUMN_FIRST_NAME, student.getFirstname());
values.put(StudentDatabaseHandler.COLUMN_LAST_NAME, student.getLastname());
values.put(StudentDatabaseHandler.COLUMN_STUDY, student.getStudy());
values.put(StudentDatabaseHandler.COLUMN_ATTENDANCE, student.getAttendance());
// updating row
return database.update(StudentDatabaseHandler.TABLE_STUDENTS, values,
StudentDatabaseHandler.COLUMN_SID + "=?",new String[] { String.valueOf(student.getStudentID())});
}
// Deleting Student
public void removeStudent(Student student)
{
database.delete(StudentDatabaseHandler.TABLE_STUDENTS, StudentDatabaseHandler.COLUMN_SID + "=" + student.getStudentID(), null);
}
}
The Main Activity
package com.appcreator.isa.theteacherassistantapp;
import android.content.DialogInterface;
import android.content.Intent;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.appcreator.isa.theteacherassistantapp.Database.StudentDatabaseHandler;
import com.appcreator.isa.theteacherassistantapp.Database.StudentOperations;
import com.appcreator.isa.theteacherassistantapp.Model.Student;
public class MainActivity extends AppCompatActivity
{
private Button addStudentButton;
private Button editStudentButton;
private Button deleteStudentButton;
private StudentOperations studentOps;
private static final String EXTRA_STUDENT_ID = "TEMP";
private static final String EXTRA_ADD_UPDATE = "TEMP";
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
addStudentButton = (Button) findViewById(R.id.button_add_student);
editStudentButton = (Button) findViewById(R.id.button_edit_student);
deleteStudentButton = (Button) findViewById(R.id.button_delete_student);
addStudentButton.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
Intent i = new Intent(MainActivity.this,AddUpdateStudent.class);
i.putExtra(EXTRA_ADD_UPDATE, "Add");
startActivity(i);
}
});
editStudentButton.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v) {
getStudentIDAndUpdateStudent();
}
});
deleteStudentButton.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v) {
getStudentIDAndRemoveStudent();
}
});
}
public void getStudentIDAndUpdateStudent()
{
LayoutInflater li = LayoutInflater.from(this);
View getStudentIdView = li.inflate(R.layout.dialog_get_student_id, null);
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
// set dialog_get_student_id.xml to alertdialog builder
alertDialogBuilder.setView(getStudentIdView);
final EditText userInput = (EditText) getStudentIdView.findViewById(R.id.editTextDialogUserInput);
// set dialog message
alertDialogBuilder
.setCancelable(false)
.setPositiveButton("OK",new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int id)
{
if (userInput.getText().toString().trim().length() > 0)
{
// get user input and set it to result
// edit text
Intent i = new Intent(MainActivity.this,AddUpdateStudent.class);
i.putExtra(EXTRA_ADD_UPDATE, "Update");
i.putExtra(EXTRA_STUDENT_ID, Long.parseLong(userInput.getText().toString()));
startActivity(i);
}
else
{
Toast.makeText(MainActivity.this, "Input is invalid", Toast.LENGTH_SHORT).show();
}
}
}).create()
.show();
}
public void getStudentIDAndRemoveStudent(){
LayoutInflater li = LayoutInflater.from(this);
View getStudentIdView = li.inflate(R.layout.dialog_get_student_id, null);
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
// set dialog_get_student_id.xml to alertdialog builder
alertDialogBuilder.setView(getStudentIdView);
final EditText userInput = (EditText) getStudentIdView.findViewById(R.id.editTextDialogUserInput);
// set dialog message
alertDialogBuilder
.setCancelable(false)
.setPositiveButton("OK",new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int id)
{
if (userInput.getText().toString().trim().length() > 0)
{
// get user input and set it to result
// edit text
//studentOps = new StudentOperations(MainActivity.this); disabled because placing it here causes error
studentOps.removeStudent(studentOps.getStudent(Long.parseLong(userInput.getText().toString())));
Toast.makeText(MainActivity.this, "Student has been removed successfully", Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(MainActivity.this, "Input is invalid", Toast.LENGTH_SHORT).show();
}
}
}).create()
.show();
}
#Override
protected void onResume()
{
super.onResume();
studentOps = new StudentOperations(MainActivity.this);
studentOps.open();
}
#Override
protected void onPause()
{
super.onPause();
studentOps.close();
}
}
Logcat
10-17 03:42:09.750 11105-11105/com.appcreator.isa.theteacherassistantapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.appcreator.isa.theteacherassistantapp, PID: 11105
android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
at android.database.AbstractCursor.checkPosition(AbstractCursor.java:460)
at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:136)
at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:50)
at com.appcreator.isa.theteacherassistantapp.Database.StudentOperations.getStudent(StudentOperations.java:71)
at com.appcreator.isa.theteacherassistantapp.MainActivity$5.onClick(MainActivity.java:144)
at android.support.v7.app.AlertController$ButtonHandler.handleMessage(AlertController.java:167)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:241)
at android.app.ActivityThread.main(ActivityThread.java:6274)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Updated Main Activity
package com.appcreator.isa.theteacherassistantapp;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.appcreator.isa.theteacherassistantapp.Database.StudentDatabaseHandler;
import com.appcreator.isa.theteacherassistantapp.Database.StudentOperations;
import com.appcreator.isa.theteacherassistantapp.Model.Student;
public class MainActivity extends AppCompatActivity
{
private Button addStudentButton;
private Button editStudentButton;
private Button deleteStudentButton;
private StudentOperations studentOps;
private static final String EXTRA_STUDENT_ID = "TEMP";
private static final String EXTRA_ADD_UPDATE = "TEMP";
private static final String TAG = "Student Exits";
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
addStudentButton = (Button) findViewById(R.id.button_add_student);
editStudentButton = (Button) findViewById(R.id.button_edit_student);
deleteStudentButton = (Button) findViewById(R.id.button_delete_student);
addStudentButton.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
Intent i = new Intent(MainActivity.this,AddUpdateStudent.class);
i.putExtra(EXTRA_ADD_UPDATE, "Add");
startActivity(i);
}
});
editStudentButton.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v) {
getStudentIDAndUpdateStudent();
}
});
deleteStudentButton.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v) {
getStudentIDAndRemoveStudent();
}
});
}
public boolean check_existence(String stud_id)
{
SQLiteOpenHelper db = new StudentDatabaseHandler(this);
SQLiteDatabase database = db.getWritableDatabase();
String select = "SELECT * FROM students WHERE studentID =" + stud_id;
Cursor c = database.rawQuery(select, null);
if (c.moveToFirst())
{
Log.d(TAG,"Student Exists");
return true;
}
if(c!=null)
{
c.close();
}
database.close();
return false;
}
public void getStudentIDAndUpdateStudent()
{
LayoutInflater li = LayoutInflater.from(this);
final View getStudentIdView = li.inflate(R.layout.dialog_get_student_id, null);
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
// set dialog_get_student_id.xml to alertdialog builder
alertDialogBuilder.setView(getStudentIdView);
final EditText userInput = (EditText) getStudentIdView.findViewById(R.id.editTextDialogUserInput);
// set dialog message
alertDialogBuilder
.setCancelable(false)
.setPositiveButton("OK",new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog,int id)
{
if (userInput.getText().toString().isEmpty())
{
Toast.makeText(MainActivity.this, "Input is invalid", Toast.LENGTH_SHORT).show();
}
else
{
// get user input and set it to result
// edit text
if (check_existence(userInput.getText().toString()) == true)
{
Intent i = new Intent(MainActivity.this,AddUpdateStudent.class);
i.putExtra(EXTRA_ADD_UPDATE, "Update");
i.putExtra(EXTRA_STUDENT_ID, Long.parseLong(userInput.getText().toString()));
startActivity(i);
}
else
{
Toast.makeText(MainActivity.this, "Input is invalid", Toast.LENGTH_SHORT).show();
}
}
}
}).create()
.show();
}
public void getStudentIDAndRemoveStudent()
{
LayoutInflater li = LayoutInflater.from(this);
View getStudentIdView = li.inflate(R.layout.dialog_get_student_id, null);
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
// set dialog_get_student_id.xml to alertdialog builder
alertDialogBuilder.setView(getStudentIdView);
final EditText userInput = (EditText) getStudentIdView.findViewById(R.id.editTextDialogUserInput);
// set dialog message
alertDialogBuilder
.setCancelable(false)
.setPositiveButton("OK",new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int id)
{
if (userInput.getText().toString().isEmpty())
{
Toast.makeText(MainActivity.this, "Invalid Input", Toast.LENGTH_SHORT).show();
}
else
{
if(check_existence(userInput.getText().toString()) == true)
{
// get user input and set it to result
// edit text
//studentOps = new StudentOperations(MainActivity.this); disabled because placing it here causes error
studentOps.removeStudent(studentOps.getStudent(Long.parseLong(userInput.getText().toString())));
Toast.makeText(MainActivity.this, "Student has been removed successfully", Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(MainActivity.this, "Invalid Input" , Toast.LENGTH_SHORT).show();
}
}
}
}).create()
.show();
}
#Override
protected void onResume()
{
super.onResume();
studentOps = new StudentOperations(MainActivity.this);
studentOps.open();
}
#Override
protected void onPause()
{
super.onPause();
studentOps.close();
}
}
You can make a new method to do the work with boolean data type and if it returns false, you might want to display it to the user via Toast or anything like that.
It may look like this in code:
public boolean check_existence(String stud_id) {
SQLiteDatabase db = this.getWritableDatabase();
String select = "SELECT * FROM table_name WHERE column_name ='" + stud_id;
Cursor c = db.rawQuery(select, null);
if (c.moveToFirst()) {
Log.d(TAG,"User exits");
return true;
}
if(c!=null) {
c.close();
}
db.close();
return false;
}
You can now just call the method and if it returns false you may just display what you want using Toast.
I created an app with database in assets folder . I wrote a code to copy database to SD Card and of course for android 6 + it needs run time permission. My problem : on first run after granting permission database isn't loaded but on second run there is no problem. Please help me to solve this issue .
UPDATE: Problem solved! now I have problem with favorite section. when I add something to favorite it can't be updated and I have to restart app and also with each run data is shown more than one time.
Here's my code :
package farmani.com.essentialwordsforielts.mainPage;
import android.Manifest;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Build;
import android.os.Environment;
import android.support.annotation.NonNull;
import android.support.design.widget.NavigationView;
import android.support.design.widget.TabLayout;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.ViewPager;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Gravity;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import farmani.com.essentialwordsforielts.R;
import farmani.com.essentialwordsforielts.search.ActivitySearch;
public class MainActivity extends AppCompatActivity {
public static Context context;
public static ArrayList<Structure> list = new ArrayList<>();
public static ArrayList<Structure> favorite = new ArrayList<>();
DrawerLayout drawerLayout;
NavigationView navigationView;
ImageView hamburger;
SQLiteDatabase database;
String destPath;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.navigation_activity_main);
if (Build.VERSION.SDK_INT >= 23) {
if (ContextCompat.checkSelfPermission(MainActivity.this,
Manifest.permission.READ_EXTERNAL_STORAGE) !=
PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this
, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE
, Manifest.permission.WRITE_EXTERNAL_STORAGE}
, 1);
} else if (ContextCompat.checkSelfPermission(MainActivity.this,
Manifest.permission.WRITE_EXTERNAL_STORAGE) !=
PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this
, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE
, Manifest.permission.WRITE_EXTERNAL_STORAGE}
, 1);
} else {
setupDB();
selectList();
selectFavorite();
Toast.makeText(MainActivity.this, "You grandet earlier",
Toast.LENGTH_LONG).show();
}
}
if (!favorite.isEmpty()){
favorite.clear();
selectFavorite();
} else if (!list.isEmpty()){
list.clear();
selectList();
}
context = getApplicationContext();
setTabOption();
drawerLayout = findViewById(R.id.navigation_drawer);
navigationView = findViewById(R.id.navigation_view);
hamburger = findViewById(R.id.hamburger);
hamburger.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
drawerLayout.openDrawer(Gravity.START);
}
});
navigationView.setNavigationItemSelectedListener(new
NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
int id = item.getItemId();
if (id == R.id.exit) {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(
MainActivity.this);
alertDialog.setTitle(R.string.exit);
alertDialog.setMessage(R.string.exit_ask);
alertDialog.setCancelable(false);
alertDialog.setPositiveButton(R.string.yes,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int
which) {
finish();
}
});
alertDialog.setNegativeButton(R.string.no,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int
which) {
dialog.cancel();
}
});
alertDialog.show();
}
if (id == R.id.search) {
Intent intent = new Intent(MainActivity.this,
ActivitySearch.class);
MainActivity.this.startActivity(intent);
}
return true;
}
});
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[]
permissions, #NonNull int[] grantResults) {
switch (requestCode) {
case 1: {
if (grantResults.length >= 2 && grantResults[0] ==
PackageManager.PERMISSION_GRANTED && grantResults[1] ==
PackageManager.PERMISSION_GRANTED) {
Toast.makeText(MainActivity.this, "Access granted",
Toast.LENGTH_LONG).show();
}
}
}
}
#Override
public void onBackPressed() {
if (drawerLayout.isDrawerOpen(Gravity.START)) {
drawerLayout.closeDrawer(Gravity.START);
} else {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(
MainActivity.this);
alertDialog.setTitle(R.string.exit);
alertDialog.setMessage(R.string.exit_ask);
alertDialog.setCancelable(false);
alertDialog.setPositiveButton(R.string.yes,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
finish();
}
});
alertDialog.setNegativeButton(R.string.no,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
alertDialog.show();
}
}
private void setTabOption() {
ViewPager viewPager = findViewById(R.id.viewpager);
viewPager.setAdapter(new AdapterFragment(getSupportFragmentManager(),
context));
TabLayout tabStrip = findViewById(R.id.tabs);
tabStrip.setupWithViewPager(viewPager);
}
private void setupDB() {
try {
destPath =
Environment.getExternalStorageDirectory().getAbsolutePath()
+ "/ielts/";
File file = new File(destPath);
if (!file.exists()) {
file.mkdirs();
file.createNewFile();
CopyDB(getBaseContext().getAssets().open("md_book.db"),
new FileOutputStream(destPath + "/md_book.db"));
}
} catch (IOException e1) {
e1.printStackTrace();
}
}
#Override
protected void onResume() {
super.onResume();
if (!favorite.isEmpty()){
favorite.clear();
selectFavorite();
} else if (!list.isEmpty()){
list.clear();
selectList();
}
}
private void CopyDB(InputStream inputStream, OutputStream outputStream)
throws IOException {
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, length);
}
inputStream.close();
outputStream.close();
}
private void selectFavorite() {
database = SQLiteDatabase.openOrCreateDatabase(destPath + "/md_book.db",
null);
Cursor cursor = database.rawQuery("SELECT * FROM main WHERE fav = 1",
null);
while (cursor.moveToNext()) {
String word = cursor.getString(cursor.getColumnIndex("word"));
String definition =
cursor.getString(cursor.getColumnIndex("definition"));
String trans = cursor.getString(cursor.getColumnIndex("trans"));
String img = cursor.getString(cursor.getColumnIndex("img"));
int id = cursor.getInt(cursor.getColumnIndex("id"));
Structure struct = new Structure(word, definition, trans, img, id);
struct.setWord(word);
struct.setDefinition(definition);
struct.setTrans(trans);
struct.setImg(img);
struct.setId(id);
favorite.add(struct);
}
}
private void selectList() {
database = SQLiteDatabase.openOrCreateDatabase(destPath + "/md_book.db",
null);
Cursor cursor = database.rawQuery("SELECT * FROM main", null);
while (cursor.moveToNext()) {
String word = cursor.getString(cursor.getColumnIndex("word"));
String definition =
cursor.getString(cursor.getColumnIndex("definition"));
String trans = cursor.getString(cursor.getColumnIndex("trans"));
String img = cursor.getString(cursor.getColumnIndex("img"));
int id = cursor.getInt(cursor.getColumnIndex("id"));
Structure struct = new Structure(word, definition, trans, img, id);
struct.setWord(word);
struct.setDefinition(definition);
struct.setTrans(trans);
struct.setImg(img);
struct.setId(id);
list.add(struct);
}
}
}
You have just shown a toast after permissions are granted for the first time i.e. inside onRequestPermissionsResult. You will need to place the code to perform necessary operations inside there too.