Send a Message Dialog to a another user - java

In my activity a user is shown another user based around various criteria. I am trying to figure out a way to alert that the other user that this individual has selected him upon the current user button click. I am thinking that once the user has click on the confirm button, an alert dialog message would be displayed to the user so that he is aware that someone has click confirm on him.
I am using Parse to manage the users, and the below is the code that would display a user based around various criteria.
query1.findInBackground(new FindCallback<ParseUser>() {
#Override
public void done(List<ParseUser> objects,ParseException e) {
if (e == null) {
for(int i = 0; i < objects.size(); i++){
// Do whatever you need to extract object from "users"
ParseQuery<ParseObject> query1 = ParseQuery.getQuery("User");
query1.whereNotEqualTo("objectId", ParseUser.getCurrentUser().
getObjectId());
Button buttonconfirm = (Button) getView().
findViewById(R.id.btnMatchConfirm);
buttonconfirm.setText("Confirm");
mUserNameRetrieved = (TextView) getActivity().
findViewById(R.id.userlistname);
mUserNameRetrieved.setText(objects.get(i).get("Name").toString());
Button newPage = (Button)getView().
findViewById(R.id.btnMatchConfirm);
newPage.setVisibility(View.VISIBLE);
newPage.setText("Confirm");
newPage.setTextSize(TypedValue.COMPLEX_UNIT_SP, 30);
newPage.setTextColor(Color.parseColor("#ff0000"));
newPage.setBackgroundColor(Color.TRANSPARENT);
ViewGroup.LayoutParams params = newPage.getLayoutParams();
params.height = ViewGroup.LayoutParams.WRAP_CONTENT;
params.width = ViewGroup.LayoutParams.WRAP_CONTENT;
newPage.setLayoutParams(params);
newPage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// ParseUser currentUser = ParseUser.getCurrentUser();
// currentUser.put("UserMatchName", mUserRetrieved);
Intent intent = new Intent(getActivity(),
OptionActivity.class);
startActivity(intent);
}
});
}
} else if (e != null) {
}
}
});
I am not sure where to go from here, and any clarification would be greatly appreciated.
Thanks in advance.

If you already using Parse, you should use their Push notifications. Register receivers with a channel for each user.
When a user selects another, notify your parse back-end and then from the back-end send push filtered by the selected channel.
See more :
https://parse.com/docs/android_guide#push

Related

How to check if a given package is disabled or not and then show toast message accordingly?

I'm making an app where it uses intent to send data to another app. In case, the other app, which is supposed to receive data from my app, is not installed on users's device then it redirects user to play store with toast message asking user to install it. I used "if else" to achieve this. It worked all good until I found that if the other app is disabled by user (OEM installed app which can't be uninstalled), then my app crashes. In such a condition, I want to let user know that the app is disabled by them and ask them to enable it (through toast message). How can I achieve this?
Here is my complete code:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Creates button view which is connected to a view in the XML layout, which gets triggered on touching the view.
TextView textView = (TextView) findViewById(R.id.location);
textView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Use package name which we want to check
boolean isAppInstalled = appInstalledOrNot("com.google.android.apps.maps");
if(isAppInstalled){
Uri gmmIntentUri = Uri.parse("geo:00,0000,00,0000");
Intent mapIntent = new Intent(Intent.ACTION_VIEW, gmmIntentUri);
mapIntent.setPackage("com.google.android.apps.maps");
startActivity(mapIntent);
} else {
Uri uri2 = Uri.parse("market://details?id=com.google.android.apps.maps");
Intent goToMarket = new Intent(Intent.ACTION_VIEW, uri2);
Toast.makeText(MainActivity.this, "Google Maps not Installed", Toast.LENGTH_SHORT).show();
startActivity(goToMarket);
}
}
});
}
private boolean appInstalledOrNot(String uri) {
PackageManager pm = getPackageManager();
try {
pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES);
return true;
} catch (PackageManager.NameNotFoundException e) {
}
return false;
}
}
I'm not sure if this will work for you, but since you know the package name, you could try this to do a check beforehand.

How can I add a data to the another activity in a Button form

I'm making an android POS and I have a problem to add a data pass to other activity. When the user is adding a new product, the product will show on the Menu activity in the Button form and has a value whatever the user input in the name and price.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_addproduct);
POSDB = new DatabaseHelper(this);
prdName = (EditText)findViewById(R.id.PrdName);
prdPrice = (EditText) findViewById(R.id.PrdPrice);
btnAdd = (Button) findViewById(R.id.BtnPrdAdd);
btnBack = (Button) findViewById(R.id.BtBack);
AddProduct();
}
public void AddProduct(){
btnAdd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String name = prdName.getText().toString().trim();
String price = prdPrice.getText().toString().trim();
if(prdName.length() != 0 && prdPrice.length() != 0)
{
boolean ADD = POSDB.addData(name,price);
if(ADD == true)
{Toast.makeText(Addproduct.this, " The product has been added", Toast.LENGTH_LONG).show();}
else
{Toast.makeText(Addproduct.this, " Something Went Wrong", Toast.LENGTH_LONG).show();}
}
else
{Toast.makeText(Addproduct.this, " Please fill up the Textfield", Toast.LENGTH_LONG).show();}
}
});
}
That depends on how do you structure the Menu Activity to get the data and how it shows it.
For example, If you are using a RecyclerView you can set it to show the data in a list of buttons, so when a new product added to the database it will be shown by RecyclerView in the button form.

One button for 2 different actions

I have "send" Button inside dialogFragment that onClick event push new data to firebase under key value.
I want this button to be also like an "update" button when the user click on particular button. the data will update in firebase under the same key value as before.
This is the send button onClick method:
send_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//some code .....//
DatabaseReference newPost = mDatabase.push();
str_key = newPost.getKey();
trempData = new TrempData(str_key, str_uid, str_name, str_phone, str_from, str_to, str_date, str_time, str_extra, str_timestamp);
newPost.setValue(trempData);
Toast.makeText(getActivity(), "Tremp Added", Toast.LENGTH_SHORT).show();
dismiss();
}
});
Any suggestions?
More important than the implementation is the way you think it can be done. So, the basic approach in these cases is to use a boolean variable.
Why? Because it can be used to indicate if the button is in a particular state or not.
So, you can do something like this.
boolean b=false;
//set your button in the initial state you want(submit in your case)
//In onClick() method
if(!b){ //button in submit state
b=true;
//do submit stuff
send_btn.setText("update");
}
else{ //button in update state
b=false;
//do update stuff
send_btn.setText("submit");
}
In this case, true value of b indicates that the button is in "update" state.
This is an Example :
private final int BUTTON_UPDATE = 1;
private final int BUTTON_SEND = 2;
private int buttonStatus = 0;
send_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
switch(buttonStatus)
{
case BUTTON_UPDATE: { // your update code here}
case BUTTON_SEND : { // your send code here
}
the buttonStatus will control what operation the button will do.
Put a boolean in sharedPrefrences and keep to false initially when
user sends data to firebase update boolean to true.
in onClick check if the value is true or false using if else and
execute code accordingly
You can use the tag of the view for this and update the state as your need
Button button = findViewById(R.id.btn);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (button.getTag().equals("send")) {
// push the value to firebase
// set the tag to update and the text
button.setTag("update");
button.setText("update");
}else if (button.getTag().equals("update")){
// update the value in firebase
}
}
});
xml
<Button
android:id="#+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:tag="send"
android:text="send" />

not able to retrieve string from parse database with query

I'm trying to retrieve a information from a parse object but the strings I store them in keep equaling null.
Here is how I saved the object
// get current user
ParseObject studentClasses = new ParseObject("StudentClasses");
// register their periods into database
studentClasses.put("student_id", ParseUser.getCurrentUser());
studentClasses.put("first_period", ClassSelected_Period[PERIOD1]);
studentClasses.put("second_period", ClassSelected_Period[PERIOD2]);
studentClasses.put("third_period", ClassSelected_Period[PERIOD3]);
studentClasses.put("fourth_period", ClassSelected_Period[PERIOD4]);
studentClasses.put("fifth_period", ClassSelected_Period[PERIOD5]);
studentClasses.put("sixth_period", ClassSelected_Period[PERIOD6]);
studentClasses.put("seventh_period", ClassSelected_Period[PERIOD7]);
// save the information into database
studentClasses.saveInBackground();
It saves it perfectly fine my database. The student_id is a pointer to the user and the rest of the columns are strings.
I want to retrieve all those strings and put them in an array when I query parse for them it doesn't work
Here is my query
// check if a user is not cached
ParseUser currentUser = ParseUser.getCurrentUser();
if (currentUser == null)
{
// prompt user to Register screen
// create intent to start activity
Intent intent = new Intent(MainActivity.this, RegisterActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
// start new activity
startActivity(intent);
// stop current activity
finish();
}
// query database for user's classes
ParseQuery<ParseObject> query = ParseQuery.getQuery("StudentClasses");
query.whereEqualTo("student_id", ParseUser.getCurrentUser());
query.getFirstInBackground(new GetCallback<ParseObject>()
{
#Override
public void done (ParseObject parseObject, ParseException e)
{
if (e == null)
{
// retrieved the object
userClasses[PERIOD1] = parseObject.getString("first_period");
userClasses[PERIOD2] = parseObject.getString("second_period");
userClasses[PERIOD3] = parseObject.getString("third_period");
userClasses[PERIOD4] = parseObject.getString("fourth_period");
userClasses[PERIOD5] = parseObject.getString("fifth_period");
userClasses[PERIOD6] = parseObject.getString("sixth_period");
userClasses[PERIOD7] = parseObject.getString("seventh_period");
}
else
{
// failed lookup. Do something here
Toast.makeText(getApplicationContext(),"Exception Thrown" ,Toast.LENGTH_SHORT).show();
}
}
});
I looked at the parse docs and it looks like it should work but it doesn't save the strings
Any help or comments is appreciated thanks!
EDIT: I showed more of my code for the query part to show there is a current user
Here i am assuming that, there is data stored in your parse database.. and it works fine.. so to retrieve it try following..
ParseQuery<ParseObject> query = ParseQuery.getQuery("StudentClasses");
query.whereEqualTo("student_id", ParseUser.getCurrentUser());
query.findInBackground(new FindCallback<ParseObject>()
{
#Override
public void done (List<ParseObject> list, ParseException e)
{
if (e == null)
{
for(int i=0; i < list.size(); i++) {
userClasses[PERIOD1] = list.get(i).getString("first_period");
userClasses[PERIOD2] = list.get(i).getString("second_period");
userClasses[PERIOD3] = list.get(i).getString("third_period");
userClasses[PERIOD4] = list.get(i).getString("fourth_period");
userClasses[PERIOD5] = list.get(i).getString("fifth_period");
userClasses[PERIOD6] = list.get(i).getString("sixth_period");
userClasses[PERIOD7] = list.get(i).getString("seventh_period");
}
}
else
{
Toast.makeText(getApplicationContext(),"Exception Thrown" ,Toast.LENGTH_SHORT).show();
}
}
});
hope it helps!
Well try when getting content to use the function
parseObject.get("the_name_of_the_column")
Which actually should work and works fine for me
Here what you need to understand is in your code studentClasses.saveInBackground(); is async call and you need to query inside SaveCallback. Then you can assure that the saved data is in the database when your query runs.
You got null data because you query before the data is saved in parse.
ParseObject studentClasses = new ParseObject("StudentClasses");
// register their periods into database
studentClasses.put("student_id", ParseUser.getCurrentUser());
studentClasses.put("first_period", ClassSelected_Period[PERIOD1]);
studentClasses.put("second_period", ClassSelected_Period[PERIOD2]);
studentClasses.put("third_period", ClassSelected_Period[PERIOD3]);
studentClasses.put("fourth_period", ClassSelected_Period[PERIOD4]);
studentClasses.put("fifth_period", ClassSelected_Period[PERIOD5]);
studentClasses.put("sixth_period", ClassSelected_Period[PERIOD6]);
studentClasses.put("seventh_period", ClassSelected_Period[PERIOD7]);
// save the information into database
studentClasses.saveInBackground(new SaveCallback() {
public void done(ParseException e) {
if (e == null) {
ParseQuery<ParseObject> query = ParseQuery.getQuery("StudentClasses");
query.whereEqualTo("student_id", ParseUser.getCurrentUser());
query.getFirstInBackground(new GetCallback<ParseObject>()
{
#Override
public void done (ParseObject parseObject, ParseException e)
{
if (e == null)
{
// retrieved the object
userClasses[PERIOD1] = parseObject.getString("first_period");
userClasses[PERIOD2] = parseObject.getString("second_period");
userClasses[PERIOD3] = parseObject.getString("third_period");
userClasses[PERIOD4] = parseObject.getString("fourth_period");
userClasses[PERIOD5] = parseObject.getString("fifth_period");
userClasses[PERIOD6] = parseObject.getString("sixth_period");
userClasses[PERIOD7] = parseObject.getString("seventh_period");
}
else
{
// failed lookup. Do something here
Toast.makeText(getApplicationContext(),"Exception Thrown" ,Toast.LENGTH_SHORT).show();
}
}
});
} else {
// myObjectSaveDidNotSucceed();
}
}
});
Hope this helps
After getting some sleep then doing more research and tinkering I found the problem. The problem isn't in my code; it's in my network... well not entirely. You see my code runs ... at well run-time (As fast as my phone can process it); however, the method
query.findInBackground(new FindCallback<ParseObject>()
runs asynchronously meaning that it does not run at the speed of my other code. Which makes sense if you think about it because it has to send and wait for a response from a database. That's why when I made a toast inside it, the data was there in the string but when I tried to make a toast a few lines later, outside of the method, the data was not there. It was null.
Here's an example. I make a toast at the end of on create with this code
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// initialise and set toolbar as actionbar
toolbar = (Toolbar) findViewById(R.id.tool_bar);
setSupportActionBar(toolbar);
// initialize nav bars
initNavBars();
// initialize drawer layout
NavigationView navView = (NavigationView) findViewById(R.id.navigation_view);
// initialize nav drawer
navDrawer = (DrawerLayout) findViewById(R.id.drawer);
initNavDrawer(navDrawer);
// initialize layout manager for recycler view
RecyclerView.LayoutManager mainLayoutManager = new LinearLayoutManager(this);
// initialize data for all classes before setting adapter
initClassData(); // <---- MY PARSE QUERY IS IN THIS METHOD
// set the adapter for recycler view
RecyclerView.Adapter mainAdapter = new MainRecyclerAdapter(classrooms);
// initialize recycler view elements
RecyclerView mainRecyclerView = (RecyclerView) findViewById(R.id.main_recycler_view);
// add layout manager to recycler view
mainRecyclerView.setLayoutManager(mainLayoutManager);
// add adapter to recycler view
mainRecyclerView.setAdapter(mainAdapter);
Toast.makeText(getApplicationContext(), userClasses[PERIOD1], Toast.LENGTH_SHORT).show(); // <----- HERE IS MY TOAST
}
When I run it, the toast is empty because the string is still null, but if I run it with this code
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// initialise and set toolbar as actionbar
toolbar = (Toolbar) findViewById(R.id.tool_bar);
setSupportActionBar(toolbar);
// initialize nav bars
initNavBars();
// initialize drawer layout
NavigationView navView = (NavigationView) findViewById(R.id.navigation_view);
// initialize nav drawer
navDrawer = (DrawerLayout) findViewById(R.id.drawer);
initNavDrawer(navDrawer);
// initialize layout manager for recycler view
RecyclerView.LayoutManager mainLayoutManager = new LinearLayoutManager(this);
// initialize data for all classes before setting adapter
initClassData(); // <---- PARSE QUERY IS STILL IN THIS METHOD
// set the adapter for recycler view
RecyclerView.Adapter mainAdapter = new MainRecyclerAdapter(classrooms);
// initialize recycler view elements
RecyclerView mainRecyclerView = (RecyclerView) findViewById(R.id.main_recycler_view);
// add layout manager to recycler view
mainRecyclerView.setLayoutManager(mainLayoutManager);
// add adapter to recycler view
mainRecyclerView.setAdapter(mainAdapter);
final Handler handler = new Handler();
handler.postDelayed(new Runnable()
{
#Override
public void run()
{
// Do something after 5s = 5000ms
Toast.makeText(getApplicationContext(), userClasses[PERIOD1], Toast.LENGTH_SHORT).show();
}
}, 5000);
}
In this example I forced the toast to wait five seconds to allow
query.getFirstInBackground(new GetCallback<ParseObject>()
to finish querying the database and when I run it, the toast displays the string correctly.
So if your program relies on a parse query to get important data, you have to structure your code in a way to allow for a second or two to pass to let the parse query return.
Or you could alternatively store the data locally and then you can use the database as a backup for the data and check to make sure it is the same every time the user wants to switch it or somethings.
Thank you Ajay and Rasika I would still be trying to figure why it was not working if it weren't you.

how to use run runOnUithread?

The app I am working on has a login/register which connects to a mysql database, At first I was running everything on the UI Thread I later found out it was not working because of the against running long code on Android's UI Thread. I attempted to edit my code to run the long task on a new Thread that i added.
. Now my app registers the I see the result in mysql but my app keeps closing because of this error
android.view.ViewRootImpl$CalledFromWrongThreadException:
Only the original thread that created a view hierarchy can touch its views.
the error is understandable but I don't know how to run the View or Views back to the UI Thread.
I've done some research about the runOnuithread but I dont know where to place it in my code, or weather I placed the new Thread I added before in the wrong place to begin with please
can anyone help my fix this
here is a snippet of the code
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.register);
// Importing all assets like buttons, text fields
inputFullName = (EditText) findViewById(R.id.registerName);
inputEmail = (EditText) findViewById(R.id.registerEmail);
inputPassword = (EditText) findViewById(R.id.registerPassword);
btnRegister = (Button) findViewById(R.id.btnRegister);
btnLinkToLogin = (Button) findViewById(R.id.btnLinkToLoginScreen);
registerErrorMsg = (TextView) findViewById(R.id.register_error);
// Register Button Click event
btnRegister.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
/** According with the new StrictGuard policy, running long tasks on the Main UI thread is not possible
So creating new thread to create and execute http operations */
new Thread (new Runnable() {
#Override
public void run() {
//
String name = inputFullName.getText().toString();
String email = inputEmail.getText().toString();
String password = inputPassword.getText().toString();
UserFunctions userFunction = new UserFunctions();
JSONObject json = userFunction.registerUser(name, email, password);
// check for login response
try {
//
//
if (json.getString(KEY_SUCCESS) != null) {
registerErrorMsg.setText("");
String res = json.getString(KEY_SUCCESS);
if(Integer.parseInt(res) == 1){
// user successfully registred
// Store user details in SQLite Database
DatabaseHandler db = new DatabaseHandler(getApplicationContext());
JSONObject json_user = json.getJSONObject("user");
// Clear all previous data in database
userFunction.logoutUser(getApplicationContext());
db.addUser(json_user.getString(KEY_NAME), json_user.getString(KEY_EMAIL), json.getString(KEY_UID), json_user.getString(KEY_CREATED_AT));
// Launch Dashboard Screen
Intent dashboard = new Intent(getApplicationContext(), MainActivity.class);
// Close all views before launching Dashboard
dashboard.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(dashboard);
// Close Registration Screen
finish();
}else{
// Error in registration
registerErrorMsg.setText("Error occured in registration");
}
}//
} catch (JSONException e) {
e.printStackTrace();
}
}
}).start();
}
});
// Link to Login Screen
btnLinkToLogin.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Intent i = new Intent(getApplicationContext(),
LoginActivity.class);
startActivity(i);
// Close Registration View
finish();
}
});
}
}
Since you seem to have network code mixed in with UI code, I'm not going to try and write it for you. I can tell you how it should be and assume that you can rearrange the code yourself since you know what all of it does.
Ok, inside your run() you put your network code then when you need to update the UI you can have
runOnUiThread(new Runnable()
{
#Override
public void run()
{
// code to update UI
}
});
With that said, I recommend using AsyncTask for your network operations. This makes it much easier as it already has the functions for background stuff and updating the UI. You start the task and doInBackground() runs and that is where you do all of your network operations. Then you can update the UI in any of AsyncTasks other 3 methods.
See this answer for an example of using AsyncTask, along with the link to the docs above.

Categories