I had this error :
Cannot make a static reference to the non-static method
getApplicationContext() from the type ContextWrapper
please find the method that have the error registerInGCMService(Context context)
class:
package com.example.elarabygroup;
import com.google.android.gcm.GCMBaseIntentService;
import com.google.android.gcm.GCMRegistrar;
import android.content.Context;
import android.content.Intent;
import android.os.PowerManager;
import android.provider.Settings.Secure;
import android.util.Log;
public class GCMIntenetService extends GCMBaseIntentService {
private static final String GCM_SENDER_ID = "1111111111";
public GCMIntenetService() {
super();
}
#Override
protected void onRegistered(Context context, String registrationId) {
Log.i(TAG, "Device registered: regId = " + registrationId);
GCMRegistrar.setRegisteredOnServer(context, true);
}
#Override
protected void onUnregistered(Context context, String registrationId) {
Log.i(TAG, "Device unregistered");
if (GCMRegistrar.isRegisteredOnServer(context)) {
String regId = "";
Log.i(TAG, "unregistering device (regId = " + regId + ")");
GCMRegistrar.setRegisteredOnServer(context, false);
} else {
// This callback results from the call to unregister made on
// ServerUtilities when the registration to the server failed.
Log.i(TAG, "Ignoring unregister callback");
}
}
#Override
protected void onError(Context context, String errorId) {
// push error processing
}
#Override
protected void onMessage(Context arg0, Intent arg1) {
Log.i(TAG, "Received message");
Log.i(TAG, "EXTRAS" + arg1.getExtras());
// String message = getString(R.string.gcm_message);
generateNotification(arg0,
arg1.getStringExtra("Please download our new updates"));
// notifies user about message
}
private void generateNotification(Context arg0, String stringExtra) {
// TODO Auto-generated method stub
}
public static void registerInGCMService(Context context) {
GCM_SENDER_ID = Secure.getString(context.getApplicationContext().getContentResolver(),
Secure.ANDROID_ID);
if (!checkIsGCMServiceAvailable(context)) {
return;
}
final String regId = GCMRegistrar.getRegistrationId(context);
if (regId.equals("")) {
try {
GCMRegistrar.register(context, GCM_SENDER_ID);
} catch (Exception ex) {
}
} else {
// Already registered
}
}
public static boolean checkIsGCMServiceAvailable(Context context) {
try {
GCMRegistrar.checkDevice(context);
GCMRegistrar.checkManifest(context);
return true;
} catch (Throwable th) {
return false;
}
}
}
What you probably meant is :
context.getApplicationContext()
instead of
getApplicationContext()
Or you can try like this -
GCM_SENDER_ID = Secure.getString(context.getContentResolver(),
Secure.ANDROID_ID);
Sometime this error comes, when we are using "getConTentResolver()" in static method
like:
public static void Mthd()
{
Cursor cursor =getContentResolver().query(uri, null, null, null, null);
//ur next code
}
So, in this case it will give an error, Therefore we have to make the function non-static.
Related
I am trying to create push notification for my cordova project. I followed the tutorial from this link http://devgirl.org/2012/10/25/tutorial-android-push-notifications-with-phonegap/ and created the plugin and I see the FCM is not sending back the registration id. I have added sender id in my application. Please help me to get this done. Thanks in advance.
GCMIntentService.java
import org.json.JSONException;
import org.json.JSONObject;
import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import com.google.android.gcm.GCMBaseIntentService;
#SuppressLint("NewApi")
public class GCMIntentService extends GCMBaseIntentService {
private static final String TAG = "GCMIntentService";
public GCMIntentService() {
super("GCMIntentService");
}
#Override
public void onRegistered(Context context, String regId) {
Log.v(TAG, "onRegistered: "+ regId);
JSONObject json;
try
{
json = new JSONObject().put("event", "registered");
json.put("regid", regId);
Log.v(TAG, "onRegistered: " + json.toString());
// Send this JSON data to the JavaScript application above EVENT should be set to the msg type
// In this case this is the registration ID
PushPlugin.sendJavascript( json );
}
catch( JSONException e)
{
// No message to the user is sent, JSON failed
Log.e(TAG, "onRegistered: JSON exception");
}
}
#Override
public void onUnregistered(Context context, String regId) {
Log.d(TAG, "onUnregistered - regId: " + regId);
}
#Override
protected void onMessage(Context context, Intent intent) {
Log.d(TAG, "onMessage - context: " + context);
// Extract the payload from the message
Bundle extras = intent.getExtras();
if (extras != null)
{
// if we are in the foreground, just surface the payload, else post it to the statusbar
if (PushPlugin.isInForeground()) {
extras.putBoolean("foreground", true);
createNotification(context, extras);
PushPlugin.sendExtras(extras);
}
else {
extras.putBoolean("foreground", false);
// Send a notification if there is a message
if (extras.getString("message") != null && extras.getString("message").length() != 0) {
createNotification(context, extras);
}
}
}
}
public void createNotification(Context context, Bundle extras)
{
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
String appName = getAppName(this);
Intent notificationIntent = new Intent(this, PushHandlerActivity.class);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
notificationIntent.putExtra("pushBundle", extras);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
int defaults = Notification.DEFAULT_ALL;
if (extras.getString("defaults") != null) {
try {
defaults = Integer.parseInt(extras.getString("defaults"));
} catch (NumberFormatException e) {}
}
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context)
.setDefaults(defaults)
.setSmallIcon(context.getApplicationInfo().icon)
.setWhen(System.currentTimeMillis())
.setContentTitle(extras.getString("title"))
.setContentText(extras.getString("title"))
.setTicker(extras.getString("title"))
.setContentIntent(contentIntent)
.setAutoCancel(true);
String message = extras.getString("message");
if (message != null) {
mBuilder.setContentText(message);
} else {
mBuilder.setContentText("<missing message content>");
}
String msgcnt = extras.getString("msgcnt");
if (msgcnt != null) {
mBuilder.setNumber(Integer.parseInt(msgcnt));
}
int notId = 0;
try {
notId = Integer.parseInt(extras.getString("notId"));
}
catch(NumberFormatException e) {
Log.e(TAG, "Number format exception - Error parsing Notification ID: " + e.getMessage());
}
catch(Exception e) {
Log.e(TAG, "Number format exception - Error parsing Notification ID" + e.getMessage());
}
mNotificationManager.notify((String) appName, notId, mBuilder.build());
}
private static String getAppName(Context context)
{
CharSequence appName =
context
.getPackageManager()
.getApplicationLabel(context.getApplicationInfo());
return (String)appName;
}
#Override
public void onError(Context context, String errorId) {
Log.e(TAG, "onError - errorId: " + errorId);
}
}
PushPlugin.Java
import java.util.Iterator;
import org.apache.cordova.CordovaWebView;
import org.apache.cordova.api.Plugin;
import org.apache.cordova.api.PluginResult;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import com.google.android.gcm.GCMRegistrar;
import android.os.Bundle;
import android.util.Log;
public class PushPlugin extends Plugin {
public static final String TAG = "PushPlugin";
public static final String REGISTER = "register";
public static final String UNREGISTER = "unregister";
public static final String EXIT = "exit";
private static CordovaWebView gWebView;
private static String gECB;
private static String gSenderID;
private static Bundle gCachedExtras = null;
private static boolean gForeground = false;
#Override
public PluginResult execute(String action, JSONArray data, String CallbackContext) {
// TODO Auto-generated method stub
boolean result = false;
Log.v(TAG, "execute: action=" + action);
if (REGISTER.equals(action)) {
Log.v(TAG, "execute: data=" + data.toString());
try {
JSONObject jo = data.getJSONObject(0);
gWebView = this.webView;
Log.v(TAG, "execute: jo=" + jo.toString());
gECB = (String) jo.get("ecb");
gSenderID = (String) jo.get("senderID");
Log.v(TAG, "execute: ECB=" + gECB + " senderID=" + gSenderID);
GCMRegistrar.register(this.cordova.getActivity(), gSenderID);
result = true;
// callbackContext.success();
} catch (JSONException e) {
Log.e(TAG, "execute: Got JSON Exception " + e.getMessage());
result = false;
// callbackContext.error(e.getMessage());
}
if ( gCachedExtras != null) {
Log.v(TAG, "sending cached extras");
sendExtras(gCachedExtras);
gCachedExtras = null;
}
}else if (UNREGISTER.equals(action)) {
GCMRegistrar.unregister(this.cordova.getActivity());
Log.v(TAG, "UNREGISTER");
result = true;
// callbackContext.success();
} else {
result = false;
Log.e(TAG, "Invalid action : " + action);
//callbackContext.error("Invalid action : " + action);
}
return new PluginResult(PluginResult.Status.OK);
//return null;
}
public static void sendExtras(Bundle extras)
{
if (extras != null) {
if (gECB != null && gWebView != null) {
sendJavascript(convertBundleToJson(extras));
} else {
Log.v(TAG, "sendExtras: caching extras to send at a later time.");
gCachedExtras = extras;
}
}
}
private static JSONObject convertBundleToJson(Bundle extras)
{
try
{
JSONObject json;
json = new JSONObject().put("event", "message");
JSONObject jsondata = new JSONObject();
Iterator<String> it = extras.keySet().iterator();
while (it.hasNext())
{
String key = it.next();
Object value = extras.get(key);
// System data from Android
if (key.equals("from") || key.equals("collapse_key"))
{
json.put(key, value);
}
else if (key.equals("foreground"))
{
json.put(key, extras.getBoolean("foreground"));
}
else if (key.equals("coldstart"))
{
json.put(key, extras.getBoolean("coldstart"));
}
else
{
// Maintain backwards compatibility
if (key.equals("message") || key.equals("msgcnt") || key.equals("soundname"))
{
json.put(key, value);
}
if ( value instanceof String ) {
// Try to figure out if the value is another JSON object
String strValue = (String)value;
if (strValue.startsWith("{")) {
try {
JSONObject json2 = new JSONObject(strValue);
jsondata.put(key, json2);
}
catch (Exception e) {
jsondata.put(key, value);
}
// Try to figure out if the value is another JSON array
}
else if (strValue.startsWith("["))
{
try
{
JSONArray json2 = new JSONArray(strValue);
jsondata.put(key, json2);
}
catch (Exception e)
{
jsondata.put(key, value);
}
}
else
{
jsondata.put(key, value);
}
}
}
} // while
json.put("payload", jsondata);
Log.v(TAG, "extrasToJSON: " + json.toString());
return json;
}
catch( JSONException e)
{
Log.e(TAG, "extrasToJSON: JSON exception");
}
return null;
}
public static void sendJavascript(JSONObject _json) {
String _d = "javascript:" + gECB + "(" + _json.toString() + ")";
Log.v(TAG, "sendJavascript: " + _d);
if (gECB != null && gWebView != null) {
gWebView.sendJavascript(_d);
}
}
public static boolean isInForeground()
{
return gForeground;
}
public static boolean isActive()
{
return gWebView != null;
}
}
PushHandlerActivity.java
import android.app.Activity;
import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.util.Log;
public class PushHandlerActivity extends Activity
{
private static String TAG = "PushHandlerActivity";
/*
* this activity will be started if the user touches a notification that we own.
* We send it's data off to the push plugin for processing.
* If needed, we boot up the main activity to kickstart the application.
* #see android.app.Activity#onCreate(android.os.Bundle)
*/
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Log.v(TAG, "onCreate");
boolean isPushPluginActive = PushPlugin.isActive();
processPushBundle(isPushPluginActive);
finish();
if (!isPushPluginActive) {
forceMainActivityReload();
}
}
/**
* Takes the pushBundle extras from the intent,
* and sends it through to the PushPlugin for processing.
*/
private void processPushBundle(boolean isPushPluginActive)
{
Bundle extras = getIntent().getExtras();
if (extras != null) {
Bundle originalExtras = extras.getBundle("pushBundle");
originalExtras.putBoolean("foreground", false);
originalExtras.putBoolean("coldstart", !isPushPluginActive);
PushPlugin.sendExtras(originalExtras);
}
}
/**
* Forces the main activity to re-launch if it's unloaded.
*/
private void forceMainActivityReload()
{
PackageManager pm = getPackageManager();
Intent launchIntent = pm.getLaunchIntentForPackage(getApplicationContext().getPackageName());
startActivity(launchIntent);
}
#Override
protected void onResume() {
super.onResume();
final NotificationManager notificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancelAll();
}
}
Manifeast file
<uses-permission android:name="android.permission.BROADCAST_STICKY" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission
android:name="MyPackageName".push.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<activity android:name="MyPackageName".push.PushHandlerActivity"/>
<receiver android:name="MyPackageName".push.CordovaGCMBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="MyPackageName".push" />
</intent-filter>
</receiver>
<service android:name="MyPackageName".push.GCMIntentService" />
I have been trying to incorporate MQTT into one of my Android applications. I originally had it working within an activity and have since tried to move it to a service to run in the background. Im able to connect and send messages from the service but Im not able to receive messages. My service implements MqttCallback and overrides the messageReceived() function but it never seems to get called. Can someone help me understand why the callback is not firing?
package com.example.test;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttClientPersistence;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.MqttToken;
import org.eclipse.paho.client.mqttv3.MqttTopic;
import org.eclipse.paho.client.mqttv3.persist.MqttDefaultFilePersistence;
import android.app.Service;
import android.content.Intent;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
public class MqttService extends Service implements MqttCallback{
final static String MY_ACTION = "MqttService";
String username;
//MQTT Variables
MqttClient mySubClient;
MqttConnectOptions connOpt;
String BROKER_URL;
String PUB_TOPIC;
String SUB_TOPIC;
String PUB_CLIENT_ID;
String SUB_CLIENT_ID;
Boolean MqttConnState;
Boolean IsRunning;
static final String TOPIC_BASE = MyProperties.TOPIC_BASE;
static final String PI_BROKER_URL = MyProperties.PI_BROKER_URL; //no encryption
static final String PI_SSL_BROKER_URL = MyProperties.PI_SSL_BROKER_URL; //ssl enabled
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("log_mqtt_service", "Service onStartCommand entered");
//Get session id from previous activity
Bundle extras = intent.getExtras();
if (extras != null) {
username = extras.getString("SESSION_ID");
}
//set mqtt vars
BROKER_URL = PI_BROKER_URL;
PUB_CLIENT_ID = "My-Pub-" + username;
SUB_CLIENT_ID = "My-Sub-" + username;
SUB_TOPIC = TOPIC_BASE + username;
PUB_TOPIC = TOPIC_BASE + "test";
IsRunning = false;
MqttThread myThread = new MqttThread();
myThread.start();
return super.onStartCommand(intent, flags, startId);
}
public class MqttThread extends Thread{
#Override
public void run() {
if(IsRunning==false)
{
IsRunning = true;
connMqtt();
}
while(IsRunning){
//keep thread running
Log.i("log_mqtt_thread_send", "thread sending mqtt message");
sendMsg(PUB_TOPIC, "0x0001", "Message from " + PUB_CLIENT_ID);
}
Log.i("log_mqtt_thread", "thread stopped");
}
}
#Override
public void onDestroy()
{
super.onDestroy();
try {
mySubClient.disconnect();
} catch (MqttException e) {
Log.e ("log_mqtt_disconnect",e.toString());
}
}
#Override
public void connectionLost(Throwable cause) {
// TODO Auto-generated method stub
}
#Override
public void messageArrived(String topic, MqttMessage message)
throws Exception {
String msgStr;
msgStr = new String(message.getPayload());
Log.i("log_mqtt_Rx", "-------------------------------------------------");
Log.i("log_mqtt_Rx", "| Topic: " + topic.toString());
Log.i("log_mqtt_Rx", "| Message: " + msgStr);
Log.i("log_mqtt_Rx", "-------------------------------------------------");
Intent intent = new Intent();
intent.setAction(MY_ACTION);
intent.putExtra("RX_MESSAGE", msgStr);
sendBroadcast(intent);
}
#Override
public void deliveryComplete(IMqttDeliveryToken token) {
// TODO Auto-generated method stub
}
// ------------------------------------------------------------------------
// Function to make mqtt connection and subscribe
// ------------------------------------------------------------------------
int connMqtt()
{
int result=0;
MqttClientPersistence persistence = new MqttDefaultFilePersistence(getBaseContext().getApplicationInfo().dataDir);
try{
Log.i("log_mqtt","mqtt start");
try{
// setup MQTT Client
connOpt = new MqttConnectOptions();
connOpt.setCleanSession(true);
connOpt.setKeepAliveInterval(30);
Log.i("log_mqtt","connOpt vars setup");
}catch(Exception e){
result = -1;
Log.e ("log_mqtt",e.toString());
}
// Connect to Broker for Subscriber connection
try {
mySubClient = new MqttClient(BROKER_URL, SUB_CLIENT_ID, persistence);
Log.i("log_mqtt_conn","create mqttClient");
mySubClient.connect(connOpt);
Log.i("log_mqtt_conn","MQTT client connected to " + BROKER_URL);
} catch (MqttException e) {
result = -2;
Log.i ("log_mqtt_conn","BROKER: " + BROKER_URL);
Log.i ("log_mqtt_conn","SUB_CLIENT_ID: " + SUB_CLIENT_ID);
Log.e ("log_mqtt_conn",e.toString());
}
try {
int subQoS = 0;
mySubClient.subscribe(SUB_TOPIC, subQoS);
Log.i("log_mqtt_sub","mqtt client subscribed to \"" + SUB_TOPIC + "\"");
} catch (Exception e) {
result = -3;
Log.e ("log_mqtt_sub",e.toString());
}
}catch(Exception e){
result = -4;
Log.e ("log_mqtt",e.toString());
}
return result;
}
// ------------------------------------------------------------------------
// Function to send mqtt message to a topic
// ------------------------------------------------------------------------
public void sendMsg(String sendTopic, String msgid, String msg)
{
String timeStamp = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(Calendar.getInstance().getTime());
String pubMsg = "{\"msgid\":\"" + msgid + "\",\"time\":\"" + timeStamp + "\", \"message\":\"" + msg + "\"}";
int pubQoS = 0;
MqttMessage message = new MqttMessage(pubMsg.getBytes());
message.setQos(pubQoS);
message.setRetained(false);
//Topic for publisher
MqttTopic pubTopic = mySubClient.getTopic(sendTopic);
// Publish the message
Log.i("log_mqtt_send","Publishing to topic \"" + pubTopic + "\" qos " + pubQoS);
Log.i("log_mqtt_msg", pubMsg);
MqttDeliveryToken token = null;
try {
// Publish message to broker then disconnect
token = pubTopic.publish(message);
// Wait until the message has been delivered to the broker
token.waitForCompletion();
Thread.sleep(1000);
} catch (Exception ex) {
Log.e("log_mqtt_error",ex.toString());
}
}
}
You have to add Callback on your 'mySubClient.setCallBack' then only your callback methods will get called.
I am new to GCM and CCS. I have setup GCM using PHP by referring this link.
Now I am trying to jump from HTTP to CCS but I am not able to register CCS.
Here is my code:
import java.io.IOException;
import java.util.concurrent.atomic.AtomicInteger;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import com.google.android.gms.gcm.GoogleCloudMessaging;
import com.squareup.picasso.Picasso;
public class RegisterActivity extends Activity {
Button btnGCMRegister;
Button btnXmppRegiser;
Button btnSendMessage;
GoogleCloudMessaging gcm;
Context context;
String regId;
AsyncTask<Void, Void, String> sendTask;
AtomicInteger ccsMsgId = new AtomicInteger();
static final String GOOGLE_PROJECT_ID = "306923*****";
public static final String REG_ID = "regId";
private static String APP_VERSION = "appVersion";
static final String TAG = "Register Activity";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
context = getApplicationContext();
APP_VERSION = getAppVersion(context)+"";
btnGCMRegister = (Button) findViewById(R.id.btnGCMRegister);
btnGCMRegister.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
if (TextUtils.isEmpty(regId)) {
regId = registerGCM();
Log.d("RegisterActivity", "GCM RegId: " + regId);
} else {
Toast.makeText(getApplicationContext(),
"Already Registered with GCM Server!",
Toast.LENGTH_LONG).show();
}
}
});
btnXmppRegiser = (Button) findViewById(R.id.btnXmppRegiser);
btnXmppRegiser.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
if (TextUtils.isEmpty(regId)) {
Toast.makeText(getApplicationContext(), "RegId is empty!",
Toast.LENGTH_LONG).show();
} else {
sendMessage("REGISTER");
}
}
});
btnSendMessage = (Button) findViewById(R.id.btnSendMessage);
btnSendMessage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
if (TextUtils.isEmpty(regId)) {
Toast.makeText(getApplicationContext(), "RegId is empty!",
Toast.LENGTH_LONG).show();
} else {
sendMessage("ECHO");
}
}
});
}
private void sendMessage(final String action) {
sendTask = new AsyncTask<Void, Void, String>() {
#Override
protected String doInBackground(Void... params) {
Bundle data = new Bundle();
data.putString("ACTION", action);
data.putString("CLIENT_MESSAGE", "Hello GCM CCS XMPP!");
String id = Integer.toString(ccsMsgId.incrementAndGet());
try {
Log.d("RegisterActivity", "messageid: " + id);
gcm.send(GOOGLE_PROJECT_ID + "#gcm.googleapis.com", id,
data);
Log.d("RegisterActivity", "After gcm.send successful.");
} catch (IOException e) {
Log.d("RegisterActivity", "Exception: " + e);
e.printStackTrace();
}
return "Sent message.";
}
#Override
protected void onPostExecute(String result) {
sendTask = null;
Toast.makeText(getApplicationContext(), result,
Toast.LENGTH_LONG).show();
}
};
sendTask.execute(null, null, null);
}
public String registerGCM() {
gcm = GoogleCloudMessaging.getInstance(this);
regId = getRegistrationId(context);
if (TextUtils.isEmpty(regId)) {
registerInBackground();
Log.d("RegisterActivity",
"registerGCM - successfully registered with GCM server - regId: "
+ regId);
} else {
Toast.makeText(getApplicationContext(),
"RegId already available. RegId: " + regId,
Toast.LENGTH_LONG).show();
}
return regId;
}
private String getRegistrationId(Context context) {
final SharedPreferences prefs = getSharedPreferences(
RegisterActivity.class.getSimpleName(), Context.MODE_PRIVATE);
String registrationId = prefs.getString(REG_ID, "");
if (registrationId.isEmpty()) {
Log.i(TAG, "Registration not found.");
return "";
}
int registeredVersion = prefs.getInt(APP_VERSION, Integer.MIN_VALUE);
int currentVersion = getAppVersion(context);
if (registeredVersion != currentVersion) {
Log.i(TAG, "App version changed.");
return "";
}
return registrationId;
}
private static int getAppVersion(Context context) {
try {
PackageInfo packageInfo = context.getPackageManager()
.getPackageInfo(context.getPackageName(), 0);
return packageInfo.versionCode;
} catch (NameNotFoundException e) {
Log.d("RegisterActivity",
"I never expected this! Going down, going down!" + e);
throw new RuntimeException(e);
}
}
private void registerInBackground() {
new AsyncTask<Void, Void, String>() {
#Override
protected String doInBackground(Void... params) {
String msg = "";
try {
if (gcm == null) {
gcm = GoogleCloudMessaging.getInstance(context);
}
regId = gcm.register(GOOGLE_PROJECT_ID);
Log.d("RegisterActivity", "registerInBackground - regId: "
+ regId);
msg = "Device registered, registration ID=" + regId;
storeRegistrationId(context, regId);
} catch (IOException ex) {
msg = "Error :" + ex.getMessage();
Log.d("RegisterActivity", "Error: " + msg);
}
Log.d("RegisterActivity", "AsyncTask completed: " + msg);
return msg;
}
#Override
protected void onPostExecute(String msg) {
Toast.makeText(getApplicationContext(),
"Registered with GCM Server." + msg, Toast.LENGTH_LONG)
.show();
}
}.execute(null, null, null);
}
private void storeRegistrationId(Context context, String regId) {
final SharedPreferences prefs = getSharedPreferences(
RegisterActivity.class.getSimpleName(), Context.MODE_PRIVATE);
int appVersion = getAppVersion(context);
Log.i(TAG, "Saving regId on app version " + appVersion);
SharedPreferences.Editor editor = prefs.edit();
editor.putString(REG_ID, regId);
editor.putInt(APP_VERSION, appVersion);
editor.commit();
}
}
I am using the hidden APIs of the Android SDK in my code (i.e.ITelephony), but my broadcast receiver class is not getting active when a call comes. Because of that, my call is not getting ended.
I have used broadcast receiver inside an activity because I want to use context of an activity for some displaying purpose. I do not get where the problem is! Please help.
package com.example.callprio;
import java.lang.reflect.Method;
import android.app.Activity;
import android.app.ActivityManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.telephony.PhoneStateListener;
import android.telephony.SmsManager;
import android.telephony.TelephonyManager;
import android.util.Log;
import com.android.internal.telephony.ITelephony;
public class MyCallBroadcastReceiver extends Activity
{
private static final boolean USE_ITELEPHONY = true;
/**
* AIDL access to the telephony service process
*/
private ITelephony telephonyService;
private BroadcastReceiver receiver=new BroadcastReceiver()
{
private String id;
public void onReceive(Context context, Intent intent) {
telephony = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
MyPhoneStateListener customPhoneListener = new MyPhoneStateListener();
telephony.listen(customPhoneListener, PhoneStateListener.LISTEN_CALL_STATE);
Bundle bundle = intent.getExtras();
phone_number = bundle.getString("incoming_number");
System.out.println("Phone Number : " + phone_number);
Log.i("phone_number", phone_number);
Uri myPhoneUri = Uri.withAppendedPath(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI, phone_number);
// Query the table
Cursor phoneCursor = MyCallBroadcastReceiver.this.getContentResolver().query(
myPhoneUri, null, null, null, null);
// Get the phone numbers from the contact
for (phoneCursor.moveToFirst(); !phoneCursor.isAfterLast();
phoneCursor.moveToNext())
{
// Get a phone number id
id = phoneCursor.getString(phoneCursor
.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone._ID));
Log.i("Contact_id", id);
// sb.append("Phone: " + phoneNumber + "\n");
}
connectToTelephonyService();
Log.i("After connectToTelephonyService()", "Telephony service connected");
fetchPrioById(id);
}
};
private TelephonyManager telephony;
private MyPhoneStateListener customPhoneListener;
private String phone_number;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.main);
}
#Override
protected void onResume() {
this.registerReceiver(receiver, new IntentFilter("android.intent.action.PHONE_STATE"));
super.onResume();
}
#Override
protected void onPause() {
this.unregisterReceiver(receiver);
super.onPause();
}
protected void onDestroy() {
telephony.listen(customPhoneListener, PhoneStateListener.LISTEN_NONE);
}
/**
* get an instance of ITelephony to talk handle calls with
*/
#SuppressWarnings("unchecked") private void connectToTelephonyService() {
try
{
// "cheat" with Java reflection to gain access to TelephonyManager's ITelephony
Class c = Class.forName(telephony.getClass().getName());
Method m = c.getDeclaredMethod("getITelephony");
m.setAccessible(true);
telephonyService = (ITelephony)m.invoke(telephony);
} catch (Exception e) {
e.printStackTrace();
Log.e("TAG",
"FATAL ERROR: could not connect to telephony subsystem");
Log.e("TAG", "Exception object: " + e);
finish();
}
}
protected void fetchPrioById(String id) {
int prio=0;
int cid=Integer.parseInt(id);
String query="SELECT priority FROM Call WHERE contact_id="+cid;
DatabaseAdapter databaseAdapter = new DatabaseAdapter(getApplicationContext());
databaseAdapter.open();
Cursor cursor=null;
cursor= databaseAdapter.getSQLiteDatabase().rawQuery(query,null);
if (cursor != null)
{
//that means priority is assigned take prio from table
if (cursor.moveToFirst())
{
prio = cursor.getInt(cursor.getColumnIndex("priority"));
}
}
if(prio==0)
{
ignoreCall();
}
else if(prio==1)
{
onSilent();
}
else if(prio==3)
{
sendMessage();
}
else if (cursor == null)
{
//means priority is not assigned so default behaviour i.e. lower prio
ignoreCall();
}
cursor.close();
databaseAdapter.open();
}//FetchFunc
private void sendMessage() {
// TODO Auto-generated method stub
ignoreCall();
String message="I am in meeting,Call you later";
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(phone_number, null, message, null, null);
}
private void onSilent() {
telephonyService.silenceRinger();
}
private void ignoreCall() {
if (USE_ITELEPHONY)
ignoreCallAidl();
else
ignoreCallPackageRestart();
}
/**
* package restart technique for ignoring calls
*/
private void ignoreCallPackageRestart() {
ActivityManager am = (ActivityManager)getSystemService(ACTIVITY_SERVICE);
am.restartPackage("com.android.providers.telephony");
am.restartPackage("com.android.phone");
}
/**
* AIDL/ITelephony technique for ignoring calls
*/
private void ignoreCallAidl() {
try
{
telephonyService.silenceRinger();
telephonyService.endCall();
}
catch(Exception e)
{
e.printStackTrace();
Log.e("EXCEPTION","FATAL ERROR: call to service method endCall failed.");
Log.e("TAG", "Exception object: " + e);
}
}
}//class Activity ends here
I had some errors on "" class when I was handling the GCM .
the error appeared here :
onHandleIntent(Intent intent)
"Cannot override the final method from GCMBaseIntentService"
handleRegistration
"The method handleRegistration(Context, Intent) in the type
GCMBaseIntentService is not applicable for the arguments (Intent)"
handleMessage
"The method handleMessage(Intent) is undefined for the type
GCMIntenetService"
public final void onHandleIntent(Intent intent) {
try {
String action = intent.getAction();
if (action.equals("com.google.android.c2dm.intent.REGISTRATION")) {
handleRegistration(intent);
} else if (action.equals("com.google.android.c2dm.intent.RECEIVE")) {
handleMessage(intent);
}
} finally {
synchronized (LOCK) {
sWakeLock.release();
}
}
}
class
package com.example.elarabygroup;
import com.google.android.gcm.GCMBaseIntentService;
import android.content.Context;
import android.content.Intent;
import android.os.PowerManager;
import android.util.Log;
public class GCMIntenetService extends GCMBaseIntentService {
public static String TAG = "GCMIntentService";
private static PowerManager.WakeLock sWakeLock;
private static final Object LOCK = GCMIntenetService.class;
/*Handling Intents sent by GCM*/
static void runIntentInService(Context context, Intent intent) {
synchronized (LOCK) {
if (sWakeLock == null) {
PowerManager pm = (PowerManager) context
.getSystemService(Context.POWER_SERVICE);
sWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
"my_wakelock");
}
}
sWakeLock.acquire();
intent.setClassName(context, GCMIntenetService.class.getName());
context.startService(intent);
}
public GCMIntenetService(String senderId) {
super(senderId);
// TODO Auto-generated constructor stub
Log.d(TAG, "[GCMIntentService] start - sender Id : " + senderId);
}
#Override
protected void onError(Context arg0, String arg1) {
Log.d("onError", arg1);
}
#Override
protected boolean onRecoverableError(Context context, String errorId) {
Log.d("onRecoverableError", errorId);
return false;
}
#Override
/*
* protected void onMessage(Context arg0, Intent arg1) { Log.d("onMessage",
* String.valueOf(arg1)); }
*/
protected void onMessage(Context arg0, Intent arg1) {
Log.d("GCM", "RECIEVED A MESSAGE");
// Get the data from intent and send to notificaion bar
generateNotification(arg0, arg1.getStringExtra("**notificaion**"));
}
private void generateNotification(Context arg0, String stringExtra) {
// TODO Auto-generated method stub
}
#Override
protected void onRegistered(intent) {
try {
String action = intent.getAction();
if (action.equals("com.google.android.c2dm.intent.REGISTRATION")) {
handleRegistration(intent);
} else if (action.equals("com.google.android.c2dm.intent.RECEIVE")) {
handleMessage(intent);
}
} finally {
synchronized (LOCK) {
sWakeLock.release();
}
}
}
#Override
protected void onUnregistered(Context arg0, String arg1) {
Log.d("onUnregistered", arg1);
}
}
You shouldn't override final methods of GCMBaseIntentService. You need ovveride only callback methods of this base class. Here is an example:
public class GCMIntentService extends GCMBaseIntentService {
private static final String GCM_SENDER_ID = "your_sender_id";
public GCMIntentService() {
super();
}
#Override
protected void onRegistered(Context context, String gcmDeviceToken) {
// remember and save somewhere "gcmDeviceToken"
}
#Override
protected void onUnregistered(Context context, String s) {
// Push unregistered processing
}
#Override
protected void onError(Context context, String errorId) {
// push error processing
}
#Override
protected void onMessage(Context context, Intent intent) {
// process Push message
}
public static void registerInGCMService(Context context) {
if (!checkIsGCMServiceAvailable(context)) {
return;
}
final String regId = GCMRegistrar.getRegistrationId(context);
if (regId.equals("")) {
try {
GCMRegistrar.register(context, GCM_SENDER_ID);
} catch (Exception ex) {
}
} else {
// Already registered
}
}
public static boolean checkIsGCMServiceAvailable(Context context) {
try {
GCMRegistrar.checkDevice(context);
GCMRegistrar.checkManifest(context);
return true;
} catch (Throwable th) {
return false;
}
}
}
UPDATE: please note - you should change value of GCM_SENDER_ID constant with your own, it should be numeric value, something like "1234567890123"
#Override
protected void onRegistered(Context context, String registrationId) {
Log.i(TAG, "Device registered: regId = " + registrationId);
GCMRegistrar.setRegisteredOnServer(context, true);
}
#Override
protected void onMessage(Context context, Intent intent) {
Log.i(TAG, "Received message");
Log.i(TAG, "EXTRAS" + intent.getExtras());
String message = getString(R.string.gcm_message);
// notifies user about message
}
#Override
protected void onUnregistered(Context context, String registrationId) {
Log.i(TAG, "Device unregistered");
if (GCMRegistrar.isRegisteredOnServer(context)) {
Log.i(TAG, "unregistering device (regId = " + regId + ")");
GCMRegistrar.setRegisteredOnServer(context, false);
} else {
// This callback results from the call to unregister made on
// ServerUtilities when the registration to the server failed.
Log.i(TAG, "Ignoring unregister callback");
}
}
See GCM google tutorial http://developer.android.com/guide/google/gcm/gs.html