Unable to start intent service gcm - java

Note:This is not a duplication or spammming since i have checked whole lot of searches.
Im currently developing an gcm integrated application and when i run on my emulator,it shows :
04-13 00:07:23.814: W/ActivityManager(366): Unable to start service
Intent { act=com.google.android.c2dm.intent.REGISTER
pkg=com.google.android.gms (has extras) } U=0: not found
My code is not similar to searches in here as I followed this tutorial https://github.com/erikswed/InstaChatX
In this tutorial,there are only 4 gcm client class,gcmbroadcast receiver,Gcm Util,Server Utilities and Constants.In those 4 classes havent mentioned about intent and in android manifest files also dont have permission:
Here is code for 4 gcm client class:
public class GcmBroadcastReceiver extends BroadcastReceiver {
private static final String TAG = "GcmBroadcastReceiver";
private Context ctx;
#Override
public void onReceive(Context context, Intent intent) {
ctx = context;
PowerManager mPowerManager = (PowerManager)
context.getSystemService(Context.POWER_SERVICE);
WakeLock mWakeLock =
mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
mWakeLock.acquire();
try {
GoogleCloudMessaging gcm =
GoogleCloudMessaging.getInstance(context);
String messageType = gcm.getMessageType(intent);
if
(GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR.equals(messageType)) {
sendNotification("Send error", false);
} else if
(GoogleCloudMessaging.MESSAGE_TYPE_DELETED.equals(messageType)) {
sendNotification("Deleted messages on server", false);
} else {
String msg = intent.getStringExtra(DataProvider.COL_MESSAGE);
String senderEmail =
intent.getStringExtra(DataProvider.COL_SENDER_EMAIL);
String receiverEmail =
intent.getStringExtra(DataProvider.COL_RECEIVER_EMAIL);
ContentValues values = new ContentValues(2);
values.put(DataProvider.COL_TYPE,
MessageType.INCOMING.ordinal());
values.put(DataProvider.COL_MESSAGE, msg);
values.put(DataProvider.COL_SENDER_EMAIL, senderEmail);
values.put(DataProvider.COL_RECEIVER_EMAIL, receiverEmail);
context.getContentResolver().insert
(DataProvider.CONTENT_URI_MESSAGES, values);
if (Common.isNotify()) {
sendNotification("New message", true);
}
}
setResultCode(Activity.RESULT_OK);
} finally {
mWakeLock.release();
}
}
private void sendNotification(String text, boolean launchApp) {
NotificationManager mNotificationManager = (NotificationManager)
ctx.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationCompat.Builder notification = new
NotificationCompat.Builder(ctx);
notification.setContentTitle(ctx.getString(R.string.app_name));
notification.setContentText(text);
notification.setAutoCancel(true);
notification.setSmallIcon(R.drawable.ic_launcher);
if (!TextUtils.isEmpty(Common.getRingtone())) {
notification.setSound(Uri.parse(Common.getRingtone()));
}
if (launchApp) {
Intent intent = new Intent(ctx, Chat_List.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pi = PendingIntent.getActivity(ctx, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
notification.setContentIntent(pi);
}
mNotificationManager.notify(1, notification.build());
}
}
This is GcmUtil class:
public class GcmUtil {
private static final String TAG = "GcmUtil";
public static final String PROPERTY_REG_ID = "registration_id";
private static final String PROPERTY_APP_VERSION = "appVersion";
private static final String PROPERTY_ON_SERVER_EXPIRATION_TIME = "onServerExpirationTimeMs";
/**
* Default lifespan (7 days) of a reservation until it is considered expired.
*/
public static final long REGISTRATION_EXPIRY_TIME_MS = 1000 * 3600 * 24 * 7;
private static final int MAX_ATTEMPTS = 5;
private static final int BACKOFF_MILLI_SECONDS = 2000;
private static final Random random = new Random();
private Context ctx;
private SharedPreferences prefs;
private GoogleCloudMessaging gcm;
private AsyncTask registrationTask;
public GcmUtil(Context ApplicationContext) {
super();
ctx = ApplicationContext;
prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
String regid = getRegistrationId();
if (regid.length() == 0) {
registerBackground();
} else {
broadcastStatus(true);
}
gcm = GoogleCloudMessaging.getInstance(ctx);
}
/**
* Gets the current registration id for application on GCM service.
* <p>
* If result is empty, the registration has failed.
*
* #return registration id, or empty string if the registration is not
* complete.
*/
private String getRegistrationId() {
String registrationId = prefs.getString(PROPERTY_REG_ID, "");
if (registrationId.length() == 0) {
//Log.v(TAG, "Registration not found.");
return "";
}
// check if app was updated; if so, it must clear registration id to
// avoid a race condition if GCM sends a message
int registeredVersion = prefs.getInt(PROPERTY_APP_VERSION, Integer.MIN_VALUE);
int currentVersion = getAppVersion();
if (registeredVersion != currentVersion || isRegistrationExpired()) {
//Log.v(TAG, "App version changed or registration expired.");
return "";
}
return registrationId;
}
/**
* Stores the registration id, app versionCode, and expiration time in the
* application's {#code SharedPreferences}.
*
* #param regId registration id
*/
private void setRegistrationId(String regId) {
int appVersion = getAppVersion();
//Log.v(TAG, "Saving regId on app version " + appVersion);
SharedPreferences.Editor editor = prefs.edit();
editor.putString(PROPERTY_REG_ID, regId);
editor.putInt(PROPERTY_APP_VERSION, appVersion);
long expirationTime = System.currentTimeMillis() + REGISTRATION_EXPIRY_TIME_MS;
//Log.v(TAG, "Setting registration expiry time to " + new Timestamp(expirationTime));
editor.putLong(PROPERTY_ON_SERVER_EXPIRATION_TIME, expirationTime);
editor.commit();
}
/**
* #return Application's version code from the {#code PackageManager}.
*/
private int getAppVersion() {
try {
PackageInfo packageInfo = ctx.getPackageManager().getPackageInfo(ctx.getPackageName(), 0);
return packageInfo.versionCode;
} catch (NameNotFoundException e) {
// should never happen
throw new RuntimeException("Could not get package name: " + e);
}
}
/**
* Checks if the registration has expired.
*
* <p>To avoid the scenario where the device sends the registration to the
* server but the server loses it, the app developer may choose to re-register
* after REGISTRATION_EXPIRY_TIME_MS.
*
* #return true if the registration has expired.
*/
private boolean isRegistrationExpired() {
// checks if the information is not stale
long expirationTime = prefs.getLong(PROPERTY_ON_SERVER_EXPIRATION_TIME, -1);
return System.currentTimeMillis() > expirationTime;
}
/**
* Registers the application with GCM servers asynchronously.
* <p>
* Stores the registration id, app versionCode, and expiration time in the
* application's shared preferences.
*/
private void registerBackground() {
registrationTask = new AsyncTask<Void, Void, Boolean>() {
#Override
protected Boolean doInBackground(Void... params) {
long backoff = BACKOFF_MILLI_SECONDS + random.nextInt(1000);
for (int i = 1; i <= MAX_ATTEMPTS; i++) {
//Log.d(TAG, "Attempt #" + i + " to register");
try {
if (gcm == null) {
gcm = GoogleCloudMessaging.getInstance(ctx);
}
String regid = gcm.register(Common.getSenderId());
// You should send the registration ID to your server over HTTP,
// so it can use GCM/HTTP or CCS to send messages to your app.
ServerUtilities.register(Common.getPreferredEmail(), regid);
// Save the regid - no need to register again.
setRegistrationId(regid);
return Boolean.TRUE;
} catch (IOException ex) {
//Log.e(TAG, "Failed to register on attempt " + i + ":" + ex);
if (i == MAX_ATTEMPTS) {
break;
}
try {
//Log.d(TAG, "Sleeping for " + backoff + " ms before retry");
Thread.sleep(backoff);
} catch (InterruptedException e1) {
// Activity finished before we complete - exit.
//Log.d(TAG, "Thread interrupted: abort remaining retries!");
Thread.currentThread().interrupt();
}
// increase backoff exponentially
backoff *= 2;
}
}
return Boolean.FALSE;
}
#Override
protected void onPostExecute(Boolean status) {
broadcastStatus(status);
}
}.execute();
}
private void broadcastStatus(boolean status) {
Intent intent = new Intent(Common.ACTION_REGISTER);
intent.putExtra(Common.EXTRA_STATUS, status ? Common.STATUS_SUCCESS : Common.STATUS_FAILED);
ctx.sendBroadcast(intent);
}
public void cleanup() {
if (registrationTask != null) {
registrationTask.cancel(true);
}
if (gcm != null) {
gcm.close();
}
}
}
This is Server Utilities Class:
public final class ServerUtilities {
private static final String TAG = "ServerUtilities";
private static final int MAX_ATTEMPTS = 5;
private static final int BACKOFF_MILLI_SECONDS = 2000;
private static final Random random = new Random();
/**
* Register this account/device pair within the server.
*/
public static void register(final String email, final String regId) {
//Log.i(TAG, "registering device (regId = " + regId + ")");
String serverUrl = Common.getServerUrl() + "/register";
Map<String, String> params = new HashMap<String, String>();
params.put(DataProvider.SENDER_EMAIL, email);
params.put(DataProvider.REG_ID, regId);
// Once GCM returns a registration id, we need to register it in the
// demo server. As the server might be down, we will retry it a couple
// times.
try {
post(serverUrl, params, MAX_ATTEMPTS);
} catch (IOException e) {
}
}
/**
* Unregister this account/device pair within the server.
*/
public static void unregister(final String email) {
//Log.i(TAG, "unregistering device (email = " + email + ")");
String serverUrl = Common.getServerUrl() + "/unregister";
Map<String, String> params = new HashMap<String, String>();
params.put(DataProvider.SENDER_EMAIL, email);
try {
post(serverUrl, params, MAX_ATTEMPTS);
} catch (IOException e) {
// At this point the device is unregistered from GCM, but still
// registered in the server.
// We could try to unregister again, but it is not necessary:
// if the server tries to send a message to the device, it will get
// a "NotRegistered" error message and should unregister the device.
}
}
/**
* Send a message.
*/
public static void send(String msg, String to) throws IOException {
//Log.i(TAG, "sending message (msg = " + msg + ")");
String serverUrl = Common.getServerUrl() + "/send";
Map<String, String> params = new HashMap<String, String>();
params.put(DataProvider.MESSAGE, msg);
params.put(DataProvider.SENDER_EMAIL, Common.getPreferredEmail());
params.put(DataProvider.RECEIVER_EMAIL, to);
post(serverUrl, params, MAX_ATTEMPTS);
}
/** Issue a POST with exponential backoff */
private static void post(String endpoint, Map<String, String> params, int maxAttempts) throws IOException {
long backoff = BACKOFF_MILLI_SECONDS + random.nextInt(1000);
for (int i = 1; i <= maxAttempts; i++) {
//Log.d(TAG, "Attempt #" + i);
try {
post(endpoint, params);
return;
} catch (IOException e) {
//Log.e(TAG, "Failed on attempt " + i + ":" + e);
if (i == maxAttempts) {
throw e;
}
try {
Thread.sleep(backoff);
} catch (InterruptedException e1) {
Thread.currentThread().interrupt();
return;
}
backoff *= 2;
} catch (IllegalArgumentException e) {
throw new IOException(e.getMessage(), e);
}
}
}
/**
* Issue a POST request to the server.
*
* #param endpoint POST address.
* #param params request parameters.
*
* #throws IOException propagated from POST.
*/
private static void post(String endpoint, Map<String, String> params) throws IOException {
URL url;
try {
url = new URL(endpoint);
} catch (MalformedURLException e) {
throw new IllegalArgumentException("invalid url: " + endpoint);
}
StringBuilder bodyBuilder = new StringBuilder();
Iterator<Entry<String, String>> iterator = params.entrySet().iterator();
// constructs the POST body using the parameters
while (iterator.hasNext()) {
Entry<String, String> param = iterator.next();
bodyBuilder.append(param.getKey()).append('=').append(param.getValue());
if (iterator.hasNext()) {
bodyBuilder.append('&');
}
}
String body = bodyBuilder.toString();
//Log.v(TAG, "Posting '" + body + "' to " + url);
byte[] bytes = body.getBytes();
HttpURLConnection conn = null;
try {
conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setFixedLengthStreamingMode(bytes.length);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
// post the request
OutputStream out = conn.getOutputStream();
out.write(bytes);
out.close();
// handle the response
int status = conn.getResponseCode();
if (status != 200) {
throw new IOException("Post failed with error code " + status);
}
} finally {
if (conn != null) {
conn.disconnect();
}
}
}
}
Constants class only have sender id and url.

Related

Google Play in-app Billing onPurchasesUpdated() error response code -1

I've been implementing for the first time in-app billing in my app and even if all the code is correct, it is not working!
I have a BillingManager.java
public class BillingManager implements PurchasesUpdatedListener {
private static final String TAG = "BillingManager";
private final BillingClient mBillingClient;
private final Activity mActivity;
String base64Key = "mykey";
private static Context myCxt;
private String mAdRemovalPrice;
private static final String ITEM_SKU_ADREMOVAL = "myskuid";
public int billingResult;
public BillingManager(Activity activity) {
mActivity = activity;
mBillingClient = BillingClient.newBuilder(mActivity).setListener(this).build();
mBillingClient.startConnection(new BillingClientStateListener() {
#Override
public void onBillingSetupFinished(#BillingClient.BillingResponse int billingResponse) {
if (billingResponse == BillingClient.BillingResponse.OK) {
Log.i(TAG, "onBillingSetupFinished() good response: " + billingResponse);
List skuList = new ArrayList<>();
skuList.add(ITEM_SKU_ADREMOVAL);
SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();
params.setSkusList(skuList).setType(BillingClient.SkuType.INAPP);
mBillingClient.querySkuDetailsAsync(params.build(),
new SkuDetailsResponseListener() {
#Override
public void onSkuDetailsResponse(int responseCode, List skuDetailsList) {
// Process the result.
if (responseCode == BillingClient.BillingResponse.OK
&& skuDetailsList != null) {
for (Object skuDetailsObject : skuDetailsList) {
SkuDetails skuDetails = (SkuDetails) skuDetailsObject;
String sku = skuDetails.getSku();
String price = skuDetails.getPrice();
if (ITEM_SKU_ADREMOVAL.equals(sku)) {
mAdRemovalPrice = price;
}
}
}
}
});
} else {
Log.w(TAG, "onBillingSetupFinished() error code: " + billingResponse);
}
}
#Override
public void onBillingServiceDisconnected() {
Log.w(TAG, "onBillingServiceDisconnected()");
}
});
}
#Override
public void onPurchasesUpdated(int responseCode, List<Purchase> purchases) {
if (responseCode == BillingClient.BillingResponse.OK
&& purchases != null) {
for(Purchase purchase: purchases) {
// When every a new purchase is made
// Here we verify our purchase
Log.i(TAG, "onPurchasesUpdated() ourchase ok response: " + responseCode);
if (!verifyValidSignature(purchase.getOriginalJson(), purchase.getSignature())) {
// Invalid purchase
// show error to user
myCxt = MainActivity.proContext;
Toast.makeText(myCxt, myCxt.getString(R.string.purchase_err), Toast.LENGTH_LONG).show();
Log.i(TAG, "Got a purchase: " + purchase + "; but signature is bad. Skipping...");
return;
} else {
// purchase is valid
// Perform actions
myCxt = MainActivity.proContext;
Toast.makeText(myCxt, myCxt.getString(R.string.purchase_done), Toast.LENGTH_LONG).show();
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(myCxt);
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("isPro", true);
editor.apply();
}
}
} else if (responseCode == BillingClient.BillingResponse.USER_CANCELED) {
// Handle an error caused by a user cancelling the purchase flow.
Log.i(TAG, "onPurchasesUpdated() user canceled response: " + responseCode);
} else {
// Handle any other error codes.
Log.i(TAG, "onPurchasesUpdated() error response: " + responseCode);
}
}
public void startPurchaseFlow() {
BillingFlowParams flowParams = BillingFlowParams.newBuilder()
.setSku(ITEM_SKU_ADREMOVAL)
.setType(BillingClient.SkuType.INAPP)
.build();
mBillingClient.launchBillingFlow(mActivity, flowParams);
Log.i(TAG, "StartPurchaseFlow called");
}
private boolean verifyValidSignature(String signedData, String signature) {
try {
return Security.verifyPurchase(base64Key, signedData, signature);
} catch (IOException e) {
Log.e(TAG, "Got an exception trying to validate a purchase: " + e);
return false;
}
}
And then i call it like this in my App menu:
if (id == R.id.action_pro) {
BillingManager mbilling = new BillingManager(MainActivity.this);
mbilling.startPurchaseFlow();
return true;
}
Actually it turns out that if I read the logs in debugging mode seems that onPurchasesUpdated() method throws the error -1 as response code! So this means that the responsecode is -1 which according to Java documentation is a generic error in http protocol... Why am I getting this?
The code seems pretty good even if compared to others or to guides found online. Does anyone have any suggestions?
Please make sure your billing client is initialized before you start the purchaseflow.
response code -1 indicates billingclient disconnected

How to schedule a java code having messageArrived method of MqttCallback

I am new in MQTT world. I have written a code to subscribe a topic and get message from topic and store it in database. Now my problem is how to put this code on server so that it will keep receiving message infinitely. I am trying to create a scheduler but in that case i am Getting Persistence Already in Use error from MQTT. I cannot change the clientId every time it connect. It is a fixed one in my case. Is there any way to get the persistence object which is already connected for a particular clientId?
Please help. Thanks and advance.
Please Find the code subscribe topic and messageArrived method of mqqt to get message from topic
public class AppTest {
private MqttHandler handler;
public void doApp() {
// Read properties from the conf file
Properties props = MqttUtil.readProperties("MyData/app.conf");
String org = props.getProperty("org");
String id = props.getProperty("appid");
String authmethod = props.getProperty("key");
String authtoken = props.getProperty("token");
// isSSL property
String sslStr = props.getProperty("isSSL");
boolean isSSL = false;
if (sslStr.equals("T")) {
isSSL = true;
}
// Format: a:<orgid>:<app-id>
String clientId = "a:" + org + ":" + id;
String serverHost = org + MqttUtil.SERVER_SUFFIX;
handler = new AppMqttHandler();
handler.connect(serverHost, clientId, authmethod, authtoken, isSSL);
// Subscribe Device Events
// iot-2/type/<type-id>/id/<device-id>/evt/<event-id>/fmt/<format-id>
handler.subscribe("iot-2/type/" + MqttUtil.DEFAULT_DEVICE_TYPE
+ "/id/+/evt/" + MqttUtil.DEFAULT_EVENT_ID + "/fmt/json", 0);
}
/**
* This class implements as the application MqttHandler
*
*/
private class AppMqttHandler extends MqttHandler {
// Pattern to check whether the events comes from a device for an event
Pattern pattern = Pattern.compile("iot-2/type/"
+ MqttUtil.DEFAULT_DEVICE_TYPE + "/id/(.+)/evt/"
+ MqttUtil.DEFAULT_EVENT_ID + "/fmt/json");
DatabaseHelper dbHelper = new DatabaseHelper();
/**
* Once a subscribed message is received
*/
#Override
public void messageArrived(String topic, MqttMessage mqttMessage)
throws Exception {
super.messageArrived(topic, mqttMessage);
Matcher matcher = pattern.matcher(topic);
if (matcher.matches()) {
String payload = new String(mqttMessage.getPayload());
// Parse the payload in Json Format
JSONObject contObj = new JSONObject(payload);
System.out
.println("jsonObject arrived in AppTest : " + contObj);
// Call method to insert data in database
dbHelper.insertIntoDB(contObj);
}
}
}
Code to connect to client
public void connect(String serverHost, String clientId, String authmethod,
String authtoken, boolean isSSL) {
// check if client is already connected
if (!isMqttConnected()) {
String connectionUri = null;
//tcp://<org-id>.messaging.internetofthings.ibmcloud.com:1883
//ssl://<org-id>.messaging.internetofthings.ibmcloud.com:8883
if (isSSL) {
connectionUri = "ssl://" + serverHost + ":" + DEFAULT_SSL_PORT;
} else {
connectionUri = "tcp://" + serverHost + ":" + DEFAULT_TCP_PORT;
}
if (client != null) {
try {
client.disconnect();
} catch (MqttException e) {
e.printStackTrace();
}
client = null;
}
try {
client = new MqttClient(connectionUri, clientId);
} catch (MqttException e) {
e.printStackTrace();
}
client.setCallback(this);
// create MqttConnectOptions and set the clean session flag
MqttConnectOptions options = new MqttConnectOptions();
options.setCleanSession(false);
options.setUserName(authmethod);
options.setPassword(authtoken.toCharArray());
//If SSL is used, do not forget to use TLSv1.2
if (isSSL) {
java.util.Properties sslClientProps = new java.util.Properties();
sslClientProps.setProperty("com.ibm.ssl.protocol", "TLSv1.2");
options.setSSLProperties(sslClientProps);
}
try {
// connect
client.connect(options);
System.out.println("Connected to " + connectionUri);
} catch (MqttException e) {
e.printStackTrace();
}
}
}

GCM Notification Receiver/Token Registration

EDIT: Figured it out -- see answer below
I'm attempting to generate registration tokens, store them in a server, and then use the tokens to send push notifications. At this point, I've successfully sent and stored registration tokens and am sending notifications from a web API, but they aren't arriving to my device. I was wondering if/what I should replace R.string.gcm_defaultSenderId with (i.e. the sender key from GCM?) I'm including my code for token registration as well as my notification listener below.
public class GCMRegistrationIntentService extends IntentService {
//Constants for success and errors
public static final String REGISTRATION_SUCCESS = "RegistrationSuccess";
public static final String REGISTRATION_ERROR = "RegistrationError";
private Context context;
private String sessionGUID = "";
private String userGUID = "";
//Class constructor
public GCMRegistrationIntentService() {
super("");
}
#Override
protected void onHandleIntent(Intent intent) {
context = getApplicationContext();
sessionGUID = RequestQueueSingleton.getInstance(context).getSessionGUID();
userGUID = RequestQueueSingleton.getInstance(context).getUserGUID();
//Registering gcm to the device
registerGCM();
}
//Registers the device to Google Cloud messaging and calls makeAPICall to send the registration
//token to the server
private void registerGCM() {
//Registration complete intent initially null
Intent registrationComplete;
//declare a token, try to find it with a successful registration
String token;
try {
//Creating an instanceid
InstanceID instanceID = InstanceID.getInstance(this);
//Getting the token from the instance id
token = instanceID.getToken(getString(R.string.gcm_defaultSenderId),
GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
//Display the token, need to send to server
Log.w("GCMRegIntentService", "token:" + token);
String android_id = Settings.Secure.getString(context.getContentResolver(),
Settings.Secure.ANDROID_ID);
int osTypeCode = Constants.OST_ANDROID;
JSONObject parms = new JSONObject();
try {
parms.put("deviceID", android_id);
parms.put("OSTypeCode", osTypeCode);
parms.put("token", token);
} catch (JSONException e) {
e.printStackTrace();
}
Transporter oTransporter = new Transporter(Constants.TransporterSubjectUSER,
Constants.REGISTER_NOTIFICATION_TOKEN, "", parms, userGUID, sessionGUID);
oTransporter.makeAPICall(getApplicationContext(), "");
//on registration complete. creating intent with success
registrationComplete = new Intent(REGISTRATION_SUCCESS);
//Putting the token to the intent
registrationComplete.putExtra("token", token);
} catch (Exception e) {
//If any error occurred
Log.w("GCMRegIntentService", "Registration error");
registrationComplete = new Intent(REGISTRATION_ERROR);
}
//Sending the broadcast that registration is completed
LocalBroadcastManager.getInstance(this).sendBroadcast(registrationComplete);
}
}
And the listener service:
public class GCMPushReceiverService extends GcmListenerService {
private static final String TAG = "GCMPushReceiverService";
//with every new message
#Override
public void onMessageReceived(String from, Bundle data){
System.out.println("WE'VE RECIEVED A MESSAGE");
String message = data.getString("message");
Log.d(TAG, "From: " + from);
Log.d(TAG, "Message: " + message);
sendNotification(message);
}
private void sendNotification(String message) {
Intent intent = new Intent(this, LogInPage.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
int requestCode = 0;
PendingIntent pendingIntent =
PendingIntent.getActivity(this, requestCode, intent, PendingIntent.FLAG_ONE_SHOT);
Uri sound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder noBuilder = new NotificationCompat.Builder(this);
noBuilder.setContentTitle("title");
noBuilder.setContentText(message);
noBuilder.setContentIntent(pendingIntent);
noBuilder.setSound(sound);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, noBuilder.build()); //0 = ID of notification
}
}
Lastly, as it may be of some assistance, the information transporter/networking class:
public class Transporter {
private String subject;
private String request;
private String key;
private Date lastUpdateDate;
private boolean forceLoad = false;
private Date requestDate;
private Date responseDate;
private int status;
private String statusMsg = "";
private String tempKey = "";
private JSONObject additionalInfo = null;
private JSONObject parameters;
public static String sessionGUID = "";
public static String userGUID = "";
public static String SERVER = Constants.qa_api;
//transporter object to interact with the server, containing information about the request
//made by the user
public Transporter(String pSubject, String pRequest, String pKey,
JSONObject parms, String userGUID, String sessionGUID)
{
subject = pSubject;
request = pRequest;
key = pKey;
parameters = parms;
setUserGUID(userGUID);
setSessionGUID(sessionGUID);
}
//implements an API call for a given transporter, takes 2 arguments:
//the application context (call getApplicationContext() whenever it's called)
//and a String that represents the field that we are trying to update (if there is one)
//i.e. if we are calling getUserFromSession(), we want the user guid so jsonID = "userGUID"
public void makeAPICall(final Context context, final String jsonID) {
RequestQueue mRequestQueue =
RequestQueueSingleton.getInstance(context).getRequestQueue();
String targetURL = getServerURL() + "/Transporter.aspx";
StringRequest postRequest = new StringRequest(Request.Method.POST, targetURL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
String parseXML= parseXML(response);
System.out.println("response: " + parseXML);
JSONObject lastResponseContent = null;
try {
lastResponseContent = new JSONObject(parseXML);
} catch (JSONException e) {
e.printStackTrace();
}
try {
if (lastResponseContent != null && !jsonID.equals("")) {
String info = lastResponseContent.getString(jsonID);
if (jsonID.equals("userGUID")) {
userGUID = info;
RequestQueueSingleton.getInstance(context).setUserGUID(userGUID);
}
}
//put other things in here to pull whatever info
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
}) {
#Override
public byte[] getBody() throws AuthFailureError {
String body = getXML(subject,
request, "",
sessionGUID, userGUID, null, parameters);
return body.getBytes();
}
};
postRequest.setTag("POST");
mRequestQueue.add(postRequest);
}
you need to send a post to the url "https://android.googleapis.com/gcm/send":
private void sendGCM() {
StringRequest strReq = new StringRequest(Request.Method.POST,
"https://android.googleapis.com/gcm/send", new Response.Listener<String>() {
#Override
public void onResponse(String response) {
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
NetworkResponse networkResponse = error.networkResponse;
Log.e(TAG, "Volley error: " + error.getMessage() + ", code: " + networkResponse);
Toast.makeText(getApplicationContext(), "Volley error: " + error.getMessage(), Toast.LENGTH_SHORT).show();
}
}) {
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<>();
params.put("data", "message that you send");
params.put("to", "token gcm");
Log.e(TAG, "params: " + params.toString());
return params;
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String,String> headers = new HashMap<String, String>();
headers.put("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
headers.put("Authorization", "key="google key");
return headers;
}
};
}
So the Volley calls are non-sequential so the first call (to get a userGUID) didn't return before the second call (to register for notifications), so while the token registration was "successful," there was no corresponding user information so it didn't know how/where to send the push notification. To resolve, I made a special case in the makeAPICall class which created another StringRequest which first basically did the normal getUserFromSession but then recursively called MakeAPICall with the new userGUID information. To avoid an infinite loop, I used an if else statement: (if userGUID == null || userGUID.equals("")) then I did the recursive call, so when the first call returned that conditional was always false and it would only make one recursive call. This answer may be a rambling a bit, but the key take away is using onResponse to make another Volley call for sequential requests. See: Volley - serial requests instead of parallel? and Does Volley library handles all the request sequentially

HTTP Status 404 - /GroupChat/ The requested resource is not available

I am working on a project to build a group chat app on socket server!
but when I start the server it get started and displays the following error:
HTTP Status 404- /GroupChat/
type Status report
message /GroupChat/
description The requested resource is not available.
I am using a J2EE eclipse where I have added a tomcat 7 server.
Below are my two files:
JSONUtils.java
package com.groupchat;
import org.json.JSONException;
import org.json.JSONObject;
public class JSONUtils {
// flags to identify the kind of json response on client side
private static final String FLAG_SELF = "self", FLAG_NEW = "new",
FLAG_MESSAGE = "message", FLAG_EXIT = "exit";
public JSONUtils() {
}
/**
* Json when client needs it's own session details
* */
public String getClientDetailsJson(String sessionId, String message) {
String json = null;
try {
JSONObject jObj = new JSONObject();
jObj.put("flag", FLAG_SELF);
jObj.put("sessionId", sessionId);
jObj.put("message", message);
json = jObj.toString();
} catch (JSONException e) {
e.printStackTrace();
}
return json;
}
/**
* Json to notify all the clients about new person joined
* */
public String getNewClientJson(String sessionId, String name,
String message, int onlineCount) {
String json = null;
try {
JSONObject jObj = new JSONObject();
jObj.put("flag", FLAG_NEW);
jObj.put("name", name);
jObj.put("sessionId", sessionId);
jObj.put("message", message);
jObj.put("onlineCount", onlineCount);
json = jObj.toString();
} catch (JSONException e) {
e.printStackTrace();
}
return json;
}
/**
* Json when the client exits the socket connection
* */
public String getClientExitJson(String sessionId, String name,
String message, int onlineCount) {
String json = null;
try {
JSONObject jObj = new JSONObject();
jObj.put("flag", FLAG_EXIT);
jObj.put("name", name);
jObj.put("sessionId", sessionId);
jObj.put("message", message);
jObj.put("onlineCount", onlineCount);
json = jObj.toString();
} catch (JSONException e) {
e.printStackTrace();
}
return json;
}
/**
* JSON when message needs to be sent to all the clients
* */
public String getSendAllMessageJson(String sessionId, String fromName,
String message) {
String json = null;
try {
JSONObject jObj = new JSONObject();
jObj.put("flag", FLAG_MESSAGE);
jObj.put("sessionId", sessionId);
jObj.put("name", fromName);
jObj.put("message", message);
json = jObj.toString();
} catch (JSONException e) {
e.printStackTrace();
}
return json;
}
}
SocketServer.java
#ServerEndpoint("/chat")
public class SocketServer {
// set to store all the live sessions
private static final Set<Session> sessions = Collections
.synchronizedSet(new HashSet<Session>());
// Mapping between session and person name
private static final HashMap<String, String> nameSessionPair = new HashMap<String, String>();
private JSONUtils jsonUtils = new JSONUtils();
// Getting query params
public static Map<String, String> getQueryMap(String query) {
Map<String, String> map = Maps.newHashMap();
if (query != null) {
String[] params = query.split("&");
for (String param : params) {
String[] nameval = param.split("=");
map.put(nameval[0], nameval[1]);
}
}
return map;
}
/**
* Called when a socket connection opened
* */
#OnOpen
public void onOpen(Session session) {
System.out.println(session.getId() + " has opened a connection");
Map<String, String> queryParams = getQueryMap(session.getQueryString());
String name = "";
if (queryParams.containsKey("name")) {
// Getting client name via query param
name = queryParams.get("name");
try {
name = URLDecoder.decode(name, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
// Mapping client name and session id
nameSessionPair.put(session.getId(), name);
}
// Adding session to session list
sessions.add(session);
try {
// Sending session id to the client that just connected
session.getBasicRemote().sendText(
jsonUtils.getClientDetailsJson(session.getId(),
"Your session details"));
} catch (IOException e) {
e.printStackTrace();
}
// Notifying all the clients about new person joined
sendMessageToAll(session.getId(), name, " joined conversation!", true, false);
}
/**
* method called when new message received from any client
*
* #param message
* JSON message from client
* */
#OnMessage
public void onMessage(String message, Session session) {
System.out.println("Message from " + session.getId() + ": " + message);
String msg = null;
// Parsing the json and getting message
try {
JSONObject jObj = new JSONObject(message);
msg = jObj.getString("message");
} catch (JSONException e) {
e.printStackTrace();
}
// Sending the message to all clients
sendMessageToAll(session.getId(), nameSessionPair.get(session.getId()),
msg, false, false);
}
/**
* Method called when a connection is closed
* */
#OnClose
public void onClose(Session session) {
System.out.println("Session " + session.getId() + " has ended");
// Getting the client name that exited
String name = nameSessionPair.get(session.getId());
// removing the session from sessions list
sessions.remove(session);
// Notifying all the clients about person exit
sendMessageToAll(session.getId(), name, " left conversation!", false, true);
}
/**
* Method to send message to all clients
*
* #param sessionId
* #param message
* message to be sent to clients
* #param isNewClient
* flag to identify that message is about new person joined
* #param isExit
* flag to identify that a person left the conversation
* */
private void sendMessageToAll(String sessionId, String name,
String message, boolean isNewClient, boolean isExit) {
// Looping through all the sessions and sending the message individually
for (Session s : sessions) {
String json = null;
// Checking if the message is about new client joined
if (isNewClient) {
json = jsonUtils.getNewClientJson(sessionId, name, message,
sessions.size());
} else if (isExit) {
// Checking if the person left the conversation
json = jsonUtils.getClientExitJson(sessionId, name, message, sessions.size());
} else {
// Normal chat conversation message
json = jsonUtils
.getSendAllMessageJson(sessionId, name, message);
}
try {
System.out.println("Sending Message To: " + sessionId + ", " + json);
s.getBasicRemote().sendText(json);
} catch (IOException e) {
System.out.println("error in sending. " + s.getId() + ", "
+ e.getMessage());
e.printStackTrace();
}
}
}
}
main.js
#ServerEndpoint("/chat")
public class SocketServer {
// set to store all the live sessions
private static final Set<Session> sessions = Collections
.synchronizedSet(new HashSet<Session>());
// Mapping between session and person name
private static final HashMap<String, String> nameSessionPair = new HashMap<String, String>();
private JSONUtils jsonUtils = new JSONUtils();
// Getting query params
public static Map<String, String> getQueryMap(String query) {
Map<String, String> map = Maps.newHashMap();
if (query != null) {
String[] params = query.split("&");
for (String param : params) {
String[] nameval = param.split("=");
map.put(nameval[0], nameval[1]);
}
}
return map;
}
/**
* Called when a socket connection opened
* */
#OnOpen
public void onOpen(Session session) {
System.out.println(session.getId() + " has opened a connection");
Map<String, String> queryParams = getQueryMap(session.getQueryString());
String name = "";
if (queryParams.containsKey("name")) {
// Getting client name via query param
name = queryParams.get("name");
try {
name = URLDecoder.decode(name, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
// Mapping client name and session id
nameSessionPair.put(session.getId(), name);
}
// Adding session to session list
sessions.add(session);
try {
// Sending session id to the client that just connected
session.getBasicRemote().sendText(
jsonUtils.getClientDetailsJson(session.getId(),
"Your session details"));
} catch (IOException e) {
e.printStackTrace();
}
// Notifying all the clients about new person joined
sendMessageToAll(session.getId(), name, " joined conversation!", true, false);
}
/**
* method called when new message received from any client
*
* #param message
* JSON message from client
* */
#OnMessage
public void onMessage(String message, Session session) {
System.out.println("Message from " + session.getId() + ": " + message);
String msg = null;
// Parsing the json and getting message
try {
JSONObject jObj = new JSONObject(message);
msg = jObj.getString("message");
} catch (JSONException e) {
e.printStackTrace();
}
// Sending the message to all clients
sendMessageToAll(session.getId(), nameSessionPair.get(session.getId()), msg, false, false);
}
/**
* Method called when a connection is closed
* */
#OnClose
public void onClose(Session session) {
System.out.println("Session " + session.getId() + " has ended");
// Getting the client name that exited
String name = nameSessionPair.get(session.getId());
// removing the session from sessions list
sessions.remove(session);
// Notifying all the clients about person exit
sendMessageToAll(session.getId(), name, " left conversation!", false, true);
}
/**
* Method to send message to all clients
*
* #param sessionId
* #param message
* message to be sent to clients
* #param isNewClient
* flag to identify that message is about new person joined
* #param isExit
* flag to identify that a person left the conversation
* */
private void sendMessageToAll(String sessionId, String name,
String message, boolean isNewClient, boolean isExit) {
// Looping through all the sessions and sending the message individually
for (Session s : sessions) {
String json = null;
// Checking if the message is about new client joined
if (isNewClient) {
json = jsonUtils.getNewClientJson(sessionId, name, message,
sessions.size());
} else if (isExit) {
// Checking if the person left the conversation
json = jsonUtils.getClientExitJson(sessionId, name, message, sessions.size());
} else {
// Normal chat conversation message
json = jsonUtils
.getSendAllMessageJson(sessionId, name, message);
}
try {
System.out.println("Sending Message To: " + sessionId + ", " + json);
s.getBasicRemote().sendText(json);
} catch (IOException e) {
System.out.println("error in sending. " + s.getId() + ", "
+ e.getMessage());
e.printStackTrace();
}
}
}
}
Firstly, the 404 code indicates that the element doesn't exist, then maybe your problem is the annotation #ServerEndpoint("/chat"), the HTTP request is looking for a /GroupChat/ element. Now, also you must review your settings files (web.xml, context.xml, application.xml, etc) because you could have an context attribute or display-name attribute misconfigured.
I hope this information helps you.
Good Luck.

Exception when saving a result

I am developping J2EE application with appfuse , i have a webform called easyVolAction that contain a method search() I need to save the result of search method in database but and an excpetion is generated when clicking in the action search :NullPointerException in object trajet .I created TrajetDaoHibernate:
public TrajetDaoHibernate() {
super(TrajetModel.class);
}
/**
* {#inheritDoc}
*/
#SuppressWarnings("unchecked")
public List<TrajetModel> getTrajet() {
Session session = getSessionFactory().getCurrentSession();
Query qry = session.createQuery("from TrajetModel u order by upper(u.id)");
return qry.list();
}
/**
* {#inheritDoc}
*/
public TrajetModel saveTrajet(TrajetModel trajet) {
if (log.isDebugEnabled()) {
log.debug("user's id: " + trajet.getId());
}
Session session = getSessionFactory().getCurrentSession();
session.saveOrUpdate(trajet);
// necessary to throw a DataIntegrityViolation and catch it in UserManager
session.flush();
return trajet;
}
#Override
public TrajetModel save(TrajetModel trajet) {
return this.saveTrajet(trajet);
}
and TrajetDao:
public interface TrajetDao extends GenericDao {
List<TrajetModel> getTrajet();
TrajetModel saveTrajet(TrajetModel trajet);
}
and trajetManager:
#Service("trajetManager")
public class TrajetModelImpl extends GenericManagerImpl<TrajetModel, Long> implements TrajetManager {
private TrajetDao trajetDao;
#Autowired
public void setTrajetModelDao(TrajetDao trajetDao) {
this.dao = trajetDao;
this.trajetDao = trajetDao;
}
/**
* {#inheritDoc}
*/
public TrajetModel getTrajet(String trajetId) {
return trajetDao.get(new Long(trajetId));
}
/**
* {#inheritDoc}
*/
public List<TrajetModel> getTrajet() {
return trajetDao.getAllDistinct();
}
/**
* {#inheritDoc}
*/
public TrajetModel saveTrajet(TrajetModel trajet) throws TrajetExistsException {
try {
return trajetDao.saveTrajet(trajet);
} catch (DataIntegrityViolationException e) {
//e.printStackTrace();
log.warn(e.getMessage());
throw new TrajetExistsException("Trajet '" + trajet.getNom() + "' already exists!");
} catch (JpaSystemException e) { // needed for JPA
//e.printStackTrace();
log.warn(e.getMessage());
throw new TrajetExistsException("Trajet '" + trajet.getNom() + "' already exists!");
}
}
}
finnaly the action where i declare the search method:
public String recherche() throws IOException, TrajetExistsException {
HttpServletRequest request = (HttpServletRequest) FacesContext
.getCurrentInstance().getExternalContext().getRequest();
// String url1 =
// FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("hidden");
String departAller = request.getParameter("easyVolRobot:villeDepart");
String arriveeAller = request.getParameter("easyVolRobot:villeArrivee");
String jourAller = request.getParameter("easyVolRobot:jourDep");
String moisAller = request.getParameter("easyVolRobot:dateDep");
String jourRetour = request.getParameter("easyVolRobot:jourDep");
String moisRetour = request.getParameter("easyVolRobot:dateArr");
String jourAllerPlus1 = jourAller + 1;
parametre = "departAller=" + departAller + "&arriveeAller="
+ arriveeAller + "&jourAller=" + jourAller + "&moisAller="
+ moisAller + "&jourRetour=" + jourRetour + "&moisRetour="
+ moisRetour;
parametre1 = "departAller=" + departAller + "&arriveeAller="
+ arriveeAller + "&jourAller=" + jourAllerPlus1 + "&moisAller="
+ moisAller + "&jourRetour=" + jourRetour + "&moisRetour="
+ moisRetour;
String response = sendGetRequest(url, parametre);
// insert();
PrintStream out = null;
try {
out = new PrintStream(new FileOutputStream(
"/data/crawl/root/siteSNCF.html"));
out.print(response);
} finally {
if (out != null)
out.close();
}
// tableau de resultats des trajets
List<TrajetModel> listTrajets = new ArrayList<TrajetModel>();
// trajet
//TrajetModel trajet = new TrajetModel();
File input = new File("/data/crawl/root/siteSNCF.html");
Document doc = Jsoup.parse(input, "UTF-8",
"http://www.easyvols.org/france-voyage");
for (Element vol : doc.select("div.vols")) {
//trajet = new TrajetModel();
for (Element allerRetour : vol.select("div.aller-retour")) {
Elements aeroport = allerRetour.select("div.aeroport");
System.out.println(aeroport.text());
Elements depart = allerRetour.select("div.depart");
Elements arrive = allerRetour.select("div.arrivee");
Elements date = allerRetour.select("div.date");
trajet.setNom(aeroport.text());
trajet.setVilleDepart(depart.text());
trajet.setVilleArrive(arrive.text());
trajet.sethArrive(12);
trajet.sethDepart(11);
trajet.sethReqt(14);
}
Elements prix2 = vol.select("div.tarif");
trajet.setPrice(prix2.text());
trajet = trajetManager.saveTrajet(trajet);
System.out.println(trajet);}
return"mainMenu";
}
why you comment this line out?
//TrajetModel trajet = new TrajetModel();
I see no other line where you create the TrajetModel.
If that object is not initiated you get the NPE here:
trajet.setNom(aeroport.text());

Categories

Resources