问题
I'm using below code in my chat applicaiton where it uses RealTime Firebase Data base to chat among users.
I would like to use an notification sound when new message arrives and also have an option on toolbar to turn it off or on.
Is it possible.
Here is the code of Chat_Room
package com.nepalpolice.mnemonics.chat;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import com.google.firebase.database.ChildEventListener;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.nepalpolice.mnemonics.R;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/**
* Created by filipp on 6/28/2016.
*/
public class Chat_Room extends AppCompatActivity{
private Button btn_send_msg;
private EditText input_msg;
private TextView chat_conversation;
private Toolbar mainToolbar;
private String user_name,room_name;
private DatabaseReference root ;
private String temp_key;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.chat_room);
btn_send_msg = (Button) findViewById(R.id.btn_send);
input_msg = (EditText) findViewById(R.id.msg_input);
chat_conversation = (TextView) findViewById(R.id.textView);
user_name = getIntent().getExtras().get("user_name").toString();
room_name = getIntent().getExtras().get("room_name").toString();
mainToolbar = (Toolbar) findViewById(R.id.main_chat);
setSupportActionBar(mainToolbar);
getSupportActionBar().setTitle(" Room - "+room_name);
root = FirebaseDatabase.getInstance().getReference().child(room_name);
btn_send_msg.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Map<String,Object> map = new HashMap<String, Object>();
temp_key = root.push().getKey();
root.updateChildren(map);
DatabaseReference message_root = root.child(temp_key);
Map<String,Object> map2 = new HashMap<String, Object>();
map2.put("name",user_name);
map2.put("msg",input_msg.getText().toString());
message_root.updateChildren(map2);
input_msg.getText().clear();
}
});
root.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
append_chat_conversation(dataSnapshot);
}
@Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
append_chat_conversation(dataSnapshot);
}
@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
@Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
private String chat_msg,chat_user_name;
private void append_chat_conversation(DataSnapshot dataSnapshot) {
Iterator i = dataSnapshot.getChildren().iterator();
while (i.hasNext()){
chat_msg = (String) ((DataSnapshot)i.next()).getValue();
chat_user_name = (String) ((DataSnapshot)i.next()).getValue();
chat_conversation.append(chat_user_name +" : "+chat_msg +" \n");
}
}
public static boolean isNetworkStatusAvialable (Context context) {
ConnectivityManager cm =
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
return activeNetwork != null &&
activeNetwork.isConnectedOrConnecting();
}
}
and my Firebase Data Structure is
Firebase Data Structure Image
Thanks in advance.
my Mainactivity file is
package com.nepalpolice.mnemonics.chat;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.graphics.Typeface;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import com.nepalpolice.mnemonics.R;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import static java.security.AccessController.getContext;
public class MainActivity extends AppCompatActivity {
ProgressBar progressBar;
private Toolbar mainToolbar;
private Button add_room;
private EditText room_name;
public static final String MyPREFERENCES = "MyPrefs" ;
public static final String username = "userKey";
SharedPreferences sharedpreferences;
private ListView listView;
private ArrayAdapter<String> arrayAdapter;
private ArrayList<String> list_of_rooms = new ArrayList<>();
private String name;
private DatabaseReference root = FirebaseDatabase.getInstance().getReference().getRoot();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
mainToolbar = (Toolbar) findViewById(R.id.main_chatbar);
setSupportActionBar(mainToolbar);
getSupportActionBar().setTitle("Chat Rooms");
progressBar= (ProgressBar) findViewById(R.id.webViewProgressfaq);
add_room = (Button) findViewById(R.id.btn_add_room);
room_name = (EditText) findViewById(R.id.room_name_edittext);
listView = (ListView) findViewById(R.id.listView);
sharedpreferences = getSharedPreferences(MyPREFERENCES, Context.MODE_PRIVATE);
arrayAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,list_of_rooms);
listView.setAdapter(arrayAdapter);
add_room.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Map<String,Object> map = new HashMap<String, Object>();
map.put(room_name.getText().toString(),"");
root.updateChildren(map);
}
});
if(isNetworkStatusAvialable (getApplicationContext())) {
request_user_name();
root.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
Set<String> set = new HashSet<String>();
Iterator i = dataSnapshot.getChildren().iterator();
while (i.hasNext()) {
set.add(((DataSnapshot) i.next()).getKey());
}
list_of_rooms.clear();
list_of_rooms.addAll(set);
arrayAdapter.notifyDataSetChanged();
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}else{
Toast.makeText(getBaseContext(), "You're Offline!", Toast.LENGTH_SHORT).show();
progressBar.setVisibility(View.VISIBLE);
}
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Intent intent = new Intent(getApplicationContext(),Chat_Room.class);
intent.putExtra("room_name",((TextView)view).getText().toString() );
intent.putExtra("user_name",name);
startActivity(intent);
}
});
}
private void request_user_name() {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Enter name:");
final EditText input_field = new EditText(this);
input_field.setText(sharedpreferences.getString("username",""));
final SharedPreferences.Editor editor = sharedpreferences.edit();
builder.setCancelable(false);
builder.setView(input_field);
final String savedName = sharedpreferences.getString(username,"");
input_field.setText(savedName);
input_field.setSelection(input_field.getText().length());
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
name = input_field.getText().toString();
if(TextUtils.isEmpty(savedName)) {
input_field.setError("Your message");
builder.setCancelable(false);
}
editor.putString(username, name);
editor.apply();
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
if(TextUtils.isEmpty(savedName)) {
input_field.setError("Your message");
builder.setCancelable(false);
}
else
{
dialogInterface.cancel();
request_user_name();
}
}
});
builder.show();
}
public static boolean isNetworkStatusAvialable (Context context) {
ConnectivityManager cm =
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
return activeNetwork != null &&
activeNetwork.isConnectedOrConnecting();
}
}
回答1:
You should add FirebaseMessaging for notifications. And set sound when notification recieve. refer this link. It will help. Also learn how to use firebase functions. Firebase functions will help you to triger the realtime database from cloud to android. Firebase functions
回答2:
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("Notifications Example")
.setContentText("This is a test notification");
Intent notificationIntent = new Intent(this, MenuScreen.class);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(contentIntent);
builder.setAutoCancel(true);
builder.setLights(Color.BLUE, 500, 500);
long[] pattern = {500,500,500,500,500,500,500,500,500};
builder.setVibrate(pattern);
builder.setStyle(new NotificationCompat.InboxStyle());
builder.setSound(Settings.System.DEFAULT_NOTIFICATION_URI)
NotificationManager manager = (NotificationManager)
getSystemService(Context.NOTIFICATION_SERVICE);
manager.notify(1, builder.build());
回答3:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
notificationBuilder = new NotificationCompat.Builder(this, "")
.setColor(context.getResources().getColor(R.color.colorGreen))
.setContentText(body)
.setSmallIcon(R.drawable.white_logo)
.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.mipmap.ic_launcher))
.setStyle(new NotificationCompat.BigPictureStyle().bigPicture(image).setSummaryText(body))
.setContentTitle(title + "\n")
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setAutoCancel(true)
.setSound(defaultSoundUri);
} else {
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
notificationBuilder = new NotificationCompat.Builder(this, "")
.setSmallIcon(R.drawable.white_logo)
.setStyle(new NotificationCompat.BigPictureStyle().bigPicture(image).setSummaryText(body))/*Notification with Image*/
.setContentTitle(title + "\n")
.setContentText(body)
.setAutoCancel(true)
.setSound(defaultSoundUri);
}
}
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
回答4:
You could use a radioButton,listen to its state then save it to SharedPreference
. Heres how
SharedPreferences.Editor editor = getSharedPreferences("MyApp", MODE_PRIVATE).edit();
editor.putBoolean("allowNotification", radioButton.isChecked());
editor.apply();
and to read preference
SharedPreferences prefs = getSharedPreferences("MyApp", MODE_PRIVATE);
boolean allowNOtific = prefs.getBoolean("allowNotification", false);
radioButton.setChecked(allowNOtific);
and to create and sound notification, and allow it as clickable link to your activity
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent resultIntent = PendingIntent.getActivity(this, 0, intent,
PendingIntent.FLAG_ONE_SHOT);
Uri notificationSoundURI = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder mNotificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(subject)
.setContentText(object.getString("body"))
.setAutoCancel(true)
.setSound(notificationSoundURI)
.setContentIntent(resultIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, mNotificationBuilder.build());
ToneGenerator toneG = new ToneGenerator(AudioManager.STREAM_ALARM, ToneGenerator.MAX_VOLUME);
toneG.startTone(ToneGenerator.TONE_CDMA_HIGH_L, 3000);
((Vibrator)getSystemService(VIBRATOR_SERVICE)).vibrate(2000);
Note: Vibrate need this permission
<uses-permission android:name="android.permission.VIBRATE" />
Hope this helps
Edit:
The error is in Chat_Room so basically it is considered different question. My suspect is that your .hasNext()
still returns true which causes the error. I havent tried such approach so im not sure. How about you try my approach, heres a sample code
for (DataSnapshot messageThread : dataSnapshot.getChildren()) {
String lastMessage = (String) messageThread.child("lastMessage").getValue();
}
来源:https://stackoverflow.com/questions/49809499/how-to-sound-notifications-sound-when-new-message-arrives-from-firebase-realtime