Send Ping on Android programmatically - android

Ok, I have no Idea how to do this, I need some help.
I need to send a Ping in JSON format into a server, I've already have it with all the information that I need... timestamp, location, device_id, etc... But.. how can I send it each 5 minutes automatically ?? I'm still looking for something useful but I have no succes.. I'm kind of new on this..
here's an example of my code, feel free to use it if it is useful for you :) ...
package com.example.hugo.ping03;
// imports....
public class MainActivity extends ActionBarActivity {
//HTTP
private AsyncHttpClient client;//crear cliente
private AsyncHttpResponseHandler handler;//crear handler
private Button send;
//JSON
JSONObject json; //objeto json
Context context = this; //context element
private StringEntity entity; //entity
//Battery
private IntentFilter batIntentFilter;
private Intent battery;
private int nivelBateria;
//device_id
private String id;
//timestamp
private int time;
private Timestamp tsTemp;
private Long tsLong;
private String ts;
//GPS (this one comes from another class.java)
GPSTracker gps;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ping03);
client = new AsyncHttpClient();
String password = "pass";
client.setBasicAuth("hugo", password);
send = (Button) findViewById(R.id.send);
//battery level:
batIntentFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
battery = this.registerReceiver(null, batIntentFilter);
nivelBateria = battery.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
//device_id:
id = Secure.getString(getContentResolver(), Secure.ANDROID_ID);
//timestamp
time = (int) (System.currentTimeMillis());
tsTemp = new Timestamp(time);
tsLong = System.currentTimeMillis()/1000;
ts = tsLong.toString();
handler = new AsyncHttpResponseHandler() {
#Override
public void onSuccess(int statusCode, Header[] headers, byte[] response) {
// called when response HTTP status is "200 OK"
Log.d("onSuccess","ping exitoso !!!!");
Log.d("Nivel de Bateria:",String.valueOf(nivelBateria));
Log.d("Id de Dispositivo",id);
Log.d("Timesatmp:",ts);
}
#Override
public void onFailure(int statusCode, Header[] headers, byte[] errorResponse, Throwable e) {
// called when response HTTP status is "4XX" (eg. 401, 403, 404)
String statuscode = String.valueOf(statusCode);
Log.d("onFailure","ping nulo a causa de: ");
Log.d("Server statusCode",statuscode);
}
};
send.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//mensaje a Log para indicar clic en botón
Log.d("onPressButton","Click exitoso");
String klientourl = "server url";
//Strings to Post JSON :
String status = "1";
String device_id = id;
String timestamp =ts;
String battery = String.valueOf(nivelBateria);
json = new JSONObject();
gps = new GPSTracker(Ping03.this);//creamos objeto de clase
//if GPS is Enabled...
if (gps.canGetLocation()){
double latitude = gps.getLatitude();
double longitude = gps.getLongitude();
Log.d("Location is:", "Lat: "+latitude+" Long: "+longitude);
String IamHere = "Lat: "+latitude+" Long: "+longitude;
try {
json.put("geo", IamHere);
json.put("status", status);
json.put("device_id", device_id);
json.put("timeStamp", timestamp);
json.put("battery", battery);
}catch (JSONException e){
Log.e("Json", "unexpected JSON exception", e);
}
try {
entity = new StringEntity(json.toString());
entity.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
client.post(context, klientourl, entity, "application/json", handler);
}catch (Exception e){}
}else {
//if we can
gps.showSettingsAlert();
Log.d("Geoloc: ", "Disabled?");
}
}// ./ end onClick
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_ping03, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
} }
Any ideas? thanks a lot!

If you want to perform some periodically repeating tasks, I'd suggest you make use of a AlarmManager component of the Android SDK.Alarm manager is a system service, thus you can access it by using the following line of code.
AlarmManager mAlarmMgr=(AlarmManager) getSystemService(Context.ALARM_SERVICE);
//Then you can set alarm using mAlarmMgr.set().
You will then receive the alarm in an AlarmReceiver.
AlarmReciever class extends BroadcastReceiver and overrides onRecieve() method. inside onReceive() you can start an activity or service depending on your need like you can start an activity to vibrate phone or to ring the phone.
Here is an article from Android Developers that describes how to use AlarmManager and AlarmReceiver : http://developer.android.com/training/scheduling/alarms.html. After you are successful of setting an alarm with AlarmManager (for every 5 minutes) and intercepting it in your AlarmReceiver, you can start an IntentService that will send the ping json to your server.
I hope this helps. Cheers!

If you want to hit you server from android app after a fix time you should create a background service.and this service class will call server on a specific delay frequently.
public class MyService extends Service{
Handler mHandler = new Handler();
#Override
public IBinder onBind(Intent arg0){
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId){
Log.e(TAG, "onStartCommand");
super.onStartCommand(intent, flags, startId);
return START_STICKY;
}
#Override
public void onCreate(){
Log.e(TAG, "onCreate");
mHandler.postDelayed(mRun,300000);
}
Runnable mRun = new Runnable() {
#Override
public void run() {
// TODO call your service here
mHandler.postDelayed(mRun,300000);
}
};
}
start service from your activity like below -
private void startService(){
Handler mStartServicehandler = new Handler();
mStartServicehandler.post(new Runnable() {
#Override
public void run() {
startService(new Intent(mContext,MyService.class));
}
});
}
do something like this.
It will ping your server after every 5 min.

Related

How to perform API call in the background?

I want to create a simple app which is intend to call a API in POST method when a button clicks.The app workflow will be like this; user enter the url and a timeout value, and press start button. The API will called in the provided url and it will again and again call according to the timeout value provided. When user press the stop button,all activity should stop.The API call will not provide any data in response. I simply want to call that API in POST method.In order to achieve this I written the API call in a service.
The problem Iam facing is
The POST method doesn't working.
2.How can I call this api in background according to the timeout value provided.?
What I have Done
My MainActivity
url = (EditText)findViewById(R.id.editText3);
timeOut = (EditText)findViewById(R.id.editText5);
Button clickButton = (Button) findViewById(R.id.start);
clickButton.setOnClickListener( new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent(MainActivity.this, APIService.class);
Bundle bund = new Bundle();
bund.putString("url",url.getText().toString());
bund.putString("timeout",timeOut.getText().toString());
intent.putExtras(bund);
startService(intent);
}
});
Button stopbutton = (Button) findViewById(R.id.stop);
stopbutton.setOnClickListener( new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent(MainActivity.this, APIService.class);
stopService(intent);
}
});
My API Service class
public APIService() {
}
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public void onCreate() {
Toast.makeText(this, " Client API Service Started", Toast.LENGTH_LONG).show();
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "Client API Service Started", Toast.LENGTH_LONG).show();
String WEBURL;
String TimeOut;
Bundle bund = intent.getExtras();
WEBURL=bund.getString("url");
TimeOut=bund.getString("timeout");
String URL= "http://"+WEBURL+"/API/ReportSubscription/GetAllReportSubscription?subscriptionUR="+WEBURL;
new HttpRequestTask(
new HttpRequest(URL, HttpRequest.POST),
new HttpRequest.Handler() {
#Override
public void response(HttpResponse response) {
if (response.code == 200) {
Log.d(this.getClass().toString(), "Request successful!");
} else {
Log.e(this.getClass().toString(), "Request unsuccessful: " + response);
}
}
}).execute();
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, "Client API Service Stopped", Toast.LENGTH_LONG).show();
}
}
I Used compile 'com.apptakk.http_request:http-request:0.1.2' for Web API call.Any help is appriciated
You can use OkHttp for this. See this tutorial for more: https://www.vogella.com/tutorials/JavaLibrary-OkHttp/article.html
// avoid creating several instances, should be singleon
OkHttpClient client = new OkHttpClient();
String weburl = bund.getString("url");
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("subscriptionUR", weburl)
.build();
Request request = new Request.Builder()
.url("http://"+weburl+"/API/ReportSubscription/GetAllReportSubscription")
.post(requestBody)
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
// Do something when request failed
e.printStackTrace();
Log.d(TAG, "Request Failed.");
}
#Override
public void onResponse(Call call, Response response) throws IOException {
if(!response.isSuccessful()){
throw new IOException("Error : " + response);
}else {
Log.d(TAG,"Request Successful.");
}
// Read data in the worker thread
final String data = response.body().string();
}
});
First make sure your API is working by testing through Postman. After you have make sure that API is working fine from the backend itself then the problem is from your mobile side calling that API. I would really recommend retrofit (https://square.github.io/retrofit/) to try out API calling task asynchronously because its really easy and standard way .You simply using POST method in api by passing your time out value as a parameter and your api url as base url.
You can use service in android to execute in the background i.e your API calling

Updating UI from Service in Android

I have an App that Monitors room noise levels, I initially got the Code from Github, in the original code, the programmer was monitoring noise levels from Main Activity and displaying the results in textviews, but I want to monitor using a service, I have implemented everything and its working but the textviews seem to be lagging behind, lets say I make a bit of noise and the noise level reach 5, it sticks at 5 even when there is no noise in the room, but in the original app, it was so sensitive that it would go back to 0 or another value depending on the noise levels, I do not know where I have gone wrong but below is my code:
Main Activity
public class StartingPoint extends Activity {
private String volumeBars;
private String volumeLevel;
private TextView volumeBarView;
private TextView volumeLevelView;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Toast.makeText(getBaseContext(), "Loading...", Toast.LENGTH_LONG).show();
setContentView(R.layout.activity_starting_point);
//starting Service
startService(new Intent(this, VolumeListerner.class));
volumeBarView = (TextView) findViewById(R.id.volumeBars);
volumeLevelView = (TextView) findViewById(R.id.volumeLevel);
}
#Override
public void onResume() {
LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver, new IntentFilter("UI_UPDATER"));
super.onResume();
// Sound based code
}
#Override
public void onPause() {
super.onPause();
}
public void updateTextView() {
volumeBarView.setText(volumeBars);
volumeLevelView.setText(volumeLevel);
return;
}
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
volumeBars = intent.getStringExtra("VolumeBars");
volumeLevel = intent.getStringExtra("volumeLevel");
Log.d("receiver", "Got message: " + volumeBars + " : " + volumeLevel);
updateTextView();
}
};
Service:
public class VolumeListerner extends Service {
private static String volumeVisual = "";
private static int volumeToSend;
private Handler handler;
private SoundMeter mSensor;
/** interface for clients that bind */
IBinder mBinder;
/** indicates whether onRebind should be used */
boolean mAllowRebind;
/** The service is starting, due to a call to startService() */
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
soundLevelCheck();
return super.onStartCommand(intent, flags, startId);
}
private void soundLevelCheck()
{
mSensor = new SoundMeter();
try {
mSensor.start();
Toast.makeText(getBaseContext(), "Sound sensor initiated.", Toast.LENGTH_SHORT).show();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
handler = new Handler();
final Runnable r = new Runnable() {
public void run() {
// Get the volume from 0 to 255 in 'int'
double volume = 10 * mSensor.getTheAmplitude() / 32768;
volumeToSend = (int) volume;
volumeVisual = "";
for( int i=0; i<volumeToSend; i++){
volumeVisual += "|";
updateUI();
}
handler.postDelayed(this, 250); // amount of delay between every cycle of volume level detection + sending the data out
}
};
// Is this line necessary? --- YES IT IS, or else the loop never runs
// this tells Java to run "r"
handler.postDelayed(r, 250);
}
private void updateUI()
{
Intent intent = new Intent( "UI_UPDATER" );
intent.putExtra("VolumeBars", "Volume Bars: " + String.valueOf(volumeVisual));
intent.putExtra("volumeLevel","Volume Levels: " + String.valueOf(volumeToSend));
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
I recommmand you to use an enhanced event bus with emphasis on Android support. you have a choice between :
1- Otto
2- Event Bus

how do I start the registration thread which is in another fragment

I have an app which has a main activity and two fragments running on top of it, One of the fragment is related to Google Cloud Notification registration and receiving of push notifications from gcm . Now the issue is the first time user launches the app and clicks on the notification fragment then only the process of registration with gcm starts and then he starts receiving the notifications . But I want to automatically start the registration process from the main acitvity without the wating for switching to notification fragment . How do I achieve this? I tried to make a new function in notification fragment and put all code regarding gcm registration into that function and then I tried calling that function from MainActivity but it gets the null pointer exception .. Please take a look at my code
public class NotificationFragment extends Fragment {
TextView lblMessage;
private AppPreferences _appPrefs;
public AsyncTask<Void, Void, Void> mRegisterTask;
AlertDialogManager alert = new AlertDialogManager();
ConnectionDetector cd;
public static String name;
public static String email;
public View rootView;
public NotificationFragment(){}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.gcm_activity_main, container, false);
return rootView;
}
#Override
public void onStart (){
super.onStart();
autoRegistrationForNotification();
}
public void autoRegistrationForNotification()
{
_appPrefs = new AppPreferences(rootView.getContext());
_appPrefs.setToZero();
cd = new ConnectionDetector(getActivity().getApplicationContext());
name = " ";
email = " ";
// Make sure the device has the proper dependencies.
//if(cd.isConnectingToInternet())
try{
GCMRegistrar.checkDevice(getActivity().getApplicationContext());
}catch(Exception e){}
// Make sure the manifest was properly set - comment out this line
// while developing the app, then uncomment it when it's ready.
//if(cd.isConnectingToInternet())
try{
GCMRegistrar.checkManifest(getActivity().getApplicationContext());
}catch(Exception e){}
lblMessage = (TextView) rootView.findViewById(R.id.lblMessage);
lblMessage.setText(_appPrefs.getMessageFromArchive());
getActivity().getApplicationContext().registerReceiver(mHandleMessageReceiver, new IntentFilter(
DISPLAY_MESSAGE_ACTION));
// Get GCM registration id
//if(cd.isConnectingToInternet()){
final String regId = GCMRegistrar.getRegistrationId(getActivity().getApplicationContext());
// Check if regid already presents
if (regId.equals("")) {
// Registration is not present, register now with GCM
// if(cd.isConnectingToInternet())
try{
GCMRegistrar.register(getActivity().getApplicationContext(), SENDER_ID);}
catch(Exception e){}
} else {
// Device is already registered on GCM
//if(cd.isConnectingToInternet())
if (GCMRegistrar.isRegisteredOnServer(getActivity().getApplicationContext())) {
// Skips registration.
// Toast.makeText(getActivity().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 = getActivity().getApplicationContext();
mRegisterTask = new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... params) {
// Register on our server
// On server creates a new user
// if(cd.isConnectingToInternet())
try{
ServerUtilities.register(context, name, email, regId);}
catch(Exception e){}
return null;
}
#Override
protected void onPostExecute(Void result) {
mRegisterTask = null;
}
};
try{
// if(cd.isConnectingToInternet())
try{
mRegisterTask.execute(null, null, null);}catch(Exception e){}
}catch(Exception e){}
}
}//else ends
}
/**
* Receiving push messages
* */
public final BroadcastReceiver mHandleMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// _appPrefs = new AppPreferences(getActivity());
_appPrefs = new AppPreferences(rootView.getContext());
String newMessage = "";
try{
_appPrefs.incrementNotificationCount();
newMessage = intent.getExtras().getString(EXTRA_MESSAGE);
// Waking up mobile if it is sleeping
}catch(Exception e)
{
}
try{
WakeLocker.acquire(getActivity().getApplicationContext());
}catch(Exception e)
{
}
if(_appPrefs.getMessageFromArchive().length() > 800){
_appPrefs.saveMessageToArchive(" ");
}
Time now = new Time();
now.setToNow();
int month = now.month;
int day = now.monthDay;
int year = now.year;
DateFormatSymbols dfs = new DateFormatSymbols();
String[] months = dfs.getMonths();
//lblMessage.append("\n"+String.valueOf(day)+" " +months[month - 1] + " "+String.valueOf(year)+"\n"+newMessage.toString());
try{
if(newMessage!=null)
{
_appPrefs.saveMessageToArchive(_appPrefs.getMessageFromArchive().toString()+"\n _____________________ \n"+String.valueOf(day)+" " +months[month - 1] + " "+String.valueOf(year)+"\n"+newMessage.toString());
lblMessage.setText(_appPrefs.getMessageFromArchive());
}else{}
}
catch(Exception e){}
Toast.makeText(getActivity().getApplicationContext(), "New Message: " + newMessage, Toast.LENGTH_LONG).show();
try{
// Releasing wake lock
WakeLocker.release();}catch(Exception e){}
}
};
}
But I want to automatically start the registration process from the main acitvity without the wating for switching to notification fragment
If you wish to register to GCM from the main activity, even before the fragment is created, you should move the registration code to onCreate method of the activity.

Post to an API every after 15 minutes

I want to know how could I setup my application to update its details via API post every after 15 minutes. Right now, I knos how to use get and use a thread in order to create a loader for it while accessing the API.
Here's how I do it:
private int authenticateLogin()
{
EditText user = ((EditText)findViewById(R.id.username));
EditText pass = ((EditText)findViewById(R.id.password));
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
String username = user.getText().toString(), password = pass.getText().toString();
String URL = "MyUrl";
String authData = "Basic " + Base64.encodeToString((username + ":" + password).getBytes(), Base64.NO_WRAP);
HttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet(URL);
httpget.setHeader("Authorization", authData);
HttpResponse response = null;
try {
response = httpclient.execute(httpget);
StatusLine sl = response.getStatusLine();
int statCode = sl.getStatusCode();
if (statCode == 200) {
String entityStringDrivers = EntityUtils.toString(response.getEntity());
Intent i = new Intent(Login.this,DriverLogin.class);
i.putExtra("stringDrivers", entityStringDrivers);
startActivity(i);
return 100;
}
else
{
user.setText("");
pass.setText("");
Toast.makeText(getBaseContext(), "Unauthorized Login", Toast.LENGTH_SHORT).show();
return 100;
}
} catch (Exception e) {
// Auto-generated catch block
e.printStackTrace();
return 100;
}
finally {
}
}
I want to to know how should I do it when posting and do it in background. I don't know where to start specially with the every 15 minutes POST. Any ideas? Thanks!
You can check this out , and use Intent Services to run in the back ground.
android timer, For intent servicse check it out Intent Services
Use a handler for the timer as follows:
In the snippet call startTimeReqTask() to start your timer.
private Handler m_handler = new Handler();
....
Runnable m_handlerTask = new Runnable() {
#Override
public void run() {
m_handler.postDelayed(m_handlerTask, 900000); // 15 minutes
new authenticateLoginTask().execute(); // POST (your asynctask)
}
};
private void startTimeReqTask() // start timer
{
m_handlerTask.run();
}
private void stopTimeReqTask() // stop time
{
m_handler.removeCallbacks(m_handlerTask);
}
And use AsyncTask authenticateLoginTask for doing it background.
If you want to do this background, create a Service and start it in your main activity's onCreate or some BroadcastReceiver
eg:( You need to add try-catch or other sort of protective code)
public class MyService extends Service {
#Override
public void onStartCommand(Intent intent, int flags, int startId) {
//Use intent to pass your username and password here
//start a PostThread here.
}
private class PostThread extends Thread {
private static final int INTERVAL = 15 * 60 * 1000L;
private boolean canceled = false;
#Override
public void run() {
while (!canceled) {
Post();
Thread.sleep(INTERVAL); // or you can use a Timer to trigger this
}
}
public void interrupt() { canceled = true; super.interrupt();}
}
}
Timer timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
// call your api method here
}
});
}
}, 0, /*here define your internal*/);
// when you no longer required this api call just call "cancel" method of timer

Android Local Service Architecture

I'm trying to implement a service to handle the communication with the server for the following code. I don't know much about the design architecture for these.
Here is my service class
public class BgService extends Service {
private static final String TAG = BgService.class.getSimpleName();
private Timer timer;
SendJsonRequest sjr;
private TimerTask updateTask = new TimerTask(){
#Override
public void run(){
try{
SendJsonRequest sjr = new SendJsonRequest();
sjr.carMake();
Log.i(TAG, "LOOK AT ME");
}
catch(Exception e){
Log.w(TAG,e);
}
}
};
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate(){
super.onCreate();
Log.i(TAG, "Service creating");
timer = new Timer("Server listening timer");
timer.schedule(updateTask, 1000L, 60*1000L);
}
#Override
public void onDestroy(){
super.onDestroy();
Log.i(TAG, "Service Destroying");
timer.cancel();
timer = null;
}
}
Here is my SendJsonRequest class
public class SendJsonRequest{
private static final String TAG = "SendJsonRequest";
private static String URL = "xxxxxxxxx";
private static String infoRec;
public static void createJsonObj(String path, Map x){
infoRec = CreateJsonRequest.jsonRequest(URL+path, x );
System.out.println(infoRec);
}
public static void carMake(){
String path = "/CarMake";
Map<String, Object> z = new HashMap<String,Object>();
z.put("Name", "Ford");
z.put("Model", "Mustang");
createJsonObj(path, z);
}
}
Here is my CreateJsonObject class
public class CreateJsonRequest {
public static String jsonRequest(String URL, Map<String,Object> params){
try{
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(URL);
JSONObject holder = new JSONObject();
for (Map.Entry<String, Object> m : params.entrySet()){
try {
holder.put(m.getKey(), m.getValue());
}
catch (JSONException e) {
Log.e("Hmmmm", "JSONException : "+e);
}
}
StringEntity se;
se = new StringEntity(holder.toString());
httpPost.setEntity(se);
httpPost.setHeader("Accept", "text/json");
httpPost.setHeader("Content-type", "text/json");
HttpResponse response = (HttpResponse) httpClient.execute(httpPost);
HttpEntity entity = response.getEntity();
if(entity != null){
InputStream is = entity.getContent();
Header contentEncoding = response.getFirstHeader("Content-Encoding");
String result= convertToString(is);
is.close();
System.out.println(result);
return result;
}
}
catch(Exception e)
{
e.printStackTrace();
}
return null;
}
Sorry for the massive amount of code. How I implemented my service is obviously not correct, I just have no clue where to start to get a service handling the json requests to the server. Thanks in advance.
To be more clear, this did work on a button click, now I'm trying to get it to all run in the background with the service. So I guess my question is what goes where in the service?
My activity successfully starts the service, the service would work and print "look at me" to the logcat every minute. Then I added the try{ sjr.carMake()} and it catches an exception.
You can use a broadcast receiver. This is a way to have your code start at certain times indicated by Android OS - for example, you can have it start when Android finished booting up (this is where I run my services usually.
The best way is to use the AlarmManager class, and tell your service how often to run.
Tell us more about what you're trying to do, and what the problem is, and we can give you a more concise answer...
UPDATE:
Have you created an entry in the manifest.xml file for the service?
UPDATE
Here is how I'm doing it in my application. This is your "hook" to the OS. It's going to fire when it finishes booting (don't forget to make in entry in the manifest for this!)
public class TmBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(final Context context, final Intent bootintent) {
try{
Log.i("Taskmotion-ROBOT", "Robot Broadcast signal received on Boot. Trying to start Alarm scheduler");
Intent mServiceIntent = new Intent(context, ServiceAlarm.class);
context.startService(mServiceIntent);
}
catch(Exception e)
{
Log.i("Taskmotion", "Failed to start service...");
}
}
}
This Broadcast receiver calls a service that implements the AlarmManager class. The alarm manager sets up a schedule to run my service at a specified interval. Note that the alarms are deleted when the phone is shut down - but then recreated again when process is repeated as the phone boots back up and runs the BroadcastReceiver again.
public class ServiceAlarm extends Service {
private PendingIntent mAlarmSender;
#Override
public void onCreate() {
try{
Log.i("Taskmotion-ROBOT", "Setting Service Alarm Step 1");
mAlarmSender = PendingIntent.getService(this.getApplicationContext(),
0, new Intent(this.getApplicationContext(), BackgroundService.class), 0);
}
catch(Exception e)
{
Log.i("Taskmotion-ROBOT", "Problem at 1 :" + e.toString());
}
long firstTime = SystemClock.elapsedRealtime();
Log.i("Taskmotion-ROBOT", "Setting Service Alarm Step 2");
// Schedule the alarm!
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
am.setRepeating(AlarmManager.ELAPSED_REALTIME,
firstTime, AlarmManager.INTERVAL_HOUR, mAlarmSender);
this.stopSelf();
}
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
}
I haven't refactored this code yet, it was my first go at it. I see now that I'm looking at it again that I could probably do the scheduling inside the BroadcastReceiver, but for the sake of getting you something that works, I'll continue.
As indicated by AlarmManager.INTERVAL_HOUR, my service will run once an hour. The service that I want to run is defined in the pendingIntent (BackgroundService.class). This is where you put your own service class.
I reworked your service class for you, and removed the timer (functionality replaced by the BroadcastReceiver & AlarmManager).
public class BgService extends Service {
private static final String TAG = BgService.class.getSimpleName();
SendJsonRequest sjr;
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate(){
super.onCreate();
Log.i(TAG, "Service creating");
//DO YOUR WORK WITH YOUR JSON CLASS HERE
//**************************************
//Make sure to call stopSelf() or your service will run in the background, chewing up
//battery life like rocky mountain oysters!
this.stopSelf();
}
#Override
public void onDestroy(){
super.onDestroy();
}
}

Categories

Resources