I'm trying to implement a Server-Client communication via Push from Server to Client. Since the Client is an Android device, I'm using Google Cloud Messaging to fulfill pushing a message from server to android device. I followed this tutorial
Current status: The Client get's the Registry ID from GCM. So the client - GCM communication should be fine. The Server get's the following message while trying to push the message to gcm :
2015-01-20T23:31:24.289+0100|Information: Response Code : 200
2015-01-20T23:31:24.290+0100|Information: {"multicast_id":534481856434...,"success":1,"failure":0,"canonical_ids":0,"results":[{"message_id":"0:1421793086402018%64d756d9f9fd7ecd"}]}
2015-01-20T23:31:24.296+0100|Information: com.sun.enterprise.web.connector.coyote.PECoyoteResponse$PECoyoteWriter#49...
It seems like the connection between client - gcm is working. But the gcm doesn't forward the message to my client.
My gcm project is also showing just 2 requests and over 2000 errors. I don't know that much about push notification to handle this issue, maybe somebody could help me.
Here's my code
Client MainActivity
// ... some other imports
import com.google.android.gms.gcm.GoogleCloudMessaging;
public class MainActivity extends ActionBarActivity implements OnCheckedChangeListener {
GoogleCloudMessaging gcm;
String regid;
String PROJECT_NUMBER = pn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getRegId();
}
public void getRegId() {
new AsyncTask<Void, Void, String>() {
#Override
protected String doInBackground(Void... params) {
// TODO Auto-generated method stub
String msg = "";
try {
if (gcm == null) {
gcm = GoogleCloudMessaging.getInstance(getApplicationContext());
}
regid = gcm.register(PROJECT_NUMBER);
msg = "Device registered, registration ID = " + regid;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
msg = "Error: " + e.getMessage();
}
Log.d("Systemablauf", "MainActivity getRegId() " + msg);
return msg;
}
}.execute(null, null, null);
}
}
Client MessageHandler
import com.google.android.gms.gcm.GoogleCloudMessaging;
public class GcmMessageHandler extends IntentService {
String msg;
private Handler handler;
public GcmMessageHandler(String name) {
super("GcmMessageHandler");
// TODO Auto-generated constructor stub
}
#Override
public void onCreate() {
super.onCreate();
handler = new Handler();
}
#Override
protected void onHandleIntent(Intent intent) {
// TODO Auto-generated method stub
Bundle extras = intent.getExtras();
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
// The getMessageType() intent parameter must be the intent you received
// in your BroadcastReceiver.
String messageType = gcm.getMessageType(intent);
msg = extras.getString("title");
showToast();
Log.d("Systemablauf", "Received: (" + messageType + ") " + extras.getString("title"));
GcmBroadcastReceiver.completeWakefulIntent(intent);
}
private void showToast() {
// TODO Auto-generated method stub
handler.post(new Runnable() {
public void run() {
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();
}
});
}
}
Client BroadcastReceiver
public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
// Explicitly specify that GcmMessageHandler will handle the intent.
ComponentName comp = new ComponentName(context.getPackageName(), GcmMessageHandler.class.getName());
// Start the service, keeping the device awake while it is launching.
startWakefulService(context, (intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
Log.d("Systemablauf", "onReceive()");
}
}
Client Manifest
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xml>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="thesis.com.example.clientsync"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="21" />
<uses-permission
android:name="android.permission.INTERNET"/>
<uses-permission
android:name="android.permission.VIBRATE"/>
<uses-permission
android:name="android.permission.GET_ACCOUNTS"/>
<uses-permission
android:name="android.permission.WAKE_LOCK"/>
<uses-permission
android:name="com.google.android.c2dm.permission.RECEIVE"/>
<permission
android:name="thesis.com.example.clientsync.permission.C2D_MESSAGE"
android:protectionLevel="signature"/>
<uses-permission
android:name="thesis.com.example.clientsync.permission.C2D_MESSAGE" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver
android:name=".GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action
android:name="com.google.android.c2dm.intent.RECEIVE" />
<category
android:name="thesis.com.example.clientsync" />
</intent-filter>
</receiver>
<meta-data android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<service
android:name="service.MainService" />
</application>
</manifest>
Server Servlet
#WebServlet("/ServerServlet")
public class ServerServlet extends HttpServlet {
public ServerServlet() {
super();
// TODO Auto-generated constructor stub
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
sendNotification();
}
private void sendNotification() {
System.out.println("Sending POST to GCM");
String apiKey = "AIzaSyA0pOZf13cZzqQHrWBZfFE9XFMHA5ftiAo";
Content content = createContent();
POST2GCM.post(apiKey, content);
}
private static Content createContent() {
// TODO Auto-generated method stub
Content c = new Content();
c.addRegId("APA91bFrSX_mGLzLUf2Va6...");
c.createData("Test Title", "Test Message");
return c;
}
}
Server Post
public class POST2GCM {
public static void post(String apiKex, Content content) {
String apiKey = "AIzaSyA0pO...";
try {
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 = " + apiKey);
connection.setDoOutput(true);
Gson gsonMapper = new GsonBuilder().create();
DataOutputStream writer = new DataOutputStream(connection.getOutputStream());
writer.writeBytes(gsonMapper.toJson(content));
writer.flush();
writer.close();
int responseCode = connection.getResponseCode();
System.out.println("\nSending 'POST' request to URL: " + url);
System.out.println("Response Code : " + responseCode);
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null)
response.append(inputLine);
in.close();
System.out.println(response.toString());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Server Content
#SuppressWarnings("serial")
public class Content implements Serializable {
private List<String> registration_ids;
private Map<String, String> data;
public void addRegId (String regId) {
if (registration_ids == null)
registration_ids = new LinkedList<String>();
registration_ids.add(regId);
}
public void createData (String title, String message) {
if (data == null)
data = new HashMap<String, String>();
data.put("title", title);
data.put("message", message);
}
}
Related
I have a method "send()" that send values to the server and then get response 0 or 1 from the server. then i want to active a method that check if its 0 or 1 and then i want to active a method that on MainActivity that called from the service.
this is the service code
public class SendThreadCommunication extends Thread {
private final static String TAG = "SendThreadCommunication";
private final int READ_TIMEOUT = 100000;
private final int CONNECTION_TINEOUT = 100000;
private Looper myLooper;
private int mResponseCode;
private String mData = "";
private final ServerRequest req;
// private RegisterUser user;
private static String ans;
public SendThreadCommunication(ServerRequest req) {
this.req = req;
}
public String readWebData(InputStream stream) {
String line = "";
StringBuffer buffer = new StringBuffer();
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
try {
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
reader.close();
} catch (IOException e) {
// TODO Auto-generated catch block
}
return buffer.toString();
}
#Override
public void run() {
try {
send();
// evaluateDataAndRespondToFragment(mData);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void send() throws ClientProtocolException, IOException {
OutputStream mOutputStream = null;
BufferedWriter mWriter = null;
List<NameValuePair> mParameters = req.getParameters();
URL url = null;
HttpURLConnection connection = null;
try {
Looper.prepare();
url = new URL(req.returnRequestUrl());
connection = (HttpURLConnection) url.openConnection();
connection.setReadTimeout(READ_TIMEOUT);
connection.setConnectTimeout(CONNECTION_TINEOUT);
connection.setRequestMethod(Params.HTTP_REQUEST_METHOD_POST);
connection.setDoOutput(true);
connection.setDoInput(true);
mOutputStream = connection.getOutputStream();
mWriter = new BufferedWriter(new OutputStreamWriter(mOutputStream, Params.UTF8));
String sparams = URLEncodedUtils.format(mParameters, Params.UTF8);
mWriter.write(sparams);
mWriter.flush();
mResponseCode = connection.getResponseCode();
if (mResponseCode > 203) {
mData = readWebData(connection.getErrorStream());
//this.req.getResponse().notGoodServerEroorr();
} else {
mData = readWebData(connection.getInputStream());
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (connection != null) {
try {
if (mOutputStream != null)
mOutputStream.close();
if (mWriter != null)
mWriter.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
connection.disconnect();
evaluateDataAndRespondToFragment(mData);
myLooper = Looper.myLooper();
Looper.loop();
myLooper.quit();
}
}
}
private void evaluateDataAndRespondToFragment(String mData) {
Listen lis = this.req.getResponse();
if (mData.equals("1"))
lis.good();
else
lis.notGood();
if (mData.equals("0"))
{
lis.userGcmNotRegistered();
}
}
}
this service code send to the server values and get response. the method "evaluateDataAndRespondToFragment" check if its 0 or 1 and then active the appropriate method. that method should trigger other method in the MainActivity.
i know that runOnUiThread handle this, but i dont know how to use it.
the method on the MainActivity change the UI.
this is the MainActivity code
public class MainActivity extends Activity implements SensorEventListener, Listen {
private BroadcastReceiver statusReceiver;
private IntentFilter mIntent;
Sensor accelerometer;
SensorManager sm;
TextView acceleration;
SendValues sv;
int counter3 = 0;
int counter5 = 0;
int pastTime = 0;
private static final String TAG = "MainActivity";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public void good() {
Toast.makeText(getApplication(), "successful transfer", Toast.LENGTH_LONG).show();
}
#Override
public void notGood() {
Toast.makeText(getApplication(), "UNsuccssful transfer", Toast.LENGTH_LONG).show();
}
#Override
public void userGcmNotRegistered() {
Toast.makeText(getApplication(), "There is some problem, please register again to the App", Toast.LENGTH_LONG).show();
}
}
Here it should active one of the methods "good","not good"....
i know that runOnUiThread handle it but i dont know how to use it and where.
if anyone could tell me what to do i will appreciate.
A service doesn't have a runOnUiThread method, but you can use intent instead of.
Simply,
Add a BroadcastReceiver to your activity,
Add receiver to your AndroidManifest.xml,
Send intent from your service.
MainActivity.java
public class MainActivity extends Activity implements SensorEventListener, Listen {
private BroadcastReceiver statusReceiver;
private IntentFilter mIntent;
Sensor accelerometer;
SensorManager sm;
TextView acceleration;
SendValues sv;
int counter3 = 0;
int counter5 = 0;
int pastTime = 0;
private static final String TAG = "MainActivity";
statusReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
switch(intent.getIntExtra("status", -1) {
case 1:
good();
break;
case 2:
notGood();
break;
default:
userGcmNotRegistered();
}
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
registerReceiver(statusReceiver, new IntentFilter("com.yourpackage.yourapp.GET_STATUS_INTENT");
}
#Override
public void good() {
Toast.makeText(getApplication(), "successful transfer", Toast.LENGTH_LONG).show();
}
#Override
public void notGood() {
Toast.makeText(getApplication(), "UNsuccssful transfer", Toast.LENGTH_LONG).show();
}
#Override
public void userGcmNotRegistered() {
Toast.makeText(getApplication(), "There is some problem, please register again to the App", Toast.LENGTH_LONG).show();
}
}
A simple AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.yourpackage.yourapp"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="19"
android:targetSdkVersion="19" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.yourpackage.yourapp.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name="MainActivity">
<intent-filter>
<action android:name="com.yourpackage.yourapp.GET_STATUS_INTENT">
</action>
</intent-filter>
</receiver>
</application>
</manifest>
evaluateDataAndRespondToFragment method
private void evaluateDataAndRespondToFragment(String mData) {
Intent intent = new Intent("com.yourpackage.yourapp.GET_STATUS_INTENT");
intent.putExtra(status, mData);
sendBroadcast(intent);
}
}
Additionally you need to register/unregister within your activity's onResume/onPause methods.
A bit off topic; but, Beremaran's answer is correct, you can't get the main thread from a service. However, runOnUiThread is a very important concept to know and use, to avoid blocking up your main thread. Blocking your main thread will cause the system to kill your app.
Let say you have some networking tasks to do, and you know that it can take some time to do that. Therefore you start a new Thread to do the slow work.
new Thread(new Runnable() {
#Override
public void run() {
messageFromSlowStuff = doSomeSlowStuff();
};
}).start();
Now you might want to populate the UI with the new data messageFromSlowStuff, but you can't because it is only aloud from the main thread.
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
myTextView.setText(messageFromSlowStuff)
}
});
If you are only updating a view as in the example above you can use View.post() an alternative to runOnUiThread.
myTextView.post(new Runnable() {
public void run() {
messageFromSlowStuff = doSomeSlowStuff();
myTextView.setText(messageFromSlowStuff);
}
});
Here's the docs regarding View.post(): "post reference"
Hi In My Application I used this site for sending push notification using gcm concept androidhive.info . I am testing in localhost to server that one its working fine and no of devices also it showing after detecting the emulator registration id and then sending notification.Now that details also stored in local database.
Now My problem I am receiving any push notifications from server.
can anyone please help me and reslove it
AlertDialogManager.java:
public class AlertDialogManager {
public void showAlertDialog(Context context, String title, String message,
Boolean status) {
AlertDialog alertDialog = new AlertDialog.Builder(context).create();
// Setting Dialog Title
alertDialog.setTitle(title);
// Setting Dialog Message
alertDialog.setMessage(message);
if(status != null)
// Setting alert dialog icon
alertDialog.setIcon((status) ? R.drawable.success : R.drawable.fail);
// Setting OK Button
alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
});
// Showing Alert Message
alertDialog.show();
}
}
CommonUtilities.java
public final class CommonUtilities {
// give your server registration url here
static final String SERVER_URL = "http://10.0.2.2/gcm_server_php/register.php";
// Google project id
static final String SENDER_ID = "907381889394";
static final String TAG = "AndroidHive GCM";
static final String DISPLAY_MESSAGE_ACTION =
"com.androidhive.pushnotifications.DISPLAY_MESSAGE";
static final String EXTRA_MESSAGE = "message";
static void displayMessage(Context context, String message) {
Intent intent = new Intent(DISPLAY_MESSAGE_ACTION);
intent.putExtra(EXTRA_MESSAGE, message);
context.sendBroadcast(intent);
}
}
ConnectionDetector.java:
public class ConnectionDetector {
private Context _context;
public ConnectionDetector(Context context){
this._context = context;
}
public boolean isConnectingToInternet(){
ConnectivityManager connectivity = (ConnectivityManager) _context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivity != null)
{
NetworkInfo[] info = connectivity.getAllNetworkInfo();
if (info != null)
for (int i = 0; i < info.length; i++)
if (info[i].getState() == NetworkInfo.State.CONNECTED)
{
return true;
}
}
return false;
}
}
GCMIntentService.java:
public class GCMIntentService extends GCMBaseIntentService {
private static final String TAG = "GCMIntentService";
public GCMIntentService() {
super(SENDER_ID);
}
#Override
protected void onRegistered(Context context, String registrationId) {
Log.i(TAG, "Device registered: regId = " + registrationId);
displayMessage(context, "Your device registred with GCM");
Log.d("NAME", MainActivity.name);
ServerUtilities.register(context, MainActivity.name, MainActivity.email, registrationId);
}
#Override
protected void onUnregistered(Context context, String registrationId) {
Log.i(TAG, "Device unregistered");
displayMessage(context, getString(R.string.gcm_unregistered));
ServerUtilities.unregister(context, registrationId);
}
#Override
protected void onMessage(Context context, Intent intent) {
Log.i(TAG, "Received message");
String message = intent.getExtras().getString("price");
displayMessage(context, message);
// notifies user
generateNotification(context, message);
}
#Override
protected void onDeletedMessages(Context context, int total) {
Log.i(TAG, "Received deleted messages notification");
String message = getString(R.string.gcm_deleted, total);
displayMessage(context, message);
// notifies user
generateNotification(context, message);
}
#Override
public void onError(Context context, String errorId) {
Log.i(TAG, "Received error: " + errorId);
displayMessage(context, getString(R.string.gcm_error, errorId));
}
#Override
protected boolean onRecoverableError(Context context, String errorId) {
// log message
Log.i(TAG, "Received recoverable error: " + errorId);
displayMessage(context, getString(R.string.gcm_recoverable_error,
errorId));
return super.onRecoverableError(context, errorId);
}
private static void generateNotification(Context context, String message) {
int icon = R.drawable.ic_launcher;
long when = System.currentTimeMillis();
NotificationManager notificationManager = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(icon, message, when);
String title = context.getString(R.string.app_name);
Intent notificationIntent = new Intent(context, MainActivity.class);
// set intent so it does not start a new activity
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |
Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent intent =
PendingIntent.getActivity(context, 0, notificationIntent, 0);
notification.setLatestEventInfo(context, title, message, intent);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
// Play default notification sound
notification.defaults |= Notification.DEFAULT_SOUND;
//notification.sound = Uri.parse("android.resource://" + context.getPackageName() + "your_sound_file_name.mp3");
// Vibrate if vibrate is enabled
notification.defaults |= Notification.DEFAULT_VIBRATE;
notificationManager.notify(0, notification);
}
}
MainActivity.java:
public class MainActivity extends Activity {
// label to display gcm messages
TextView lblMessage;
// Asyntask
AsyncTask<Void, Void, Void> mRegisterTask;
// Alert dialog manager
AlertDialogManager alert = new AlertDialogManager();
// Connection detector
ConnectionDetector cd;
public static String name;
public static String email;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
cd = new ConnectionDetector(getApplicationContext());
// Check if Internet present
if (!cd.isConnectingToInternet()) {
// Internet Connection is not present
alert.showAlertDialog(MainActivity.this,
"Internet Connection Error",
"Please connect to working Internet connection", false);
// stop executing code by return
return;
}
// Getting name, email from intent
Intent i = getIntent();
name = i.getStringExtra("name");
email = i.getStringExtra("email");
// Make sure the device has the proper dependencies.
GCMRegistrar.checkDevice(this);
// Make sure the manifest was properly set - comment out this line
// while developing the app, then uncomment it when it's ready.
GCMRegistrar.checkManifest(this);
lblMessage = (TextView) findViewById(R.id.lblMessage);
registerReceiver(mHandleMessageReceiver, new IntentFilter(
DISPLAY_MESSAGE_ACTION));
// Get GCM registration id
final String regId = GCMRegistrar.getRegistrationId(this);
// Check if regid already presents
if (regId.equals("")) {
// Registration is not present, register now with GCM
GCMRegistrar.register(this, SENDER_ID);
} else {
// Device is already registered on GCM
if (GCMRegistrar.isRegisteredOnServer(this)) {
// Skips registration.
Toast.makeText(getApplicationContext(), "Already registered with GCM", Toast.LENGTH_LONG).show();
} else {
// Try to register again, but not in the UI thread.
// It's also necessary to cancel the thread onDestroy(),
// hence the use of AsyncTask instead of a raw thread.
final Context context = this;
mRegisterTask = new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... params) {
// Register on our server
// On server creates a new user
ServerUtilities.register(context, name, email, regId);
return null;
}
#Override
protected void onPostExecute(Void result) {
mRegisterTask = null;
}
};
mRegisterTask.execute(null, null, null);
}
}
}
private final BroadcastReceiver mHandleMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String newMessage = intent.getExtras().getString(EXTRA_MESSAGE);
// Waking up mobile if it is sleeping
WakeLocker.acquire(getApplicationContext());
/**
* Take appropriate action on this message
* depending upon your app requirement
* For now i am just displaying it on the screen
* */
// Showing received message
lblMessage.append(newMessage + "\n");
Toast.makeText(getApplicationContext(), "New Message: " + newMessage, Toast.LENGTH_LONG).show();
// Releasing wake lock
WakeLocker.release();
}
};
#Override
protected void onDestroy() {
if (mRegisterTask != null) {
mRegisterTask.cancel(true);
}
try {
unregisterReceiver(mHandleMessageReceiver);
GCMRegistrar.onDestroy(this);
} catch (Exception e) {
Log.e("UnRegister Receiver Error", "> " + e.getMessage());
}
super.onDestroy();
}
}
RegisterActivity.java:
public class RegisterActivity extends Activity {
// alert dialog manager
AlertDialogManager alert = new AlertDialogManager();
// Internet detector
ConnectionDetector cd;
// UI elements
EditText txtName;
EditText txtEmail;
// Register button
Button btnRegister;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
cd = new ConnectionDetector(getApplicationContext());
// Check if Internet present
if (!cd.isConnectingToInternet()) {
// Internet Connection is not present
alert.showAlertDialog(RegisterActivity.this,
"Internet Connection Error",
"Please connect to working Internet connection", false);
// stop executing code by return
return;
}
// Check if GCM configuration is set
if (SERVER_URL == null || SENDER_ID == null || SERVER_URL.length() == 0
|| SENDER_ID.length() == 0) {
// GCM sernder id / server url is missing
alert.showAlertDialog(RegisterActivity.this, "Configuration Error!",
"Please set your Server URL and GCM Sender ID", false);
// stop executing code by return
return;
}
txtName = (EditText) findViewById(R.id.txtName);
txtEmail = (EditText) findViewById(R.id.txtEmail);
btnRegister = (Button) findViewById(R.id.btnRegister);
btnRegister.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
// Read EditText dat
String name = txtName.getText().toString();
String email = txtEmail.getText().toString();
// Check if user filled the form
if(name.trim().length() > 0 && email.trim().length() > 0){
// Launch Main Activity
Intent i = new Intent(getApplicationContext(), MainActivity.class);
// Registering user on our server
// Sending registraiton details to MainActivity
i.putExtra("name", name);
i.putExtra("email", email);
startActivity(i);
finish();
}else{
// user doen't filled that data
// ask him to fill the form
alert.showAlertDialog(RegisterActivity.this, "Registration Error!", "Please enter your details", false);
}
}
});
}
}
public final class ServerUtilities {
private static final int MAX_ATTEMPTS = 5;
private static final int BACKOFF_MILLI_SECONDS = 2000;
private static final Random random = new Random();
static void register(final Context context, String name, String email, final String regId) {
Log.i(TAG, "registering device (regId = " + regId + ")");
String serverUrl = SERVER_URL;
Map<String, String> params = new HashMap<String, String>();
params.put("regId", regId);
params.put("name", name);
params.put("email", email);
long backoff = BACKOFF_MILLI_SECONDS + random.nextInt(1000);
// Once GCM returns a registration id, we need to register on our server
// As the server might be down, we will retry it a couple
// times.
for (int i = 1; i <= MAX_ATTEMPTS; i++) {
Log.d(TAG, "Attempt #" + i + " to register");
try {
displayMessage(context, context.getString(
R.string.server_registering, i, MAX_ATTEMPTS));
post(serverUrl, params);
GCMRegistrar.setRegisteredOnServer(context, true);
String message = context.getString(R.string.server_registered);
CommonUtilities.displayMessage(context, message);
return;
} catch (IOException e) {
// Here we are simplifying and retrying on any error; in a real
// application, it should retry only on unrecoverable errors
// (like HTTP error code 503).
Log.e(TAG, "Failed to register on attempt " + i + ":" + e);
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();
return;
}
// increase backoff exponentially
backoff *= 2;
}
}
String message = context.getString(R.string.server_register_error,
MAX_ATTEMPTS);
CommonUtilities.displayMessage(context, message);
}
static void unregister(final Context context, final String regId) {
Log.i(TAG, "unregistering device (regId = " + regId + ")");
String serverUrl = SERVER_URL + "/unregister";
Map<String, String> params = new HashMap<String, String>();
params.put("regId", regId);
try {
post(serverUrl, params);
GCMRegistrar.setRegisteredOnServer(context, false);
String message = context.getString(R.string.server_unregistered);
CommonUtilities.displayMessage(context, message);
} 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.
String message = context.getString(R.string.server_unregister_error,
e.getMessage());
CommonUtilities.displayMessage(context, message);
}
}
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 {
Log.e("URL", "> " + url);
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();
}
}
}
}
WakeLocker.java:
public abstract class WakeLocker {
private static PowerManager.WakeLock wakeLock;
public static void acquire(Context context) {
if (wakeLock != null) wakeLock.release();
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK |
PowerManager.ACQUIRE_CAUSES_WAKEUP |
PowerManager.ON_AFTER_RELEASE, "WakeLock");
wakeLock.acquire();
}
public static void release() {
if (wakeLock != null) wakeLock.release(); wakeLock = null;
}
}
manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.androidhive.pushnotifications"
android:versionCode="1"
android:versionName="1.0" >
<!-- GCM requires Android SDK version 2.2 (API level 8) or above. -->
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="16" />
<!-- GCM connects to Internet Services. -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<!-- GCM requires a Google account. -->
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<!-- Keeps the processor from sleeping when a message is received. -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!-- Creates a custom permission so only this app can receive its messages. -->
<permission
android:name="com.androidhive.pushnotifications.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.androidhive.pushnotifications.permission.C2D_MESSAGE" />
<!-- This app has permission to register and receive data message. -->
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<!-- Network State Permissions to detect Internet status -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- Permission to vibrate -->
<uses-permission android:name="android.permission.VIBRATE" />
<!-- Main activity. -->
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<!-- Register Activity -->
<activity
android:name=".RegisterActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- Main Activity -->
<activity
android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden"
android:label="#string/app_name" >
</activity>
<receiver
android:name="com.google.android.gcm.GCMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<!-- Receives the actual messages. -->
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<!-- Receives the registration id. -->
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.androidhive.pushnotifications" />
</intent-filter>
</receiver>
<service android:name=".GCMIntentService" />
</application>
</manifest>
A couple of points for you to check out:
Make sure your emulator's Target API is one of the Google APIs *** -- not just Android ***
Make sure you have a Google account logged in on the emulator
I am writing a chat client in Android using the XMPP protocol. I have used the asmack.jar as provided by
http://asmack.freakempire.de/. The implementation works in plain Java (using smack.jar) which I have tested. But in Android, I can only send messages to the other client (he uses pidgin) and cannot receive messages from him. The app successfully connects to the server, logs in and appears online but simply doesn't receive any message.
My processMessage() never gets called nor does chatCreated() when a message is send to my client.
My Activity class:
package com.example.basicchat;
import org.jivesoftware.smack.AndroidConnectionConfiguration;
import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.ChatManager;
import org.jivesoftware.smack.ChatManagerListener;
import org.jivesoftware.smack.ConnectionListener;
import org.jivesoftware.smack.MessageListener;
import org.jivesoftware.smack.SmackAndroid;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Message;
import android.app.Activity;
import android.os.Bundle;
import android.widget.Toast;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SmackAndroid.init(this);
MainActivity2 xmppClient= new MainActivity2("jabber.org", 5222);
try {
xmppClient.login();
} catch (XMPPException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public class MainActivity2 implements MessageListener, ChatManagerListener, ConnectionListener {
private String server;
private int port;
public MainActivity2( String server, int port )
{
super();
this.server = server;
this.port = port;
}
private XMPPConnection connection = null;
public void login() throws XMPPException
{
String username = "my_user";
String password = "xxxxxxxx";
login(username, password);
}
private void login(String userName, String password) throws XMPPException
{
AndroidConnectionConfiguration config = new AndroidConnectionConfiguration(server,
port);
connection = new XMPPConnection(config);
connection.connect();
connection.addConnectionListener(this);
connection.login(userName, password);
ChatManager chatManager = connection.getChatManager();
chatManager.addChatListener(this);
Toast.makeText(MainActivity.this,"listener set", Toast.LENGTH_SHORT).show();
// sendMessage("helloooo","command_server#jabber.org"); /* this mssg is sent */
}
private void sendMessage(String message, String to) throws XMPPException
{
Chat chat = connection.getChatManager().createChat(to, this);
chat.sendMessage(message);
}
public void disconnect()
{
connection.disconnect();
}
/** never gets called **/
#Override
public void processMessage(Chat chat, Message message)
{
/*********** Handle Request and construct response ******************/
Toast.makeText(MainActivity.this,"mssg: "+message.getBody(), Toast.LENGTH_SHORT).show();
switch (message.getType())
{
case chat:
String jsonData = (null==message.getBody())?"":message.getBody();
System.out.println(jsonData);
break;
case error:
break;
case groupchat:
break;
case headline:
break;
case normal:
break;
}
}
#Override
public void chatCreated(Chat arg0, boolean arg1) {
// TODO Auto-generated method stub
Toast.makeText(MainActivity.this,"Chat Created!", Toast.LENGTH_SHORT).show();
if (!arg1)
arg0.addMessageListener(this);
}
#Override
public void connectionClosed() {
// TODO Auto-generated method stub
}
#Override
public void connectionClosedOnError(Exception arg0) {
// TODO Auto-generated method stub
}
#Override
public void reconnectingIn(int arg0) {
// TODO Auto-generated method stub
}
#Override
public void reconnectionFailed(Exception arg0) {
// TODO Auto-generated method stub
}
#Override
public void reconnectionSuccessful() {
// TODO Auto-generated method stub
}
}
}
Manifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.basicchat"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="8" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme"
>
<activity
android:name="com.example.basicchat.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
You must implements MessageListener class for MainActivity to receive chat messages
I'm unable to receive any calls on my android SIP application, I can register successfully with the SIP server, I can initiate call and invite other users successfully but I can't receive any calls. I don't think I have anything wrong in my SIP server or my devices as I'm able to use Sipdroid application and initiate and receive calls.
My code is as follows, which is based on SipDemo example:
public class WalkieTalkieActivity extends Activity implements View.OnTouchListener {
public static final String TAG = "WalkieTalkieActivity";
public String sipAddress = null;
public SipManager manager = null;
public SipProfile me = null;
public SipAudioCall call = null;
public IncomingCallReceiver callReceiver;
private static final int CALL_ADDRESS = 1;
private static final int SET_AUTH_INFO = 2;
private static final int UPDATE_SETTINGS_DIALOG = 3;
private static final int HANG_UP = 4;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.walkietalkie);
ToggleButton pushToTalkButton = (ToggleButton) findViewById(R.id.pushToTalk);
pushToTalkButton.setOnTouchListener(this);
// Set up the intent filter. This will be used to fire an
// IncomingCallReceiver when someone calls the SIP address used by this
// application.
IntentFilter filter = new IntentFilter();
filter.addAction("android.SipDemo.INCOMING_CALL");
callReceiver = new IncomingCallReceiver();
this.registerReceiver(callReceiver, filter);
// "Push to talk" can be a serious pain when the screen keeps turning off.
// Let's prevent that.
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
initializeManager();
}
#Override
public void onStart() {
super.onStart();
// When we get back from the preference setting Activity, assume
// settings have changed, and re-login with new auth info.
initializeManager();
}
#Override
public void onDestroy() {
super.onDestroy();
if (call != null) {
call.close();
}
closeLocalProfile();
if (callReceiver != null) {
this.unregisterReceiver(callReceiver);
}
}
public void initializeManager() {
if(manager == null) {
manager = SipManager.newInstance(this);
}
initializeLocalProfile();
}
/**
* Logs you into your SIP provider, registering this device as the location to
* send SIP calls to for your SIP address.
*/
public void initializeLocalProfile() {
if (manager == null) {
return;
}
if (me != null) {
closeLocalProfile();
}
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
String username = prefs.getString("namePref", "XXX");
String domain = prefs.getString("domainPref", "192.168.1.11");
String password = prefs.getString("passPref", "");
if (username.length() == 0 || domain.length() == 0 || password.length() == 0) {
showDialog(UPDATE_SETTINGS_DIALOG);
return;
}
try {
SipProfile.Builder builder = new SipProfile.Builder(username, domain);
builder.setPassword(password);
builder.setOutboundProxy(domain);
builder.setPort(8090);
builder.setProtocol("UDP");
me = builder.build();
Log.d(TAG, "Auto Registration: " + me.getAutoRegistration());
Log.d(TAG, "SipProfile: " + me.getUriString());
Intent i = new Intent();
i.setAction("android.SipDemo.INCOMING_CALL");
PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, Intent.FILL_IN_DATA);
manager.open(me, pi, null);
Log.d(TAG, "manage.isOpen() " + manager.isOpened(me.getUriString()));
// This listener must be added AFTER manager.open is called,
// Otherwise the methods aren't guaranteed to fire.
manager.setRegistrationListener(me.getUriString(), new SipRegistrationListener() {
public void onRegistering(String localProfileUri) {
updateStatus("Registering with SIP Server...");
}
public void onRegistrationDone(String localProfileUri, long expiryTime) {
updateStatus("Ready");
Log.d(TAG,"Registration done successfully.....");
Log.d(TAG,"Local Profile URI: " + me.getUriString());
Log.d(TAG,"Local Profile URI: " + me);
}
public void onRegistrationFailed(String localProfileUri, int errorCode,
String errorMessage) {
updateStatus("Registration failed. Please check settings. " + errorMessage);
}
});
} catch (ParseException pe) {
updateStatus("Connection Error.");
} catch (SipException se) {
updateStatus("Connection error.");
}
}
/**
* Closes out your local profile, freeing associated objects into memory
* and unregistering your device from the server.
*/
public void closeLocalProfile() {
if (manager == null) {
return;
}
try {
if (me != null) {
manager.close(me.getUriString());
}
} catch (Exception ee) {
Log.d("WalkieTalkieActivity/onDestroy", "Failed to close local profile.", ee);
}
}
/**
* Make an outgoing call.
*/
public void initiateCall() {
updateStatus(sipAddress);
try {
SipAudioCall.Listener listener = new SipAudioCall.Listener() {
// Much of the client's interaction with the SIP Stack will
// happen via listeners. Even making an outgoing call, don't
// forget to set up a listener to set things up once the call is established.
#Override
public void onCallEstablished(SipAudioCall call) {
call.startAudio();
call.setSpeakerMode(true);
call.toggleMute();
updateStatus(call);
}
#Override
public void onCallEnded(SipAudioCall call) {
updateStatus("Ready.");
}
};
Log.d(TAG,"Calling: " + sipAddress);
call = manager.makeAudioCall(me.getUriString(), sipAddress, listener, 30);
}
catch (Exception e) {
Log.i("WalkieTalkieActivity/InitiateCall", "Error when trying to close manager.", e);
if (me != null) {
try {
manager.close(me.getUriString());
} catch (Exception ee) {
Log.i("WalkieTalkieActivity/InitiateCall",
"Error when trying to close manager.", ee);
ee.printStackTrace();
}
}
if (call != null) {
call.close();
}
}
}
}
public class IncomingCallReceiver extends BroadcastReceiver {
public static final String TAG = "IncomingCallReceiver";
/**
* Processes the incoming call, answers it, and hands it over to the
* WalkieTalkieActivity.
* #param context The context under which the receiver is running.
* #param intent The intent being received.
*/
#Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG,"************************* Incoming call received.....");
SipAudioCall incomingCall = null;
try {
SipAudioCall.Listener listener = new SipAudioCall.Listener() {
#Override
public void onRinging(SipAudioCall call, SipProfile caller) {
try {
call.answerCall(30);
} catch (Exception e) {
e.printStackTrace();
}
}
};
WalkieTalkieActivity wtActivity = (WalkieTalkieActivity) context;
incomingCall = wtActivity.manager.takeAudioCall(intent, listener);
incomingCall.answerCall(30);
incomingCall.startAudio();
incomingCall.setSpeakerMode(true);
if(incomingCall.isMuted()) {
incomingCall.toggleMute();
}
wtActivity.call = incomingCall;
wtActivity.updateStatus(incomingCall);
} catch (Exception e) {
if (incomingCall != null) {
incomingCall.close();
}
}
}
}
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.sip"
android:versionCode="1"
android:versionName="1.0" >
<application android:icon="#drawable/icon" android:label="SipDemo">
<activity android:name=".WalkieTalkieActivity"
android:configChanges="orientation|keyboardHidden">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name=".SipSettings" android:label="set_preferences"/>
<receiver android:name=".IncomingCallReceiver" android:label="Call Receiver"/>
</application>
<uses-sdk android:minSdkVersion="9" />
<uses-permission android:name="android.permission.USE_SIP" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-feature android:name="android.hardware.sip.voip" android:required="true" />
<uses-feature android:name="android.hardware.wifi" android:required="true" />
<uses-feature android:name="android.hardware.microphone" android:required="true" />
</manifest>
I list some features and permission that I had in my Manifest.xml, hope it help.
<uses-feature android:name="android.software.sip" android:required="false" />
<uses-feature android:name="android.software.sip.voip" android:required="false" />
<uses-feature android:name="android.hardware.telephony" android:required="false" />
<uses-permission android:name="android.permission.CONFIGURE_SIP" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
I am trying to run the application in the background but when the application starts immediately the application is closed (no error is coming).I have used asynk task in the main activity.
code:
package com.android.trace;
public class LocationStat extends Activity {
double logi;
double lat;
long MINIMUM_DISTANCE_CHANGE_FOR_UPDATES = 1; // in Meters
long MINIMUM_TIME_BETWEEN_UPDATES = 1000; // in Millisecon
Location loc;
LocationManager manager;
TextView t;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new MyLocationAsyncTask().execute();
}
public void onStart() {
super.onStart();
new MyLocationAsyncTask().execute();
}
private class MyLocationAsyncTask extends AsyncTask<Void, Location, Void> implements LocationListener {
//private Location l;
//location management variables to track and maintain user location
#Override
protected Void doInBackground(Void... arg0) {
t = (TextView) findViewById(R.id.text);
manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
manager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
MINIMUM_TIME_BETWEEN_UPDATES,
MINIMUM_DISTANCE_CHANGE_FOR_UPDATES,
new MyLocationAsyncTask());
return onLocationChanged();
}
//this method is never executed i dont know why...?
public Void onLocationChanged() {
if (manager != null) {
LocationStat l = new LocationStat();
loc = manager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
lat = loc.getLatitude();
logi = loc.getLongitude();
t.setText(" Your Location :\nlongitude:" + logi + "\nlatitude: " + lat); //Log.d("Your Location", ""+latLocation);
l.webcall(logi, lat);
}
return null;
}
public void onLocationChanged(Location location) {
onLocationChanged();
}
public void onProviderDisabled(String provider) {
}
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
}
public void webcall(double logi, double lat) {
InputStream is = null;
String result = "";
//the year data to send
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("logitude", Double.toString(logi)));
nameValuePairs.add(new BasicNameValuePair("latitude", Double.toString(lat)));
//http post
try {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://10.0.2.2/location.php");
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
} catch (Exception e) {
Toast.makeText(LocationStat.this, "Error in http connection " + e.toString(), Toast.LENGTH_LONG).show();
}
//convert response to string
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
result = sb.toString();
Toast.makeText(LocationStat.this, result, Toast.LENGTH_LONG).show();
} catch (Exception e) {
Toast.makeText(LocationStat.this, "Error converting result " + e.toString(), Toast.LENGTH_LONG).show();
}
}
the code for service to intiate the activity
code:
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.widget.Toast;
public class MyService extends Service {
String tag="TestService";
#Override
public void onCreate() {
Intent dialogIntent = new Intent(this, LocationStat.class);
dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
this.startActivity(dialogIntent);
}
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, "Service destroyed...", Toast.LENGTH_LONG).show();
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
The broadcast receiver used for initiating the service at the start up is
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class MyBroadcastReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
Intent startServiceIntent = new Intent(context, MyService.class);
startServiceIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startService(startServiceIntent);
}
}
the manifest permissions for activity,service and broadcast receiver is as follows
<service android:enabled="true" android:name=".MyService">
<intent-filter >
<action android:name="com.android.trace.MyService"/>
</intent-filter>
</service>
<receiver android:name="com.android.trace.MyBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<activity
android:name=".LocationStat"
android:label="#string/title_activity_location_stat" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
Anybody experiencing the same?
Use Service instead of Activity to do background long run jobs
You can only use setText and other operations on the GUI from the main GUI thread. You are trying to do this from the background thread you have started.
You must implement the AsyncTask function onPostExecute and modify your GUI from there.
out of memory, catch LOG onDestoy() method
Have you mentioned your receiver in the android manifest file,
Add this bunch of code in your manifest file,
<receiver
android:name=".MyBroadcastReceiver" >
<intent-filter android:priority="1000">
<action />
</intent-filter>
</receiver>