make a search in recylerview - firebase

I want to make a search on recyclerview, but the data appears if the phone is turned off and then turned on again, why is that?
the example photo
the app
When i'm search the recylerview is blank
but when the phones turned off and then turn on again, the data is appear
here's the code in fragment class
//search
editText = view.findViewById(R.id.searchServant);
searchButton = view.findViewById(R.id.button2);
searchButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String s = editText.getText().toString();
firebaseSearch(s);
}
});
//RecylerviewDatabaseServant
recyclerViewdatabase = view.findViewById(R.id.recyclerViewServant);
mManager = new LinearLayoutManager(getContext());
recyclerViewdatabase.setLayoutManager(mManager);
FirebaseRecyclerOptions<Servant> options =
new FirebaseRecyclerOptions.Builder<Servant>().setQuery(FirebaseDatabase.getInstance().getReference().child("Servant")
, Servant.class)
.build();
servantAdapter = new ServantAdapter(options);
recyclerViewdatabase.setAdapter(servantAdapter);
//End
here the function firebase search
private void firebaseSearch(String s) {
FirebaseRecyclerOptions<Servant> options = new FirebaseRecyclerOptions.Builder<Servant>().setQuery(FirebaseDatabase.getInstance()
.getReference().child("Servant").orderByChild("name").startAt(s).endAt(s + "\uf8ff"), Servant.class).build();
servantAdapter = new ServantAdapter(options);
recyclerViewdatabase.setAdapter(servantAdapter);
}

Try add this line in You search query
private void firebaseSearch(String s) {
FirebaseRecyclerOptions<Servant> options = new FirebaseRecyclerOptions.Builder<Servant>().setQuery(FirebaseDatabase.getInstance()
.getReference().child("Servant").orderByChild("name").startAt(s).endAt(s + "\uf8ff"), Servant.class).build();
servantAdapter = new ServantAdapter(options);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager({**context**}));
recyclerViewdatabase.setAdapter(servantAdapter);
servantAdapter.startListening();
}

Related

I am trying to implement NotificationChannel and WorkManager but somehow its not working and am not seeing anything Wrong

I am trying to implement a feature where you choose a date and time and the notification pops up on your phone. so after writing some code its still not working but everything seems fine
Activity code
FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#RequiresApi(api = Build.VERSION_CODES.M)
#Override
public void onClick(View view) {
Calendar customCalendar = GregorianCalendar.getInstance();
DatePicker dp = findViewById(R.id.date_picker);
TimePicker picker = findViewById(R.id.time_picker);
customCalendar.set(
dp.getYear(), dp.getMonth(), dp.getDayOfMonth(), picker.getHour(), picker.getMinute(), 0);
long customTime = customCalendar.getTimeInMillis();
SimpleDateFormat sdf = new SimpleDateFormat(getString(R.string.notification_schedule_pattern), Locale.getDefault());
long currentTime = System.currentTimeMillis();
Log.d("time", "cistomTime " + customTime);
Log.d("time", "cistomTime " + currentTime);
if (customTime > currentTime) {
Data data = new Data.Builder().putInt(NOTIFICATION_ID, 0).build();
int delay = (int) (customTime - currentTime);
scheduleNotification(delay, data);
String titleNotificationSchedule = getString(R.string.notification_schedule_title);
Snackbar.make(
view,
titleNotificationSchedule + sdf
.format(customCalendar.getTime()),
LENGTH_LONG).show();
// Snackbar.make(coordinatorLayout, "Reminder set", LENGTH_LONG)
// .setAction("Action", null).show();
} else {
String errorNotificationSchedule = "Error occured";
Snackbar.make(coordinatorLayout, errorNotificationSchedule, LENGTH_LONG).show();
}
}
});
}
private void scheduleNotification(long delay, Data data) {
OneTimeWorkRequest notificationWork = new OneTimeWorkRequest.Builder(NotifyWork.class)
.setInitialDelay(delay, MILLISECONDS).setInputData(data).build();
WorkManager instanceWorkManager = WorkManager.getInstance(getApplicationContext());
instanceWorkManager.beginUniqueWork(NOTIFICATION_WORK, REPLACE, notificationWork).enqueue();
}
Worker class
public class NotifyWork extends Worker {
public static final String NOTIFICATION_ID = "notification_id";
public static final String NOTIFICATION_NAME = "Remember";
public static final String NOTIFICATION_CHANNEL = "Reminder_Channel";
public static final String NOTIFICATION_WORK = "Notification_Work";
public NotifyWork(#NonNull Context context, #NonNull WorkerParameters workerParams) {
super(context, workerParams);
}
#NonNull
#Override
public Result doWork() {
int id = getInputData().getInt(NOTIFICATION_ID, 0);
sendNotification(id);
return Result.success();
}
private void sendNotification(int id) {
NotificationManager notificationManager = (NotificationManager) getApplicationContext()
.getSystemService(Context.NOTIFICATION_SERVICE);
Bitmap bitmap = BitmapFactory.decodeResource(getApplicationContext().getResources(), R.drawable.ic_done_white_24dp);
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.putExtra(NOTIFICATION_ID, id);
String titleNotification = "Reminder";
String subtitleNotification = "Time To WakeUp";
PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder notification = new NotificationCompat.Builder(getApplicationContext(), NOTIFICATION_CHANNEL)
.setLargeIcon(bitmap).setContentTitle(titleNotification)
.setContentText(subtitleNotification).setDefaults(IMPORTANCE_DEFAULT).setSound(getDefaultUri(TYPE_NOTIFICATION))
.setContentIntent(pendingIntent).setAutoCancel(true);
notification.setPriority(IMPORTANCE_MAX);
notificationManager.notify(id, notification.build());
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
Uri ringtoneManager = getDefaultUri(TYPE_NOTIFICATION);
AudioAttributes audioAttributes = new AudioAttributes.Builder().setUsage(USAGE_NOTIFICATION_RINGTONE)
.setContentType(CONTENT_TYPE_SONIFICATION).build();
NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL, NOTIFICATION_NAME, NotificationManager.IMPORTANCE_DEFAULT);
channel.enableLights(true);
channel.setLightColor(RED);
channel.enableVibration(true);
channel.setSound(ringtoneManager, audioAttributes);
notificationManager.createNotificationChannel(channel);
}
}
I have a DatePicker and TimePicker, when you select date and time and click on the FAB button, you get notified at that particular time
somehow changing .setLargeIcon to .setSmallIcon and referencing the image directly without converting to bitmap eg .setSmallIcon(R.drawable.ic_done_white_24dp) solved the issue

SQLite Database for Commenting function

There is no errors with the codes. However, I am trying to build a comment section where the name and comments will be saved in the database(SQLite).
1) It does not stay in the Textview after i come back from another page.
2) Example, i commented once, and the comment shows. I comment again, it actually re-displays the previous and the new comments together.
public class BuyerHome extends AppCompatActivity {
DatabaseHelper2 myDB;
//EditText name,comment;
EditText nameIn;
EditText commentIn;
TextView viewComment;
Button postComment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_buyer_home);
nameIn = (EditText) findViewById(R.id.nameInput);
commentIn = (EditText) findViewById(R.id.commentText);
viewComment = (TextView) findViewById(R.id.viewCommentText);
myDB = new DatabaseHelper2(this);
postComment = (Button) findViewById(R.id.buttonComment);
postComment.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String name = nameIn.getText().toString();
String comment = commentIn.getText().toString();
if(nameIn.length()!=0 && commentIn.length()!=0){
AddData(name,comment);
nameIn.setText("");
commentIn.setText("");
}else{
Toast.makeText(BuyerHome.this, "Insert fields",
Toast.LENGTH_SHORT).show();
}
Cursor data = myDB.getContents();
if(data.getCount()==0){
Toast.makeText(BuyerHome.this, "Database empty",
Toast.LENGTH_SHORT).show();
}
else{
while(data.moveToNext()){
viewComment.append(data.getString(1));
viewComment.append(data.getString(2)+"\n");
}
}
//viewComment.append("\n"+name+":"+comment);
}
});
}
public void AddData(String name,String comment){
boolean insertData = myDB.insertData(name,comment);
if(insertData==true){
Toast.makeText(this, "Success", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(this, "Fail", Toast.LENGTH_SHORT).show();
}
}
}
1) I would like the past comments to be there as long as the page is available.
2) I would like only the latest comment to be displayed(on top of the past comments), and not the past comments(re-displaying again) with the new comment.
I'd suggest perhaps using a second view for the older comments. You would also need a means of determining the latest as opposed to older comments.
In the example below the second view is a Listview (this would enable you to click on a specific message, perhaps quoting it, perhaps extracting the name).
The example caters for two ways of determining the last posted comment via the id column (note _id is actually used as the column name as this then allows a Cursor Adapter to be used for the ListView which can be advantageous).
To facilitate showing the comments after returning the onResume method has been overridden inn the activity.
here's the code :-
DatabaseHelper2.java
public class DatabaseHelper2 extends SQLiteOpenHelper {
private final static String DBNAME = "buyerdb";
private final static int DBVERSION = 1;
public final static String TBL_COMMENT = "comment";
public final static String COL_COMMENT_ID = BaseColumns._ID;
public final static String COL_COMMENT_NAME = "name";
public final static String COL_COMMENT_COMMENT = "comment";
public final static String COl_COMMENT_TIMESTAMP = "timestamp";
private String crt_tbl_comment = "CREATE TABLE IF NOT EXISTS " + TBL_COMMENT + "(" +
COL_COMMENT_ID + " INTEGER PRIMARY KEY, " +
COL_COMMENT_NAME + " TEXT," +
COL_COMMENT_COMMENT + " TEXT, " +
COl_COMMENT_TIMESTAMP + " TEXT DEFAULT CURRENT_TIMESTAMP" +
")";
SQLiteDatabase mDB;
public DatabaseHelper2(Context context) {
super(context, DBNAME, null, DBVERSION);
mDB = this.getWritableDatabase();
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(crt_tbl_comment);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public long addData(String name, String comment) {
ContentValues cv = new ContentValues();
cv.put(COL_COMMENT_NAME,name);
cv.put(COL_COMMENT_COMMENT,comment);
return mDB.insert(TBL_COMMENT,null,cv);
}
public Cursor getLatestComment() {
return mDB.query(TBL_COMMENT,null,null,null,null,null,COl_COMMENT_TIMESTAMP + " DESC","1");
}
public Cursor getAllButLatestComment() {
String whereclause = COL_COMMENT_ID + " < (SELECT max(" +
COL_COMMENT_ID +
") FROM " + TBL_COMMENT +
")";
return mDB.query(TBL_COMMENT,null,whereclause,null,null,null,COl_COMMENT_TIMESTAMP + " DESC");
}
}
Note that the timestamp column hasn't been utilised but could be, as when a row (a comment) is added the current timestamp will automatically be used to set the column.
Note the getLatestComment and the getAllButLatestComment methods return a Cursor with the appropriate rows.
BuyerHome.java
public class BuyerHome extends AppCompatActivity {
EditText nameIn;
EditText commentIn;
TextView viewComment;
Button postComment;
ListView olderComments; //<<<<<<<<<< Added (Listview needs to be added to the layout)
DatabaseHelper2 myDB;
Cursor oldermessages, latestmessage; //<<<<<<<<<< Added
SimpleCursorAdapter sma; //<<<<<<<<<< Added adapter for the ListView
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_buyer_home);
nameIn = (EditText) findViewById(R.id.nameInput);
commentIn = (EditText) findViewById(R.id.commentText);
viewComment = (TextView) findViewById(R.id.viewCommentText);
olderComments = (ListView) findViewById(R.id.olderComments); //<<<<<<<<<< Added
myDB = new DatabaseHelper2(this);
postComment = (Button) findViewById(R.id.buttonComment);
postComment.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String name = nameIn.getText().toString();
String comment = commentIn.getText().toString();
if (nameIn.length() != 0 && commentIn.length() != 0) {
myDB.addData(name, comment); //<<<<<<<<<< method starts changed lower case a
nameIn.setText("");
commentIn.setText("");
} else {
Toast.makeText(BuyerHome.this, "Insert fields",
Toast.LENGTH_SHORT).show();
}
displayComments(); //<<<<<<<<<< added to refresh the display according to the latest comments
}
});
}
//<<<<<<<<<< ADDED so will display comments whenever called including returning from another activity
#Override
protected void onResume() {
super.onResume();
displayComments();
}
//<<<<<<<<<< ADDED entire method for displaying comments
private void displayComments() {
latestmessage = myDB.getLatestComment();
if (latestmessage.moveToFirst()) {
viewComment.setText(latestmessage.getString(latestmessage.getColumnIndex(DatabaseHelper2.COL_COMMENT_NAME)) +
" said :- " +
latestmessage.getString(latestmessage.getColumnIndex(DatabaseHelper2.COL_COMMENT_COMMENT)));
} else {
viewComment.setText("");
}
oldermessages = myDB.getAllButLatestComment();
if (sma == null) {
sma = new SimpleCursorAdapter(
this,
android.R.layout.simple_list_item_2,oldermessages,
new String[]{DatabaseHelper2.COL_COMMENT_NAME,DatabaseHelper2.COL_COMMENT_COMMENT},
new int[]{android.R.id.text1,android.R.id.text2},
0
);
olderComments.setAdapter(sma);
} else {
sma.swapCursor(oldermessages);
}
}
}
Result
The highlighted line is the latest comment.
The latest comment is followed by the list of all other comments.

Firebase Query not being updated

I want my firebase database link to be updated depending on what the user keys in inside the searchview but the link is not updated unless I open another activity and jump back to it.I have attacked my code in the bottom. So how do I refresh it automatically ?
sv.setOnQueryTextListener(new SearchView.OnQueryTextListener()
{
#Override
public boolean onQueryTextSubmit(String query) {
query = sv.getQuery().toString();
Toast.makeText(MainMenu.this,query, Toast.LENGTH_SHORT).show();
makeItem();
return true;
}
#Override
public boolean onQueryTextChange(String newText) {
return false;
}
});
public void makeItem ()
{
lv = findViewById(R.id.listView);
db = FirebaseDatabase.getInstance().getReferenceFromUrl("https://vsem-inventory.firebaseio.com/ItemList").orderByChild("ProductName").startAt(query).endAt(query+"\uf8ff");
FirebaseListOptions<ItemObject> options = new FirebaseListOptions.Builder<ItemObject>()
.setLayout(R.layout.content_main_menu_list)
.setQuery(db,ItemObject.class)
.build();
mAdapter = new FirebaseListAdapter<ItemObject>(options) {
#Override
protected void populateView(#NonNull View v, #NonNull ItemObject model, int position) {
final TextView tvAmount = v.findViewById(R.id.amount);
final TextView tvName = v.findViewById(R.id.name);
final TextView tvSerial = v.findViewById(R.id.serialNo);
final TextView tvSupplier = v.findViewById(R.id.supplierName);
final ImageView more = v.findViewById(R.id.more);
ImageView statusimg = v.findViewById(R.id.status);
Drawable paidIcon = v.getResources().getDrawable(R.drawable.succes);
Drawable lateIcon = v.getResources().getDrawable(R.drawable.late);
tvName.setText(model.getProductName());
tvSerial.setText(model.getSerialNo());
tvAmount.setText(model.getQuantity());
tvSupplier.setText(model.getModel());
final String Remarks = model.getRemarks();
final String cat = model.getCategory();
if(model.getQuantity().equals("0"))
statusimg.setImageDrawable(lateIcon);
else
statusimg.setImageDrawable(paidIcon);
more.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v) {
String serialNo = tvSerial.getText().toString();
String itemName = tvName.getText().toString();
String quan = tvAmount.getText().toString();
String supplier = tvSupplier.getText().toString();
showMenu(itemName,more,serialNo,quan,supplier,cat,Remarks);
}
});
}
};
lv.setAdapter(mAdapter);
}
The standard way is to call notifyDataSetChanged() after setting your adapter to your list view
Notifies the attached observers that the underlying data has been changed and any View reflecting the data set should refresh itself.
mAdapter.notifyDataSetChanged();
Although I have seen some situations where only using this does not work and must be followed by these 2 commands.
lv.invalidateViews();
lv.scrollBy(0, 0);
And if all else comes to fail falling back on destroying and redrawing the list view might be your only viable option.
lv.destroyDrawingCache();
lv.setVisibility(ListView.INVISIBLE);
lv.setVisibility(ListView.VISIBLE);
EDIT : After looking at it a while more I just noticed you're missing listeners for your firebase. I assume you already have them somewhere as you already have the list but failing your refresh functions, what you can try is restarting the listeners whenever you're done with a query.
lv.setAdapter(mAdapter);
mAdapter.stopListening();
mAdapter.startListening();

Fill JavaFX combobox by javascript class (Nashorn)

I try to use my custom class which I have created in my script (the script is written in Nashorn) and after that I try to use this custom class to fill in as items in combobox. I know that if I want to see correct values in combobox that the class has to override method toString, but in this case I do not know much how can be overriden this method in my custom class written in Nahorn.
Below I provide my code where the variables cmbCategories is JavaFX combobox and CategoryItem which I try to use as object to fill in the items in combobox and display as category name.
I would appreciate any suggestion or ideas how can be this problem resolved.
var ClientBuilder = Java.type("javax.ws.rs.client.ClientBuilder")
var Platform = Java.type("javafx.application.Platform")
var Executors = Java.type("java.util.concurrent.Executors")
var Response = Java.type("javax.ws.rs.core.Response")
var String = Java.type("java.lang.String")
var List = Java.type("java.util.ArrayList")
Executors.newSingleThreadExecutor().execute(function () {
print("Calling for category data...")
var categoryData = ClientBuilder
.newClient()
.target(String.format("%s%s", "http://localhost:8080", "/client/action/categories"))
.request()
.get()
if(categoryData.getStatus() == Response.Status.OK.getStatusCode()) {
var categories = JSON.parse(categoryData.readEntity(String.class))
var categoryItems = new List();
for each (var category in categories) {
categoryItems.add(new CategoryItem(category.id, category.category))
}
Platform.runLater(function() {
cmbCategory.getItems().addAll(categoryItems);
});
} else {
print(categoryData.getEntity().toString());
}
})
function CategoryItem(id, name) {
this.id = id;
this.name = name;
this.toString = function () {
return this.name;
}
}
Use the ScriptEngine to retrieve an appropriate string in the cellValueFactory of the ComboBox.
Simplified example
#Override
public void start(Stage primaryStage) throws Exception {
ScriptEngineManager manager = new ScriptEngineManager();
final ScriptEngine engine = manager.getEngineByMimeType("application/javascript");
ComboBox<Object> comboBox = new ComboBox();
comboBox.setCellFactory(c -> new ListCell<Object>() {
#Override
protected void updateItem(Object item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null) {
setText("");
} else {
Bindings bindings = new SimpleBindings();
bindings.put("a", item);
try {
// use script engine to retrieve text
setText(Objects.toString(engine.eval("a.name", bindings)));
} catch (ScriptException ex) {
setText("Error");
}
}
}
});
comboBox.setButtonCell(comboBox.getCellFactory().call(null));
Bindings b = new SimpleBindings();
b.put("cmbCategory", comboBox);
engine.eval("function CategoryItem(id, name) {this.id = id;this.name = name;}\n"
+"var Platform = Java.type(\"javafx.application.Platform\")\n"
+ "var categories = [new CategoryItem(1, 'a'), new CategoryItem(2, 'b'), new CategoryItem(3,'c')]\n"
+ "for each (var category in categories) {cmbCategory.getItems().add(category);}", b);
Scene scene = new Scene(new StackPane(comboBox));
primaryStage.setScene(scene);
primaryStage.show();
}
I don't see the purpose of using JavaScript for this though. Everything you do in the javascript code could be done from java code more efficiently...

How do I create an image of a webpage and save the image to my server using .net?

I have a page that dynamically generates a small html page containing 1 small table w/text. I want to be able to take a picture (png preferable) of that page and save it to my server.
I was previously using a 3rd party solution (ABCdrawHTML2), but I have changed servers and this one does not have it. Is there a way to do it without 3rd party solutions?
This is how I do it using the Windows.Forms WebBrowser:
public class WebSiteThumbnailImage
{
string m_Url;
int m_BrowserWidth, m_BrowserHeight, m_ThumbnailWidth, m_ThumbnailHeight;
Bitmap m_Bitmap = null;
public WebSiteThumbnailImage(string url, int browserWidth, int browserHeight, int thumbnailWidth, int thumbnailHeight)
{
m_Url = url;
m_BrowserWidth = browserWidth;
m_BrowserHeight = browserHeight;
m_ThumbnailWidth = thumbnailWidth;
m_ThumbnailHeight = thumbnailHeight;
}
public Bitmap GenerateWebSiteThumbnailImage()
{
Thread m_thread = new Thread(new ThreadStart(_GenerateWebSiteThumbnailImage));
m_thread.SetApartmentState(ApartmentState.STA);
m_thread.Start();
m_thread.Join();
return m_Bitmap;
}
private void _GenerateWebSiteThumbnailImage()
{
WebBrowser m_WebBrowser = new WebBrowser();
m_WebBrowser.ScrollBarsEnabled = false;
m_WebBrowser.Navigate(m_Url);
m_WebBrowser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(WebBrowser_DocumentCompleted);
while (m_WebBrowser.ReadyState != WebBrowserReadyState.Complete)
Application.DoEvents();
m_WebBrowser.Dispose();
}
private void WebBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
WebBrowser m_WebBrowser = (WebBrowser)sender;
m_WebBrowser.ClientSize = new Size(this.m_BrowserWidth, this.m_BrowserHeight);
m_WebBrowser.ScrollBarsEnabled = false;
m_Bitmap = new Bitmap(m_WebBrowser.Bounds.Width, m_WebBrowser.Bounds.Height);
m_WebBrowser.BringToFront();
m_WebBrowser.DrawToBitmap(m_Bitmap, m_WebBrowser.Bounds);
m_Bitmap = (Bitmap)m_Bitmap.GetThumbnailImage(m_ThumbnailWidth, m_ThumbnailHeight, null, IntPtr.Zero);
}
}
To use this, at the appropriate place in your code-behind, do something like:
WebSiteThumbnailImage thumbnail = new WebSiteThumbnailImage(url, 1000, 1000, 200, 200);
Bitmap image = thumbnail.GenerateWebSiteThumbnailImage();
image.Save(filePath);

Resources