I am new to Android Studio and intelliJ.
I am trying to work with AmazonSNS - Push. I am unable to figure out how to add AwsCredentials.properties file to classpath of the module. I get a NPE at line 57 in the image below(at method getResourceAsStream()). I added the required keys in AwsCredentials.properties file.
Error:
In the questions that i have come across on StackOverflow regarding similar issues, some suggested that the file should be in the root folder, where, src is. I placed it in the same folder as that of src, but still getting the NPE. I also tried placing the file in com/test/ but with no use.
How do i solve this? Are there any other steps involved?
EDIT after starting a bounty - Adding java files
Here is what i did till now..
Create an Android Application called MyApplication. Imported all classes(AndroidMobilePushApp.java, ExternalReceiver.java, MessageReceivingService.java) from the demo application. Added required libs, and ran it and got the registationId as response from Amazon.
In the same application, i created a new module called snspush and imported SNSMobilePush.java file into it. Also imported the AwsCredentials.properties file to the same path as that of SNSMobilePush.java. Added the keys in AwsCredentials.properties file.
Followed the steps in documentation to uncomment necessary funtions.
Project Structure:
Java files:
AndroidMobilePushApp.java:
public class AndroidMobilePushApp extends AppCompatActivity {
private TextView tView;
private SharedPreferences savedValues;
private String numOfMissedMessages;
// Since this activity is SingleTop, there can only ever be one instance. This variable corresponds to this instance.
public static Boolean inBackground = true;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
numOfMissedMessages = getString(R.string.num_of_missed_messages);
setContentView(R.layout.activity_main);
tView = (TextView) findViewById(R.id.tViewId);
tView.setMovementMethod(new ScrollingMovementMethod());
startService(new Intent(this, MessageReceivingService.class));
}
public void onStop(){
super.onStop();
inBackground = true;
}
public void onRestart(){
super.onRestart();
tView.setText("");;
}
public void onResume(){
super.onResume();
inBackground = false;
savedValues = MessageReceivingService.savedValues;
int numOfMissedMessages = 0;
if(savedValues != null){
numOfMissedMessages = savedValues.getInt(this.numOfMissedMessages, 0);
}
String newMessage = getMessage(numOfMissedMessages);
if(newMessage!=""){
Log.i("displaying message", newMessage);
tView.append(newMessage);
}
}
public void onNewIntent(Intent intent){
super.onNewIntent(intent);
setIntent(intent);
}
// If messages have been missed, check the backlog. Otherwise check the current intent for a new message.
private String getMessage(int numOfMissedMessages) {
String message = "";
String linesOfMessageCount = getString(R.string.lines_of_message_count);
if(numOfMissedMessages > 0){
String plural = numOfMissedMessages > 1 ? "s" : "";
Log.i("onResume","missed " + numOfMissedMessages + " message" + plural);
tView.append("You missed " + numOfMissedMessages +" message" + plural + ". Your most recent was:\n");
for(int i = 0; i < savedValues.getInt(linesOfMessageCount, 0); i++){
String line = savedValues.getString("MessageLine"+i, "");
message+= (line + "\n");
}
NotificationManager mNotification = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotification.cancel(R.string.notification_number);
SharedPreferences.Editor editor=savedValues.edit();
editor.putInt(this.numOfMissedMessages, 0);
editor.putInt(linesOfMessageCount, 0);
editor.commit();
}
else{
Log.i("onResume","no missed messages");
Intent intent = getIntent();
if(intent!=null){
Bundle extras = intent.getExtras();
if(extras!=null){
for(String key: extras.keySet()){
message+= key + "=" + extras.getString(key) + "\n";
}
}
}
}
message+="\n";
return message;
}
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId() == R.id.menu_clear){
tView.setText("");
return true;
}
else{
return super.onOptionsItemSelected(item);
}
}
}
ExternalReceiver.java
package com.test.awstestapp;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
public class ExternalReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
if(intent!=null){
Bundle extras = intent.getExtras();
if(!AndroidMobilePushApp.inBackground){
MessageReceivingService.sendToApp(extras, context);
}
else{
MessageReceivingService.saveToLog(extras, context);
}
}
}
}
MessageReceivingService.java
public class MessageReceivingService extends Service{
private GoogleCloudMessaging gcm;
public static SharedPreferences savedValues;
public static void sendToApp(Bundle extras, Context context){
Intent newIntent = new Intent();
newIntent.setClass(context, AndroidMobilePushApp.class);
newIntent.putExtras(extras);
newIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(newIntent);
}
public void onCreate(){
super.onCreate();
final String preferences = getString(R.string.preferences);
savedValues = getSharedPreferences(preferences, Context.MODE_PRIVATE);
// In later versions multi_process is no longer the default
if(VERSION.SDK_INT > 9){
savedValues = getSharedPreferences(preferences, Context.MODE_MULTI_PROCESS);
}
gcm = GoogleCloudMessaging.getInstance(getBaseContext());
SharedPreferences savedValues = PreferenceManager.getDefaultSharedPreferences(this);
if(savedValues.getBoolean(getString(R.string.first_launch), true)){
register();
SharedPreferences.Editor editor = savedValues.edit();
editor.putBoolean(getString(R.string.first_launch), false);
editor.commit();
}
// Let AndroidMobilePushApp know we have just initialized and there may be stored messages
sendToApp(new Bundle(), this);
}
protected static void saveToLog(Bundle extras, Context context){
SharedPreferences.Editor editor=savedValues.edit();
String numOfMissedMessages = context.getString(R.string.num_of_missed_messages);
int linesOfMessageCount = 0;
for(String key : extras.keySet()){
String line = String.format("%s=%s", key, extras.getString(key));
editor.putString("MessageLine" + linesOfMessageCount, line);
linesOfMessageCount++;
}
editor.putInt(context.getString(R.string.lines_of_message_count), linesOfMessageCount);
editor.putInt(context.getString(R.string.lines_of_message_count), linesOfMessageCount);
editor.putInt(numOfMissedMessages, savedValues.getInt(numOfMissedMessages, 0) + 1);
editor.commit();
postNotification(new Intent(context, AndroidMobilePushApp.class), context);
}
protected static void postNotification(Intent intentAction, Context context){
final NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
final PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intentAction, Notification.DEFAULT_LIGHTS | Notification.FLAG_AUTO_CANCEL);
final Notification notification = new NotificationCompat.Builder(context).setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("Message Received!")
.setContentText("")
.setContentIntent(pendingIntent)
.setAutoCancel(true)
.getNotification();
mNotificationManager.notify(R.string.notification_number, notification);
}
private void register() {
new AsyncTask(){
protected Object doInBackground(final Object... params) {
String token;
try {
token = gcm.register(getString(R.string.project_number));
Log.i("registrationId", token);
}
catch (IOException e) {
Log.i("Registration Error", e.getMessage());
}
return true;
}
}.execute(null, null, null);
}
public IBinder onBind(Intent arg0) {
return null;
}
}
SNSMobilePush.java
package com.test;
public class SNSMobilePush {
private AmazonSNSClientWrapper snsClientWrapper;
public SNSMobilePush(AmazonSNS snsClient) {
this.snsClientWrapper = new AmazonSNSClientWrapper(snsClient);
}
public static final Map<Platform, Map<String, MessageAttributeValue>> attributesMap = new HashMap<Platform, Map<String, MessageAttributeValue>>();
static {
attributesMap.put(Platform.ADM, null);
attributesMap.put(Platform.GCM, null);
attributesMap.put(Platform.APNS, null);
attributesMap.put(Platform.APNS_SANDBOX, null);
attributesMap.put(Platform.BAIDU, addBaiduNotificationAttributes());
attributesMap.put(Platform.WNS, addWNSNotificationAttributes());
attributesMap.put(Platform.MPNS, addMPNSNotificationAttributes());
}
public static void main(String[] args) throws IOException {
/*
* TODO: Be sure to fill in your AWS access credentials in the
* AwsCredentials.properties file before you try to run this sample.
* http://aws.amazon.com/security-credentials
*/
AmazonSNS sns = new AmazonSNSClient(new PropertiesCredentials(
SNSMobilePush.class
.getResourceAsStream("AwsCredentials.properties")));
sns.setEndpoint("https://sns.us-west-2.amazonaws.com");
System.out.println("===========================================\n");
System.out.println("Getting Started with Amazon SNS");
System.out.println("===========================================\n");
try {
SNSMobilePush sample = new SNSMobilePush(sns);
/* TODO: Uncomment the services you wish to use. */
sample.demoAndroidAppNotification();
// sample.demoKindleAppNotification();
// sample.demoAppleAppNotification();
// sample.demoAppleSandboxAppNotification();
// sample.demoBaiduAppNotification();
// sample.demoWNSAppNotification();
// sample.demoMPNSAppNotification();
} catch (AmazonServiceException ase) {
System.out
.println("Caught an AmazonServiceException, which means your request made it "
+ "to Amazon SNS, but was rejected with an error response for some reason.");
System.out.println("Error Message: " + ase.getMessage());
System.out.println("HTTP Status Code: " + ase.getStatusCode());
System.out.println("AWS Error Code: " + ase.getErrorCode());
System.out.println("Error Type: " + ase.getErrorType());
System.out.println("Request ID: " + ase.getRequestId());
} catch (AmazonClientException ace) {
System.out
.println("Caught an AmazonClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with SNS, such as not "
+ "being able to access the network.");
System.out.println("Error Message: " + ace.getMessage());
}
}
public void demoAndroidAppNotification() {
// TODO: Please fill in following values for your application. You can
// also change the notification payload as per your preferences using
// the method
// com.amazonaws.sns.samples.tools.SampleMessageGenerator.getSampleAndroidMessage()
String serverAPIKey = "REPLACED_WITH_SERVER_API_KEY";
String applicationName = "snspushtest";
String registrationId = "REPLACED_WITH_REG_ID_FROM_AMAZON";
snsClientWrapper.demoNotification(Platform.GCM, "", serverAPIKey,
registrationId, applicationName, attributesMap);
}
public void demoKindleAppNotification() {
// TODO: Please fill in following values for your application. You can
// also change the notification payload as per your preferences using
// the method
// com.amazonaws.sns.samples.tools.SampleMessageGenerator.getSampleKindleMessage()
String clientId = "";
String clientSecret = "";
String applicationName = "";
String registrationId = "";
snsClientWrapper.demoNotification(Platform.ADM, clientId, clientSecret,
registrationId, applicationName, attributesMap);
}
public void demoAppleAppNotification() {
// TODO: Please fill in following values for your application. You can
// also change the notification payload as per your preferences using
// the method
// com.amazonaws.sns.samples.tools.SampleMessageGenerator.getSampleAppleMessage()
String certificate = ""; // This should be in pem format with \n at the
// end of each line.
String privateKey = ""; // This should be in pem format with \n at the
// end of each line.
String applicationName = "";
String deviceToken = ""; // This is 64 hex characters.
snsClientWrapper.demoNotification(Platform.APNS, certificate,
privateKey, deviceToken, applicationName, attributesMap);
}
public void demoAppleSandboxAppNotification() {
// TODO: Please fill in following values for your application. You can
// also change the notification payload as per your preferences using
// the method
// com.amazonaws.sns.samples.tools.SampleMessageGenerator.getSampleAppleMessage()
String certificate = ""; // This should be in pem format with \n at the
// end of each line.
String privateKey = ""; // This should be in pem format with \n at the
// end of each line.
String applicationName = "";
String deviceToken = ""; // This is 64 hex characters.
snsClientWrapper.demoNotification(Platform.APNS_SANDBOX, certificate,
privateKey, deviceToken, applicationName, attributesMap);
}
public void demoBaiduAppNotification() {
/*
* TODO: Please fill in the following values for your application. If
* you wish to change the properties of your Baidu notification, you can
* do so by modifying the attribute values in the method
* addBaiduNotificationAttributes() . You can also change the
* notification payload as per your preferences using the method
* com.amazonaws
* .sns.samples.tools.SampleMessageGenerator.getSampleBaiduMessage()
*/
String userId = "";
String channelId = "";
String apiKey = "";
String secretKey = "";
String applicationName = "";
snsClientWrapper.demoNotification(Platform.BAIDU, apiKey, secretKey,
channelId + "|" + userId, applicationName, attributesMap);
}
public void demoWNSAppNotification() {
/*
* TODO: Please fill in the following values for your application. If
* you wish to change the properties of your WNS notification, you can
* do so by modifying the attribute values in the method
* addWNSNotificationAttributes() . You can also change the notification
* payload as per your preferences using the method
* com.amazonaws.sns.samples
* .tools.SampleMessageGenerator.getSampleWNSMessage()
*/
String notificationChannelURI = "";
String packageSecurityIdentifier = "";
String secretKey = "";
String applicationName = "";
snsClientWrapper.demoNotification(Platform.WNS,
packageSecurityIdentifier, secretKey, notificationChannelURI,
applicationName, attributesMap);
}
public void demoMPNSAppNotification() {
/*
* TODO: Please fill in the following values for your application. If
* you wish to change the properties of your MPNS notification, you can
* do so by modifying the attribute values in the method
* addMPNSNotificationAttributes() . You can also change the
* notification payload as per your preferences using the method
* com.amazonaws
* .sns.samples.tools.SampleMessageGenerator.getSampleMPNSMessage ()
*/
String notificationChannelURI = "";
String applicationName = "";
snsClientWrapper.demoNotification(Platform.MPNS, "", "",
notificationChannelURI, applicationName, attributesMap);
}
private static Map<String, MessageAttributeValue> addBaiduNotificationAttributes() {
Map<String, MessageAttributeValue> notificationAttributes = new HashMap<String, MessageAttributeValue>();
notificationAttributes.put("AWS.SNS.MOBILE.BAIDU.DeployStatus",
new MessageAttributeValue().withDataType("String")
.withStringValue("1"));
notificationAttributes.put("AWS.SNS.MOBILE.BAIDU.MessageKey",
new MessageAttributeValue().withDataType("String")
.withStringValue("default-channel-msg-key"));
notificationAttributes.put("AWS.SNS.MOBILE.BAIDU.MessageType",
new MessageAttributeValue().withDataType("String")
.withStringValue("0"));
return notificationAttributes;
}
private static Map<String, MessageAttributeValue> addWNSNotificationAttributes() {
Map<String, MessageAttributeValue> notificationAttributes = new HashMap<String, MessageAttributeValue>();
notificationAttributes.put("AWS.SNS.MOBILE.WNS.CachePolicy",
new MessageAttributeValue().withDataType("String")
.withStringValue("cache"));
notificationAttributes.put("AWS.SNS.MOBILE.WNS.Type",
new MessageAttributeValue().withDataType("String")
.withStringValue("wns/badge"));
return notificationAttributes;
}
private static Map<String, MessageAttributeValue> addMPNSNotificationAttributes() {
Map<String, MessageAttributeValue> notificationAttributes = new HashMap<String, MessageAttributeValue>();
notificationAttributes.put("AWS.SNS.MOBILE.MPNS.Type",
new MessageAttributeValue().withDataType("String")
.withStringValue("token")); // This attribute is required.
notificationAttributes.put("AWS.SNS.MOBILE.MPNS.NotificationClass",
new MessageAttributeValue().withDataType("String")
.withStringValue("realtime")); // This attribute is required.
return notificationAttributes;
}
}
EDIT 2:
EDIT 3:
I changed the following code to:
AmazonSNS sns = new AmazonSNSClient(new PropertiesCredentials(
SNSMobilePush.class
.getResourceAsStream("AwsCredentials.properties")));
to
AmazonSNS sns = new AmazonSNSClient(new BasicAWSCredentials("ACCESS_KEY_REPLACED",
"SECRET_KEY_REPLACED"));
Now, there is a different error: Logcat
===========================================
Getting Started with Amazon SNS
===========================================
Exception in thread "main" java.lang.NoClassDefFoundError: org/xmlpull/v1/XmlPullParserException
at com.amazonaws.services.sns.AmazonSNSClient.invoke(AmazonSNSClient.java:2263)
at com.amazonaws.services.sns.AmazonSNSClient.createPlatformApplication(AmazonSNSClient.java:358)
at com.test.tools.AmazonSNSClientWrapper.createPlatformApplication(AmazonSNSClientWrapper.java:49)
at com.test.tools.AmazonSNSClientWrapper.demoNotification(AmazonSNSClientWrapper.java:119)
at com.test.SNSMobilePush.demoAndroidAppNotification(SNSMobilePush.java:104)
at com.test.SNSMobilePush.main(SNSMobilePush.java:71)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Caused by: java.lang.ClassNotFoundException: org.xmlpull.v1.XmlPullParserException
at java.net.URLClassLoader$1.run(URLClassLoader.java:372)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:360)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 11 more
Process finished with exit code 1
I'm using sns v2.2.5 :
build.gradle > compile 'com.amazonaws:aws-android-sdk-sns:2.2.5'
Here is my solution for subscribe/unsubscribe:
public class AmazonPushClient {
private static final String TAG = "AmazonPushClient";
private static final String PLATFORM_APPLICATION_ARN = "*****";
private static final String IDENTITY_POOL_ID = "******";
private AmazonSNSClient mClient;
private boolean isUnregistering;
private Application mApp;
private NotifPreferencesHelper mNotifPreferencesHelper;
public AmazonPushClient(Application application) {
try {
mApp = application;
mClient = createPushClient(application);
mNotifPreferencesHelper = new NotifPreferencesHelper(application);
} catch (Exception e) {
LOGE(TAG, "AmazonPushClient", e);
}
}
#Nullable
private String token() {
try {
return InstanceID.getInstance(mApp).getToken(mApp.getString(R.string.gcm_defaultSenderId),
GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
} catch (Exception e) {
LOGW(TAG, "token", e);
return null;
}
}
private CognitoCachingCredentialsProvider cognitoCachingCredentialsProvider(Application application) {
return new CognitoCachingCredentialsProvider(
application,
IDENTITY_POOL_ID,
Regions.EU_WEST_1 // if your identity_pool_id start with : eu-west-1
);
}
private AmazonSNSClient createPushClient(Application application) {
AmazonSNSClient client = new AmazonSNSClient(cognitoCachingCredentialsProvider(application));
client.setRegion(Region.getRegion(Regions.EU_WEST_1));
client.addRequestHandler(mHandler);
return client;
}
public void pRegister() {
synchronized (TAG) {
LOGD(TAG, "registering");
isUnregistering = true;
String token = token();
if(TextUtils.isEmpty(token)) {
return;
}
mNotifPreferencesHelper.saveNotificationPreferences(true);
CreatePlatformEndpointRequest platformEndpointRequest = new CreatePlatformEndpointRequest();
platformEndpointRequest.setToken(token());
platformEndpointRequest.setPlatformApplicationArn(PLATFORM_APPLICATION_ARN);
CreatePlatformEndpointResult result = mClient.createPlatformEndpoint(platformEndpointRequest);
mNotifPreferencesHelper.storeEndpointArn(result.getEndpointArn());
}
}
public void pUnregister() {
synchronized (TAG) {
LOGD(TAG, "unregistering");
isUnregistering = false;
mNotifPreferencesHelper.saveNotificationPreferences(false);
DeleteEndpointRequest deletePlatformApplicationRequest = new DeleteEndpointRequest();
deletePlatformApplicationRequest.setEndpointArn(mNotifPreferencesHelper.getEndpointArn());
mClient.deleteEndpoint(deletePlatformApplicationRequest);
}
}
private RequestHandler2 mHandler = new RequestHandler2() {
#Override
public void beforeRequest(Request<?> request) {
}
#Override
public void afterResponse(Request<?> request, Response<?> response) {
if (isUnregistering) {
mNotifPreferencesHelper.storeEndpointArn(null);
}
}
#Override
public void afterError(Request<?> request, Response<?> response, Exception e) {
}
};
}
NotifPreferencesHelper is just something to store the EndpointARN. You have to use this class in a background thread
In association you have to implements GcmListenerService etc.. SNS is just for subscribe, not receive.
https://developers.google.com/cloud-messaging/
With respect to the Properties Credentials
A. Are you sure you are exporting the file in the build? Have you made sure you can access the file using regular file I/O outside of the credentials provider? Are you sure the file is formatted correctly (see https://github.com/aws/aws-sdk-android/blob/master/aws-android-sdk-core/src/main/java/com/amazonaws/auth/PropertiesCredentials.java)
accessKey=KEY
secretKey=SECRET
Also looking at the source you should be able to load this file yourself using http://developer.android.com/reference/java/util/Properties.html.
However, I highly recommend not using this credentials provider. It is extremely unsafe in a mobile applications. Anyone could decompile your app and steal your credentials. A much safer approach is to use Amazon Cognito, which there is a plethora of examples. (Bottom of https://docs.aws.amazon.com/mobile/sdkforandroid/developerguide/setup.html , any of the examples here: https://docs.aws.amazon.com/mobile/sdkforandroid/developerguide/getting-started-android.html as well as samples in the GitHub repo https://github.com/awslabs/aws-sdk-android-samples
Cognito requires a little bit of set-up but the guides are tested, and it really doesn't take much more than a few minutes to be much more secure.
Don't think you should import 'SNSMobilePush' to a module of your android application
In the same application, i created a new module called snspush and
imported SNSMobilePush.java file into it. Also imported the
AwsCredentials.properties file to the same path as that of
SNSMobilePush.java. Added the keys in AwsCredentials.properties file.
SNSMobilePush is just a Java app provided by AWS to do tasks like
upload (bulkupload package) several tokens (device tokens or registration IDs) to Amazon SNS or
send a push notification.
You need to register your mobile app with AWS (using AndroidMobilePushApp android app). You should obtain below information (refer this link)
Client ID and client secret
API key
Device token or Registration ID (per device)
Then you can use SNSMobilePush java app or even a AWS SNS console as described here to send push notification to your registered device.
I would suggest you to try out sending push notification from the console instead of java app. You can register tokens from devices that will install your app in the future as described in the one of the options (preferably the last option) as described here
Related
I want to send money between different PaypalCustomerAccount, every user's transaction would be recorded in UserTransaction table. Example in the photo, PaypalCustomerAccount user_id rmMe7a68kOXIvblu4aah1ZHc7Qx2. When she makes a transaction it will be saved into UserTransaction table with its user_id with a new transaction_id -LOvXSpmHnjmN2sWkhap.
enter image description here
I want to use a chatbot from DialogFlow integrated in Android Studio to send money between the PaypalCustomerAccount.
In the screenshot is how to android app chatbot looks like, when user wants to send a "whoosh"(digital cheque), the conversation goes:
send a whoosh Sure
who would u like to send it to
enter image description here
send it to susie
May i know the post date for the cheque
enter image description here
send it tmr
Alright, ive sent a whoosh to susie it will be processed by
2018-10-17
enter image description here
Now after the user makes the request, i want to save the request of the new transaction to my firebase. From PaypalCustomerAccount rmMe7a68kOXIvblu4aah1ZHc7Qx2 to a2u4aqw3Hc7Qx2 .
Meaning a new Transaction record will appear under UserTransaction:
for a2u4aqw3Hc7Qx2 and the status will be receive.
for rmMe7a68kOXIvblu4aah1ZHc7Qx2 status will be sent.
The follow below is index.js code in fulfilment page for Dialog Flow. I do not know how to write the codes in order for the above described to happen (Meaning a new Transaction record will appear under UserTransaction)
Do i write the codes in dialog flow or in my android studio (the backend for chatbot code) for that to happen?
'use strict';
const functions = require('firebase-functions');
const {WebhookClient} = require('dialogflow-fulfillment');
const {Card, Suggestion} = require('dialogflow-fulfillment');
// initialise DB connection
const admin = require('firebase-admin');
admin.initializeApp({
credential: admin.credential.applicationDefault(),
databaseURL: 'ws://whooshapplication.firebaseio.com/',
});
process.env.DEBUG = 'dialogflow:debug'; // enables lib debugging statements
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
const agent = new WebhookClient({ request, response });
console.log('Dialogflow Request headers: ' + JSON.stringify(request.headers));
console.log('Dialogflow Request body: ' + JSON.stringify(request.body));
function SendWhoosh(agent)
{
const nameParam = agent.parameters.name;
const context = agent.getContext('send_a_whoosh');
const name = nameParam || context.parameters.name;
// push input into db
}
function fallback(agent) {
agent.add(`I didn't understand`);
agent.add(`I'm sorry, can you try again?`);
}
// // Uncomment and edit to make your own intent handler
// // uncomment `intentMap.set('your intent name here', yourFunctionHandler);`
// // below to get this function to be run when a Dialogflow intent is matched
// function yourFunctionHandler(agent) {
// agent.add(`This message is from Dialogflow's Cloud Functions for Firebase editor!`);
// agent.add(new Card({
// title: `Title: this is a card title`,
// imageUrl: 'https://developers.google.com/actions/images/badges/XPM_BADGING_GoogleAssistant_VER.png',
// text: `This is the body text of a card. You can even use line\n breaks and emoji! 💁`,
// buttonText: 'This is a button',
// buttonUrl: 'https://assistant.google.com/'
// })
// );
// agent.add(new Suggestion(`Quick Reply`));
// agent.add(new Suggestion(`Suggestion`));
// agent.setContext({ name: 'weather', lifespan: 2, parameters: { city: 'Rome' }});
// }
// // Uncomment and edit to make your own Google Assistant intent handler
// // uncomment `intentMap.set('your intent name here', googleAssistantHandler);`
// // below to get this function to be run when a Dialogflow intent is matched
// function googleAssistantHandler(agent) {
// let conv = agent.conv(); // Get Actions on Google library conv instance
// conv.ask('Hello from the Actions on Google client library!') // Use Actions on Google library
// agent.add(conv); // Add Actions on Google library responses to your agent's response
// }
// // See https://github.com/dialogflow/dialogflow-fulfillment-nodejs/tree/master/samples/actions-on-google
// // for a complete Dialogflow fulfillment library Actions on Google client library v2 integration sample
// Run the proper function handler based on the matched Dialogflow intent name
[enter image description here][1] let intentMap = new Map();
intentMap.set('Default Welcome Intent', welcome);
intentMap.set('Default Fallback Intent', fallback);
// intentMap.set('your intent name here', yourFunctionHandler);
// intentMap.set('your intent name here', googleAssistantHandler);
agent.handleRequest(intentMap);
});
enter image description here
This is my android studio ChatBot.java codes for the chatbot to work
public class ChatBot extends AppCompatActivity implements AIListener
{
public Bot bot;
public static Chat chat;
private ListView mListView;
private Button mButtonSend;
private EditText mEditTextMessage;
private Button mImageView;
private ChatMessageAdapter mAdapter;
AIService aiService;
private static final String TAG = "ChatBot";
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat_bot);
mListView = (ListView) findViewById(R.id.listView);
mImageView = (Button)findViewById(R.id.voice_record);
mButtonSend = (Button) findViewById(R.id.btn_send);
mEditTextMessage = (EditText) findViewById(R.id.et_message);
mAdapter = new ChatMessageAdapter(this, new ArrayList<ChatMessage>());
mListView.setAdapter(mAdapter);
int permission = ContextCompat.checkSelfPermission(this,
Manifest.permission.RECORD_AUDIO);
if (permission != PackageManager.PERMISSION_GRANTED)
{
Log.i(TAG, "Permission to record denied");
makeRequest();
}
final AIConfiguration config = new AIConfiguration("c43d5450b1a54959a44158fb897f1dcb",
AIConfiguration.SupportedLanguages.English,
AIConfiguration.RecognitionEngine.System);
aiService = AIService.getService(this, config);
aiService.setListener(this);
mButtonSend.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
String message = mEditTextMessage.getText().toString();
//bot
String response = chat.multisentenceRespond(mEditTextMessage.getText().toString());
if (TextUtils.isEmpty(message))
{
return;
}
sendMessage(message);
mimicOtherMessage(response);
mEditTextMessage.setText("");
mListView.setSelection(mAdapter.getCount() - 1);
}
});
mImageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
aiService.startListening();
}
});
// *************************************
//checking SD card availablility
boolean a = isSDCARDAvailable();
//receiving the assets from the app directory
AssetManager assets = getResources().getAssets();
File jayDir = new File(Environment.getExternalStorageDirectory().toString() + "/cheque/bots/whoosh");
boolean b = jayDir.mkdirs();
if (jayDir.exists())
{
//Reading the file
try {
for (String dir : assets.list("whoosh")) {
File subdir = new File(jayDir.getPath() + "/" + dir);
boolean subdir_check = subdir.mkdirs();
for (String file : assets.list("whoosh/" + dir)) {
File f = new File(jayDir.getPath() + "/" + dir + "/" + file);
if (f.exists())
{
continue;
}
InputStream in = null;
OutputStream out = null;
in = assets.open("whoosh/" + dir + "/" + file);
out = new FileOutputStream(jayDir.getPath() + "/" + dir + "/" + file);
//copy file from assets to the mobile's SD card or any secondary memory
copyFile(in, out);
in.close();
in = null;
out.flush();
out.close();
out = null;
}
}
} catch (IOException e)
{
e.printStackTrace();
}
}
//get the working directory
MagicStrings.root_path = Environment.getExternalStorageDirectory().toString() + "/cheque";
System.out.println("Working Directory = " + MagicStrings.root_path);
AIMLProcessor.extension = new PCAIMLProcessorExtension();
//Assign the AIML files to bot for processing
bot = new Bot("whoosh", MagicStrings.root_path, "chat");
chat = new Chat(bot);
String[] args = null;
mainFunction(args);
// *************************************
} // onCreate
protected void makeRequest()
{
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.RECORD_AUDIO},
101);
}
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults)
{
switch (requestCode)
{
case 101:
{
if (grantResults.length == 0 || grantResults[0] != PackageManager.PERMISSION_GRANTED)
{
Log.i(TAG, "Permission has been denied by user");
}
else
{
Log.i(TAG, "Permission has been granted by user");
}
return;
}
}
}
public void voiceclick(View view)
{
aiService.startListening();
}
//check SD card availability
public static boolean isSDCARDAvailable()
{
return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)? true :false;
}
//copying the file
private void copyFile(InputStream in, OutputStream out) throws IOException
{
byte[] buffer = new byte[1024];
int read;
while((read = in.read(buffer)) != -1)
{
out.write(buffer, 0, read);
}
} //copyFile
//Request and response of user and the bot
public static void mainFunction (String[] args)
{
MagicBooleans.trace_mode = false;
System.out.println("trace mode = " + MagicBooleans.trace_mode);
Graphmaster.enableShortCuts = true;
Timer timer = new Timer();
String request = "Hello.";
String response = chat.multisentenceRespond(request);
System.out.println("Human: "+request);
System.out.println("Robot: " + response);
} //mainFunction
private void sendMessage(String message)
{
ChatMessage chatMessage = new ChatMessage(message, true, false);
mAdapter.add(chatMessage);
//respond as Helloworld
mimicOtherMessage("HelloWorld");
} //sendMessage
private void mimicOtherMessage(String message)
{
ChatMessage chatMessage = new ChatMessage(message, false, false);
mAdapter.add(chatMessage);
}
private void sendMessage()
{
ChatMessage chatMessage = new ChatMessage(null, true, true);
mAdapter.add(chatMessage);
mimicOtherMessage();
}
private void mimicOtherMessage()
{
ChatMessage chatMessage = new ChatMessage(null, false, true);
mAdapter.add(chatMessage);
}
#Override
public void onResult(AIResponse result)
{
Log.d("anu",result.toString());
Result result1 = result.getResult();
mEditTextMessage.setText("Query" + result1.getResolvedQuery() + " action: " + result1.getAction());
}
#Override
public void onError(AIError error) {
}
#Override
public void onAudioLevel(float level) {
}
#Override
public void onListeningStarted() {
}
#Override
public void onListeningCanceled() {
}
#Override
public void onListeningFinished() {
}
}
enter image description here
Here is also a screenshot of my intent in dialogflow
enter image description here
enter image description here
Please help me! and thank you in advance
First of all, Awesome Project on which you are working on, implementing the real-time chatbot transaction management.
I have reviewed each file you have attached and your asked question properly. I want to highlight some important steps that you can follow to implement the asked thing that are:
Checkout and implement Paypal SDK in your Android Application: https://github.com/paypal/PayPal-Android-SDK
Then, using the methods and objects you can simply put the returned values of any transaction from Paypal to your android application and thus, you can pass that on Realtime Database at Firebase.
The Chatbot Code is fine here, just you have to trigger action on particular intent calling of when the user says to send money to someone, to the android application backend where the Paypal code will run in Android Class File.
I hope you have got me! Better to know more, please feel free to ask doubts in reply section.
All the best for your future implementation!
I have made the following class to receive firebase messages and create notifications. I have tested it by sending firebase messages to the app and it works perfectly. However, I need to write unit tests to test this feature. But the 2 unit tests I have written for it are failing.
onMessageReceived() receives data in a RemoteMessage object. It then finds the value of the key type and depending on whether it is 0 or 1, it calls either buildNotificationBigText() or buildNotificationBigPicture() . Hence I have written 2 test methods. In my test methods I have created a RemoteMessage object and passed this to onMessageReceived(). However, these tests are not working correctly and I get the following error:
java.lang.NullPointerException: Attempt to invoke virtual method 'void in.ac.bits_pilani.goa.ard.services.HandleFirebaseMessages.onMessageReceived(com.google.firebase.messaging.RemoteMessage)' on a null object reference
at in.ac.bits_pilani.goa.ard.activities.MainActivityTest.handleFirebaseMessageBigPicture(MainActivityTest.java:90)
java.lang.NullPointerException: Attempt to invoke virtual method 'void in.ac.bits_pilani.goa.ard.services.HandleFirebaseMessages.onMessageReceived(com.google.firebase.messaging.RemoteMessage)' on a null object reference
at in.ac.bits_pilani.goa.ard.activities.MainActivityTest.handleFirebaseMessagesBigText(MainActivityTest.java:80)
HandleFirebaseMessages.java
public class HandleFirebaseMessages extends FirebaseMessagingService {
/**
* default id for notification in case specific id is not given in data.
*/
final int default_id = 42;
NotificationCompat.Builder builder ;
/**
* contains bigTitle value of data in onMessageReceived().
*/
String bigTitle;
/**
* is assigned the bigSummaryText value of data in onMessageReceived().
*/
String bigSummaryText;
public HandleFirebaseMessages() {
}
/**
* returns the bitmap image from the url given.
* #param src image url
* #return bitmap image at url
*/
public static Bitmap getBitmapFromURL(final String src) {
try {
final URL url = new URL(src);
final HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
final InputStream input = connection.getInputStream();
return BitmapFactory.decodeStream(input);
} catch (final IOException e) {
// Log exception
Log.e("TAG", "fucked man " + e.getMessage());
return null;
}
}
/**
* creates the notification when type is 1 or big text.
* #param data data to be put in notification
*/
public void buildNotificationBigText(final Map<String, String> data) {
Log.e("Tag4", "entered buildNotificationBigText");
//final String bigTitle = data.get("bigTitle");
final String bigSubTitle = data.get("bigSubTitle");
//final String bigSummaryText = data.get("bigSummaryText");
final NotificationCompat.BigTextStyle notificationBigText = new NotificationCompat.BigTextStyle();
if (bigTitle != null) {
notificationBigText.setBigContentTitle(bigTitle);
}
if (bigSubTitle != null) {
notificationBigText.bigText(bigSubTitle);
}
if (bigSummaryText != null) {
notificationBigText.setSummaryText(bigSummaryText);
}
builder.setStyle(notificationBigText);
}
/**
* creates the notification when type is 2 or big picture.
* #param data data to be put in notification
*/
public void buildNotificationBigPicture(final Map<String, String> data) {
Log.e("Tag3", "entered buildNotificationBigPicture");
final String imageUrl = data.get("imageUrl");
//final String bigSummaryText = data.get("bigSummaryText");
//final String bigTitle = data.get("bigTitle");
final NotificationCompat.BigPictureStyle notificationBigPicture = new NotificationCompat.BigPictureStyle();
if (imageUrl != null) {
final Bitmap image = getBitmapFromURL(imageUrl);
if (image != null) {
notificationBigPicture.bigPicture(image);
} else {
//TODO Image is null bt url wasn;t!
}
}
if (bigSummaryText != null) {
notificationBigPicture.setSummaryText(bigSummaryText);
}
if (bigTitle != null) {
notificationBigPicture.setBigContentTitle(bigTitle);
}
//TODO icon
builder.setStyle(notificationBigPicture);
}
#Override
public void onMessageReceived(final RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
Log.e("Tag1", "onMessageReceived() started");
final Map<String, String> data = remoteMessage.getData();
if (data == null) {
return;
}
bigTitle = data.get("bigTitle");
bigSummaryText = data.get("bigSummaryText");
final String type = data.get("type");
final String id = data.get("id");
final String smallTitle = data.get("smallTitle");
final String smallSubTitle = data.get("smallSubTitle");
//final String contentInfo = data.get("contentInfo");
//final String ticker = data.get("ticker");
final String link = data.get("link");
final String className = data.get("className");
Log.e("Tag2", "type = " + type);
builder = new NotificationCompat.Builder(this);
if (type != null) {
if (type.compareTo("1") == 0) {
//Large Text Style corresponds to "1"
buildNotificationBigText(data);
} else if (type.compareTo("2") == 0) {
//BigPicture style specific
buildNotificationBigPicture(data);
}
}
//General things to be added for any kind of notification
if (smallTitle != null) {
builder.setContentTitle(smallTitle);
}
if (smallSubTitle != null) {
builder.setContentText(smallSubTitle);
}
int notificationId = default_id;
if (id != null) {
notificationId = Integer.parseInt(id);
}
builder.setContentIntent(addWebsiteLinkPendingIntent(notificationId, link, className));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
builder.setCategory(Notification.CATEGORY_SOCIAL);
}
builder.setSmallIcon(R.drawable.ic_stat);
builder.setColor(ContextCompat.getColor(this, R.color.colorPrimary));
builder.setAutoCancel(true);
final NotificationManagerCompat mNotificationManager = NotificationManagerCompat.from(this);
mNotificationManager.notify(notificationId, builder.build());
}
/**
* returns the intent for the webpage or activity to open from the notification.
* #param id notification id
* #param link webpage link
* #param className class for the activity to open
* #return PendingIntent for the webpage ot activity
*/
private PendingIntent addWebsiteLinkPendingIntent(final int id, final String link, final String className) {
Intent intent;
if (link != null) {
//TODO Change to ChromeCustomTabs later
intent = new Intent(Intent.ACTION_VIEW, Uri.parse(link));
} else if (className != null) {
try {
intent = new Intent(this, Class.forName("com.csatimes.dojma." + className));
//TODO check for page number
} catch (final ClassNotFoundException e) {
intent = new Intent(this, MainActivity.class);
}
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
} else {
intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION);
}
return PendingIntent.getActivity(
this,
id,
intent,
PendingIntent.FLAG_CANCEL_CURRENT);
}
}
MainActivityTests.java :
#RunWith(AndroidJUnit4.class)
public class MainActivityTest {
private Context context;
#Mock
private HandleFirebaseMessages handleFirebaseMessages;
#Rule
public ActivityTestRule<MainActivity> activityTestRule =
new ActivityTestRule<>(MainActivity.class);
#Before
public void init() {
context = InstrumentationRegistry.getTargetContext();
//MockitoAnnotations.initMocks(this);
//handleFirebaseMessages = new HandleFirebaseMessages();
}
#Test
public void handleFirebaseMessagesBigText() {
HandleFirebaseMessages handleFirebaseMessages=new HandleFirebaseMessages();
RemoteMessage remoteMessage = new RemoteMessage.Builder("token").addData("type","1").build();
handleFirebaseMessages.onMessageReceived(remoteMessage);
Map<String,String> data = new HashMap<>() ;
data.put("type","1");
Mockito.verify(handleFirebaseMessages).buildNotificationBigText(data);
}
#Test
public void handleFirebaseMessagesBigPicture() {
HandleFirebaseMessages handleFirebaseMessages=new HandleFirebaseMessages();
RemoteMessage remoteMessage = new RemoteMessage.Builder("token").addData("type","2").build();
handleFirebaseMessages.onMessageReceived(remoteMessage);
Map<String,String> data = new HashMap<>() ;
data.put("type","2");
Mockito.verify(handleFirebaseMessages).buildNotificationBigPicture(data);
}
}
While testing it is advised to limit dependencies that you are testing. You could refactor your code in a way that it would not depend on FirebaseMessagingService.
For example instead of having your logic in onMessageReceived(), you could extract it to separate method preferably in other class (along with other methods from HandleFirebaseMessages) that would not depend on FirebaseMessagingService. It could even be structured so that it relies on plain java code, so that no instrumentation is required to run the test.
This way you would only be testing your code and not other dependencies, which would make it easier to test.
I am try to send notification using firebase using android side code.
please suggest me how can I do.
Please help me.
Thanks in advance
First of all make sure you have an firebase project, if no than create one.
After that store the device id(firebase token) while registering the device using this code.
class MyFirebaseInstanceIDService extends FirebaseInstanceIdService {
private static final String TAG = "MyFirebaseIIDService";
/**
* Called if InstanceID token is updated. This may occur if the security of
* the previous token had been compromised. Note that this is called when the InstanceID token
* is initially generated so this is where you would retrieve the token.
*/
// [START refresh_token]
#Override
public void onTokenRefresh() {
// Get updated InstanceID token.
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
Log.d(TAG, "Refreshed token: " + refreshedToken);
// If you want to send messages to this application instance or
// manage this apps subscriptions on the server side, send the
// Instance ID token to your app server.
sendRegistrationToServer(refreshedToken);
}
// [END refresh_token]
/**
* Persist token to third-party servers.
* <p>
* Modify this method to associate the user's FCM InstanceID token with any server-side account
* maintained by your application.
*
* #param token The new token.
*/
private void sendRegistrationToServer(final String token) {
new SharedPrefUtil(getApplicationContext()).saveString(Constants.ARG_FIREBASE_TOKEN, token);
if (FirebaseAuth.getInstance().getCurrentUser() != null) {
FirebaseDatabase.getInstance()
.getReference()
.child(Constants.ARG_USERS)
.child(FirebaseAuth.getInstance().getCurrentUser().getUid())
.child(Constants.ARG_FIREBASE_TOKEN)
.setValue(token);
}
}}
after that send notification to the user you want using following code-
void sendPushNotificationToReceiver(String username,
String message,
String uid,
String firebaseToken,
String receiverFirebaseToken) {
Log.d(":asdfasd",username+" "+message);
FcmNotificationBuilder.initialize()
.title(username)
.message(message)
.username(username)
.uid(uid)
.firebaseToken(firebaseToken)
.receiverFirebaseToken(receiverFirebaseToken)
.send();
}
here is the FCMNotificationBuilder class-
class FcmNotificationBuilder {
public static final MediaType MEDIA_TYPE_JSON = MediaType.parse("application/json; charset=utf-8");
private static final String TAG = "FcmNotificationBuilder";
private static final String SERVER_API_KEY = "YOUR SERVER API KEY";
private static final String CONTENT_TYPE = "Content-Type";
private static final String APPLICATION_JSON = "application/json";
private static final String AUTHORIZATION = "Authorization";
private static final String AUTH_KEY = "key=" + SERVER_API_KEY;
private static final String FCM_URL = "https://fcm.googleapis.com/fcm/send";
// json related keys
private static final String KEY_TO = "to";
private static final String KEY_NOTIFICATION = "notification";
private static final String KEY_TITLE = "title";
private static final String KEY_TEXT = "text";
private static final String KEY_DATA = "data";
private static final String KEY_USERNAME = "username";
private static final String KEY_UID = "uid";
private static final String KEY_FCM_TOKEN = "fcm_token";
private String mTitle;
private String mMessage;
private String mUsername;
private String mUid;
private String mFirebaseToken;
private String mReceiverFirebaseToken;
private FcmNotificationBuilder() {
}
public static FcmNotificationBuilder initialize() {
return new FcmNotificationBuilder();
}
public FcmNotificationBuilder title(String title) {
mTitle = title;
return this;
}
public FcmNotificationBuilder message(String message) {
mMessage = message;
return this;
}
public FcmNotificationBuilder username(String username) {
mUsername = username;
return this;
}
public FcmNotificationBuilder uid(String uid) {
mUid = uid;
return this;
}
public FcmNotificationBuilder firebaseToken(String firebaseToken) {
mFirebaseToken = firebaseToken;
return this;
}
public FcmNotificationBuilder receiverFirebaseToken(String receiverFirebaseToken) {
mReceiverFirebaseToken = receiverFirebaseToken;
return this;
}
public void send() {
RequestBody requestBody = null;
try {
requestBody = RequestBody.create(MEDIA_TYPE_JSON, getValidJsonBody().toString());
} catch (JSONException e) {
e.printStackTrace();
}
Request request = new Request.Builder()
.addHeader(CONTENT_TYPE, APPLICATION_JSON)
.addHeader(AUTHORIZATION, AUTH_KEY)
.url(FCM_URL)
.post(requestBody)
.build();
Call call = new OkHttpClient().newCall(request);
call.enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
Log.e(TAG, "onGetAllUsersFailure: " + e.getMessage());
}
#Override
public void onResponse(Call call, Response response) throws IOException {
Log.e(TAG, "onResponse: " + response.body().string());
}
});
}
private JSONObject getValidJsonBody() throws JSONException {
JSONObject jsonObjectBody = new JSONObject();
jsonObjectBody.put(KEY_TO, mReceiverFirebaseToken);
JSONObject jsonObjectData = new JSONObject();
jsonObjectData.put(KEY_TITLE, mTitle);
jsonObjectData.put(KEY_TEXT, mMessage);
jsonObjectData.put(KEY_USERNAME, mUsername);
jsonObjectData.put(KEY_UID, mUid);
jsonObjectData.put(KEY_FCM_TOKEN, mFirebaseToken);
jsonObjectBody.put(KEY_DATA, jsonObjectData);
return jsonObjectBody;
}}
and receive notifications as normally we do using services.
This is working for me in my chat application , hope it will help you also.
First thing is to get the Token of the user you want to send the notification to.
Then I use this code in an AsyncTask
protected String doInBackground(String... strings) {
try{
JSONObject jo = new JSONObject();
jo.put("message", "<Message>"));
jo.put("title", "<Message Title>");
JSONObject mainObj = new JSONObject();
mainObj.put("to",<TOKEN_OF_DEVICE>);
mainObj.put("data", jo);
URL url = new URL("https://android.googleapis.com/gcm/send");
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("Authorization", "key=<API_KEY>");
connection.setDoOutput(true);
//Log.e("sent",mainObj.toString());
DataOutputStream dStream = new DataOutputStream(connection.getOutputStream());
dStream.writeBytes(mainObj.toString());
dStream.flush();
dStream.close();
String line;
int responseCode = connection.getResponseCode();
//Log.e("code", responseCode+" hi");
BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
StringBuilder responseOutput = new StringBuilder();
while((line = br.readLine()) != null ){
responseOutput.append(line);
}
br.close();
//Log.e("output", responseOutput.toString());
}
catch (Exception e){
e.printStackTrace();
}
return null;
}
First of all connect Firebase to your project from Android Studio.
Generate token
Follow the link Firebase Notification
Also sample github code link isGithub code
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "MyFirebaseMsgService";
/**
* Called when message is received.
*
* remoteMessage Object representing the message received from Firebase Cloud Messaging.
*/
// [START receive_message]
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// [START_EXCLUDE]
// There are two types of messages data messages and notification messages. Data messages are handled
// here in onMessageReceived whether the app is in the foreground or background. Data messages are the type
// traditionally used with GCM. Notification messages are only received here in onMessageReceived when the app
// is in the foreground. When the app is in the background an automatically generated notification is displayed.
// When the user taps on the notification they are returned to the app. Messages containing both notification
// and data payloads are treated as notification messages. The Firebase console always sends notification
// messages.
// [END_EXCLUDE]
// TODO(developer): Handle FCM messages here.
// Not getting messages here?
// Log.d(TAG, "From: " + remoteMessage.getFrom());
sendNotification(remoteMessage.getNotification().getBody());
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
// Log.d(TAG, "Message data payload: " + remoteMessage.getData());
}
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
// Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
}
// Also if you intend on generating your own notifications as a result of a received FCM
// message, here is where that should be initiated. See sendNotification method below.
}
// [END receive_message]
/**
* Create and show a simple notification containing the received FCM message.
*
* #param messageBody FCM message body received.
*/
private void sendNotification(String messageBody) {
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("Title")
.setContentText(messageBody)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
}
}
I have a Broadcast receiver in my app and get a url from server response from server response url I split package name and save in shared preference,now scenario is that when any app is added in device it will check that app package name from my saved package name if match then pass intent. problem is that when variable which I declared earlier was empty then how to match new package added with my saved packge.shows me null pointer exception.
here is code:-
public class CAppDownloadReceiver extends BroadcastReceiver {
String url, packageName, s_szDealCode;
CDealBuySharedPreference m_oSharedPreference;
/**
* Get Query String as Key-Value Pair.
*/
public static Map<String, String> getQueryMap(String query) {
Map<String, String> map = new HashMap<>();
String[] queryString = query.split("\\?");
if (queryString.length > 1) {
String[] params = queryString[1].split("&");
for (String param : params) {
String name = param.split("=")[0];
String value = param.split("=")[1];
map.put(name, value);
}
}
return map;
}
#Override
public void onReceive(Context context, Intent intent) {
m_oSharedPreference = new CDealBuySharedPreference(context);
HashMap<String, String> user = m_oSharedPreference.getDealUrlDetails();
try {
if (intent.getAction().equals("android.intent.action.PACKAGE_ADDED")) {
String installAppPackgeName = intent.getData().getSchemeSpecificPart();
url = user.get(CDealBuySharedPreference.s_szDealUrl);// getting mobile from saved preferences..........
packageName = getQueryMap(url).get("id");
System.out.println("Previous package stored :" + packageName);
System.out.println("new Package added" + installAppPackgeName);
if (installAppPackgeName.equals(packageName)) {
// If install app package name is same as url package name then do some task.
// Your app is installed now.
s_szDealCode = user.get(CDealBuySharedPreference.s_szDealCode);
System.out.println("Match...");
System.out.println("Broadcast url..." + url);
System.out.println("Broadcast deal code:-" + s_szDealCode);
} else {
System.out.println("does not match ");
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
I send notification one client to another successfully. With this method:
ParsePush push = new ParsePush();
String yourMessage = "hello world";
push.setChannel("seconddevice");
push.setMessage(yourMessage);
push.sendInBackground();
my application:
public class ParseApplication extends Application {
String YOUR_APPLICATION_ID="xxx",YOUR_CLIENT_KEY="yyy";
#Override
public void onCreate() {
super.onCreate();
// Add your initialization code here
Parse.initialize(this, YOUR_APPLICATION_ID, YOUR_CLIENT_KEY);
ParseUser.enableAutomaticUser();
ParseACL defaultACL = new ParseACL();
// If you would like all objects to be private by default, remove this line.
defaultACL.setPublicReadAccess(true);
ParseACL.setDefaultACL(defaultACL, true);
PushService.subscribe(this, DEVICE_NAME, NotificationBck.class);
}
}
It works. But when I receive message in second device can I have which device send this notification?
From the Parse Android docs:
The Intent object which is passed to the receiver contains an extras Bundle with two useful mappings. The com.parse.Channel key points to a string representing the channel that the message was sent on. The com.parse.Data key points to a string representing the JSON-encoded value of the "data" dictionary that was set in the push notification.
So, in your receiver, you'd be able to check the data (assuming you've set it when pushing):
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
String channel = intent.getExtras().getString("com.parse.Channel");
String encodedJson = intent.getExtras().getString("com.parse.Data");
Log.d(TAG, "got action " + action + " on channel " + channel + " with:");
JSONObject json = decodeJsonObjectFrom(encodedJson);
logContentsOf(json);
}
private JSONObject decodeJsonObjectFrom(String encodedJson) {
try {
return new JSONObject(encodedJson);
} catch (JSONException e) {
return new JSONObject();
}
}
private void logContentsOf(JSONObject json) {
while (json.keys().hasNext()) {
String key = (String) json.keys().next();
Log.d(TAG, "..." + key + " => " + getStringFrom(json, key));
}
}
private String getStringFrom(JSONObject json, String key) {
try {
return (String) json.get(key);
} catch (JSONException e) {
return "";
}
}