1

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 enter image description here

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();

    }
}
Raj Lama
  • 23
  • 7

4 Answers4

0
    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());  
hasan_shaikh
  • 1,434
  • 1
  • 15
  • 38
  • @hasan_shaikh...I used your method but it dispalys the notification but when I click it then app crashes with belwo logcat https://ibb.co/hRVGhS and my chat structure from app is like this https://ibb.co/cMQA97. Please have a look. – Raj Lama Apr 13 '18 at 05:26
  • its crashing because of the data in your chat.java i guess. It is not because of notification. Check where it is crashing. – hasan_shaikh Apr 13 '18 at 06:05
  • @hasan_shaikh..I have edited my question and added both chat room and Mainactivity code posted. Please have a look ..I followed one youtube tutorial and build my app..so I have no brief idea about the arrayadapter or cause of it..I have also posted the logcat error...hope it will be helpful. Thanks – Raj Lama Apr 13 '18 at 06:07
  • in append_chat_conversation(DataSnapshot dataSnapshot) check if data is present or not – hasan_shaikh Apr 13 '18 at 06:11
0

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

SHIJO CS
  • 64
  • 1
  • 13
0
   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());
dev
  • 260
  • 2
  • 12
  • i think the code is not complete when I pasted it it throws me error. – Raj Lama Apr 13 '18 at 05:28
  • You should add other methods to builder like setContent,style etc..and add it to Notifcationmanager.notify(..) – dev Apr 13 '18 at 05:30
  • i did and also received notification but when I open it throws me error of java.lang.ArrayIndexOutOfBoundsException: length=3; index=3, here is the image file of logcat https://ibb.co/hRVGhS and my chat application is https://ibb.co/cMQA97...Please have a look. – Raj Lama Apr 13 '18 at 05:48
  • From the error stack, I feel that you have an Array, which contains only 3 elements.so length is 3. index starts from 0 then 1 and 2. you may be using some for loop where u checks to position 3, stop looping at position (length-1). – dev Apr 13 '18 at 05:53
  • I hope so dev..I have also added my Mainactivity file which contains array ..Please have a look if I have made any mistake in there.....I am very new to android and this code I go from youtube tutorial ..so I have no idea if there is any loop or how to stop it. – Raj Lama Apr 13 '18 at 05:58
  • Please post ChatRoom.java also – dev Apr 13 '18 at 06:03
  • the first code is from ChatRoom.now I have edited my question and labelled it as Chat_Room code. Please have a look. – Raj Lama Apr 13 '18 at 06:05
  • Remove your Iterator code; iterate using for loop. In your append_chat_conversation(DataSnapshot dataSnapshot) method; use like this: for (int i=0;i – dev Apr 13 '18 at 06:32
  • I would really like to learn about the coding as for now I'm learning from youtube and blogs......as you have suggested to use (int i=0;i – Raj Lama Apr 13 '18 at 11:45
  • check this,https://stackoverflow.com/questions/6700717/arrayindexoutofboundsexception-when-using-the-arraylists-iterator replace your iterator with for loop – dev Apr 13 '18 at 11:46
  • thanks dev I resolve that problem but now, when I open the chat activity for first time then only it sets off the alarm and vibration but then after when new message arrive it does nothing. – Raj Lama Apr 13 '18 at 12:25
  • when you are inside your app Notification behaves like that only,you are already inside, why again notify – dev Apr 13 '18 at 12:31
  • so is there any way when app is not running, then sound the notificaiton to alert the user? – Raj Lama Apr 13 '18 at 12:32
  • it should be managed from backend https://stackoverflow.com/questions/44847835/android-fcm-not-receiving-notifications-when-app-is-removed-from-background – dev Apr 13 '18 at 12:35
0

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();
} 
Android_K.Doe
  • 753
  • 1
  • 4
  • 11
  • Thanks @Android_K Doe, I was looking for same but now i did however sucessfully build and compiled the app and when I received notification but when I open it throws me error of java.lang.ArrayIndexOutOfBoundsException: length=3; index=3, here is the image file of logcat https://ibb.co/hRVGhS and my chat application is https://ibb.co/cMQA97 – Raj Lama Apr 13 '18 at 05:49
  • I have also my Mainactivity with array list..Please have a look if error is from same. – Raj Lama Apr 13 '18 at 05:59
  • Doe..should I replace the content after .hasNext() with your code?? – Raj Lama Apr 13 '18 at 11:48
  • Replace the whole `append_chat_conversation` content with a `for` each loop – Android_K.Doe Apr 16 '18 at 00:43