First of all sorry if such sort of question is already asked before.
I want to make a app which make a GET request or Simply Open A URL to tell server that app is closed now, no output is needed just load URL.
What I already tried:
I used Volley but unfortunately its not a solution in this case.
I also tried to make AsyncTask but seriously friend its weird its also not working
Only what's work is a simple line of code:
URL url = new URL("URL HERE");
InputStream stream = url.openStream();
but cause NetworkException. I just want to Execute a URL from Service after app closing.
Sample Codes Will Appreciate
THanks In Advance
Update Section
public class Service extends android.app.Service {
public int isExecuted = 0;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e("rrLOG", "Service Started");
checkClosing();
return Service.START_NOT_STICKY;
}
#Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
Log.e("rrLOG", "Service Stopped");
updateServer(UPDATE_OFFLINE);
stopSelf();
}
#Override
public void onDestroy() {
super.onDestroy();
Log.e("rrLOG", "Service Destroyed");
updateServer(UPDATE_OFFLINE);
stopSelf();
}
public void checkClosing(){
new Timer().scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
if (Helper.isAppRunning(Service.this, getPackageName())) {
Log.i("rrLOG", "App Is Running");
} else {
Log.i("rrLOG", "App Is Not Running");
updateServer(UPDATE_OFFLINE);
stopSelf();
}
}
}, 0, 500);//put here time 1000 milliseconds=1 second
}
static class RequestTask extends AsyncTask<String, String, String> {
#Override
protected String doInBackground(String... uri) {
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response;
String responseString = null;
try {
response = httpclient.execute(new HttpGet(uri[0]));
StatusLine statusLine = response.getStatusLine();
if(statusLine.getStatusCode() == HttpStatus.SC_OK){
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
responseString = out.toString();
out.close();
} else{
//Closes the connection.
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
} catch (ClientProtocolException e) {
//TODO Handle problems..
} catch (IOException e) {
//TODO Handle problems..
}
return responseString;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
//Do anything with response..
}
}
public void updateServer(final String urlJsonArry) {
Log.i("rrLOG", urlJsonArry);
new RequestTask().execute(urlJsonArry);
}
}
UPDATE2 Section
public class Service extends android.app.Service {
public int isExecuted = 0;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e("rrLOG", "Service Started");
checkClosing();
return Service.START_NOT_STICKY;
}
#Override
public void onTaskRemoved(Intent rootIntent) {
//super.onTaskRemoved(rootIntent);
Log.e("rrLOG", "Service Stopped");
updateServer(UPDATE_OFFLINE);
}
#Override
public void onDestroy() {
//super.onDestroy();
Log.e("rrLOG", "Service Destroyed");
updateServer(UPDATE_OFFLINE);
}
public void checkClosing(){
new Timer().scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
if (Helper.isAppRunning(Service.this, getPackageName())) {
Log.i("rrLOG", "App Is Running");
} else {
Log.i("rrLOG", "App Is Not Running");
updateServer(UPDATE_OFFLINE);
}
}
}, 0, 500);//put here time 1000 milliseconds=1 second
}
public class NetworkTask extends AsyncTask<Void,Void,String> {
#Override
protected String doInBackground(Void... voids) {
Log.i("rrLOG", String.valueOf(isExecuted));
URL url = null; //get URL from your uri object
try {
url = new URL(UPDATE_OFFLINE);
} catch (MalformedURLException e) {
e.printStackTrace();
}
try {
InputStream stream = url.openStream();
} catch (IOException e) {
e.printStackTrace();
}
Log.i("rrLOG", String.valueOf(url));
return String.valueOf(url);
}
#Override
protected void onPostExecute(String result) {
Log.i("rrLOG", "onPostExecute");
super.onPostExecute(result);
stopSelf();
}
}
public void updateServer(String urlJsonArry) {
Log.i("rrLOG", urlJsonArry);
if(isExecuted == 0) {
new NetworkTask().execute();
isExecuted = 1;
}
}
}
In Android, every network request is to be made on worker thread. That thread is different to UI thread. You have to make network request in background via AsyncTask. Example below:
public class NetworkTask extends AsyncTask<Void,Void,Void> {
public Void doInBackground() {
// Here you can make network request
}
}
Now you can make this request inside a Service, so even if your activity is killed the network request will go through.
Kindly ensure you have internet permissions in Manifest.
Edit:
I checked the attached code in question, you are trying to stop the service at the same time when you have triggered a network request. If you do so, your network request won't be even completed before it is killed by the system.
You can kill service once your network request is completed, i.e. inside onPostExecute of AsyncTask.
public class NetworkTask extends AsyncTask<Void,Void,String> {
#Override
protected String doInBackground(Void... voids) {
SessionManager manager=new SessionManager ();
Log.i("rrLOG", String.valueOf(isExecuted));
URL url = null; //get URL from your uri object
try {
url = new URL(paste your url);
} catch (MalformedURLException e) {
e.printStackTrace ();
}
try {
InputStream stream = url.openStream();
} catch (IOException e) {
e.printStackTrace();
}
Log.i("rrLOG", String.valueOf(url));
return String.valueOf(url);
}
#Override
protected void onPostExecute(String result) {
Log.i("rrLOG", "onPostExecute");
super.onPostExecute(result);
stopSelf();
}
}
public void updateServer(String url) {
Log.i("rrLOG", urlJsonArry);
if(isExecuted == 0) {
new NetworkTask().execute();
isExecuted = 1;
}
}
Related
I am very beginner in Android, I am creating android application, communication with Siemens PLC its working fine but if i click button only the data shown in android , I want to run this code in service I don't know how to add code(below) in service
protected String doInBackground(String... strings) {
try{
client.SetConnectionType(S7.S7_BASIC);
int res = client.ConnectTo("10.0.2.2",0,1);
if(res == 0)
{
byte[] data = new byte[4];
res = client.ReadArea(S7.S7AreaDB,1,0,2,data);
ret = "Values "+S7.GetWordAt(data,0);
}
else {
ret = "Err:"+S7Client.ErrorText(res);
}
client.Disconnect();
}
catch (Exception e)
{
ret= "Exe"+e.toString();
Thread.interrupted();
}
return "Executed";
}
Above code is working fine but this code added to service I create one service
public class MyService extends Service {
S7Client client = new S7Client();
String ret = "";
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
PlcReader task=new PlcReader();
task.execute("");
return START_NOT_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
public class PlcReader extends android.os.AsyncTask<String,Void,String>{
#Override
protected String doInBackground(String... strings) {
try{
client.SetConnectionType(S7.S7_BASIC);
int res = client.ConnectTo("10.0.2.2",0,1);
if(res == 0)
{
byte[] data = new byte[4];
client.ReadArea(S7.S7AreaDB,1,0,4,data);
ret = "Values "+S7.GetWordAt(data,0);
}
else {
ret = "Err:"+S7Client.ErrorText(res);
}
client.Disconnect();
}
catch (Exception e)
{
ret= "Exe"+e.toString();
Thread.interrupted();
}
return "Executed";
}
#Override
protected void onPostExecute(String s) {
Toast.makeText(getApplicationContext(),ret,Toast.LENGTH_LONG).show();
}
}
I added code with service but shows connection problem
See this example:-
public class ExtractService extends Service {
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
AsyncTask task=new AsyncTask();
task.execute();
return START_NOT_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
public class AsyncTask extends android.os.AsyncTask<Void,Void,Void>{
#Override
protected Void doInBackground(Void... voids) {
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
}
}
}
You can call your AsyncTask from the method onStartCommand in the Service:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Let it continue running until it is stopped.
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
new MyAsyncTask().execute("stringParameter")
return START_STICKY;
}
A couple of tips:
I see that you return a String value from your AsyncTask, just avoid using
String result = new MyAsyncTask().execute("stringParameter").get()
As it will block your main thread (unless you start your async task in a different thread).
A more appropriate solution is to handle the result in the onPostExecute method in your AsyncTask (just override it)
Another thing to think about is that AsyncTask is deprecated in Android R, some good alternatives are the java.util.concurrent package and RxJava library
I'm creating a service for my android application and I want it to run in onPostExecute on another activity.
below is CheckStatus.class (service class)
public class CheckStatus extends Service {
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e("service", "start");
loop();
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
Log.e("service", "stop service");
}
private void loop(){
long endTime = System.currentTimeMillis()+5*1000;
while (System.currentTimeMillis()<endTime) {
synchronized (this) {
try {
wait(endTime - System.currentTimeMillis());
} catch (Exception e) {
}
}
}
Log.e("service", "Check status");
new CheckStatusTask().execute();
}
private class CheckStatusTask extends AsyncTask<String, Void, Void> {
char check_online;
#Override
protected Void doInBackground(String... params) {
//call url json POST method
try {
//Check return data status
} catch (Exception e) {
e.printStackTrace();
check_online = '2';
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
dialog.dismiss();
if (check_online == '1') {
Toast.makeText(getApplicationContext(), "online", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getApplicationContext(), "offline", Toast.LENGTH_LONG).show();
}
}
}
}
So I try to call the service on another activity
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
Intent check_status = new Intent(MainActivity.this,CheckStatus.class);
startService(check_status);
}
But this is not running.
How can I make it run (the service)?
Please add following in your manifest.xml
<service
android:name=".NameOfService">
</service>
I am downloading objects(Videos) from aws s3 bucket. Once i call :
TransferManager transferManager = new TransferManager(s3client);
GetObjectRequest getRequest = new GetObjectRequest(bucket, entity.getName());
String s="";
download = transferManager.download(bucket, entity.getName(), f);
all the objects are downloading at background by default even if i exit my application or put my app on background.
BUT if u force close (means i long press my home button and close my application from running list)my application all the objects stops downloading
What are the ways to make downloading running at back even if application stops...
I tried with service as well:
public class MyDownloadingService extends Service {
public static Download download;
File f;
public static ArrayList<DownloadEntity> downloadList;
public class LocalBinder extends Binder {
public MyDownloadingService getService() {
return MyDownloadingService.this;
}
}
private final LocalBinder mBinder = new LocalBinder();
#Override
public void onCreate() {
super.onCreate();
// downloadList=new ArrayList<DownloadEntity>();
//Toast.makeText(this, "Service Created", 300);
}
#Override
public void onDestroy() {
super.onDestroy();
//Toast.makeText(this,"Service Destroy",300);
}
#Override
public void onLowMemory() {
super.onLowMemory();
//Toast.makeText(this, "Service LowMemory", 300);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Toast.makeText(this,"task perform in service",300);
if (intent!=null) {
String bucket = "", object = "", file = "";
if (intent.getExtras() != null) {
if (intent.getExtras().getString("bucket") != null) {
bucket = intent.getExtras().getString("bucket");
}
if (intent.getExtras().getString("object") != null) {
object = intent.getExtras().getString("object");
}
if (intent.getExtras().getString("file") != null) {
file = intent.getExtras().getString("file");
}
new downloader(bucket, object, file).execute();
}
}
return android.app.Service.START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
public static void getList(){
if (downloadList!=null) {
SoapCostants.downloadList = downloadList;
}
}
public class downloader extends AsyncTask<String, String, String> {
String bucket,object;
String file;
public downloader(String bucket,String object,String file) {
this.object=object;
this.file=file;
this.bucket=bucket;
}
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
}
#Override
protected String doInBackground(String... params) {
File f=new File(file);
// Toast.makeText(this,"Service start",300);
TransferManager transferManager = new TransferManager(S3Getter.s3client);
try {
GetObjectRequest getRequest = new GetObjectRequest(bucket, object);
String s="";
download = transferManager.download(bucket, object, f);
DownloadEntity entity2=new DownloadEntity();
entity2.setKey(object);
entity2.setValue(download);
if (downloadList==null){
downloadList=new ArrayList<DownloadEntity>();
}
SoapCostants.downloadList.add(entity2);
downloadList.add(entity2);
for (int i = 0; i < SoapCostants.downloadedList.size(); i++) {
//SoapCostants.downloadedList
if (object.equalsIgnoreCase(SoapCostants.downloadedList.get(i).getName())) {
SoapCostants.downloadedList.get(i).setIsDownloading("yes");
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
}
}
}
i used start_sticky for services. But if my application was in background for long time it gets closed. or when i force close my application it gets closed.
i checked it by calling getList() of service class above. But it returns null.
The TransferManager is hosted in your application. Once the application is killed, everything it owns will be killed too, TransferManager included. When TransferManager is killed, it invokes shutdown() in finalized() to terminate all transfers running in its thread pool. If you really want it to continue to run, then you'd better try Service which can survive upon application termination. See http://developer.android.com/guide/components/services.html for more details.
I am making AsynkTask within Service like this
public class MyService extends Service {
private final IBinder mBinder = new LocalBinder();
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.v("log_tag", "Service started");
ReceiveAsyncTask receiveATask = new ReceiveAsyncTask();
receiveATask.execute();
return super.onStartCommand(intent, flags, startId);
}
#Override
public IBinder onBind(Intent intent) {
Log.v("log_tag", "onBind");
return mBinder;
}
public class LocalBinder extends Binder {
MyService getService() {
return MyService.this;
}
}
class ReceiveAsyncTask extends AsyncTask<Void, Void, String> {
#Override
protected String doInBackground(Void... params) {
taskDummy();
return null;
}
#Override
protected void onPreExecute() {
Log.v("log_tag", "onPreExecute");
super.onPreExecute();
}
#Override
protected void onPostExecute(String result) {
Log.v("log_tag", "onPostExecute");
super.onPostExecute(result);
}
#Override
protected void onCancelled() {
Log.v("log_tag", "onPostExecute");
super.onCancelled();
}
}
private void taskDummy() {
while (true) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.v("log_tag", "taskDummy");
}
}
/** method for clients */
public int getRandomNumber() {
Log.v("log_tag", "inner Method called");
return 100;
}
}
when I am running the application it starting to print "taskDummy" every two second as expected, when I close application by prssing Back buttin still log printing continue as expected, but when I removed application from recent apps stack it stopped printing this should not happen I want my asynch task continue in this situation. even I can see my service is running from setting. please advise me.
You need to explicitly call of asyncTaskObject.cancel(true); in onDestroy of your Activity(Or your event whenever you want.)
And then rewrite your while loop logic , something like that:
// Create this variable is Your Asyantask class.
private boolean isRunning = true;
#Override
protected void onCancelled() {
isRunning = false;
}
#Override
protected String doInBackground(Void... params) {
while (isRunning ) {
// Your processing
}
return null;
}
It's a known bug: swiping the service out from recent apps destroys it.
Try following solution.
First I will explain the current situation.
I've 2 different threads in 2 services(read from usb port service and make web requests service). I'm starting them in onCreate of my activity like:
serialServiceIntent = new Intent(NDKSerialActivity.this, SerialService.class);
startService(serialServiceIntent);
webServiceIntent = new Intent(NDKSerialActivity.this, RecordWebService.class);
startService(webServiceIntent);
There is nothing wrong with serial service but in RecordWebService when I make a request my gui stops until response comes.
The code is like that:
public class RecordWebService extends Service
{
public static final String SERVER_ADDRESS = "http://192.168.1.100:8080/MobilHM/rest";
private static final String TAG = RecordWebService.class.getSimpleName();
private RecordWebThread recordWebThread;
#Override
public void onStart(Intent intent, int startId)
{
super.onStart(intent, startId);
recordWebThread = new RecordWebThread(true);
recordWebThread.start();
}
#Override
public void onDestroy()
{
super.onDestroy();
Log.i(TAG, "RecordWebService Destroyed");
}
#Override
public IBinder onBind(Intent intent)
{
return null;
}
}
and
public class RecordWebThread extends Thread
{
private static final String TAG = RecordWebThread.class.getSimpleName();
public boolean always;
public RecordWebThread(boolean always)
{
this.always = always;
}
#Override
public void run()
{
PatientRecord patientRecord = new PatientRecord();
while (always)
{
RestClient restClient = new RestClient(RecordWebService.SERVER_ADDRESS + "/hello");
try
{
restClient.execute(RequestMethod.GET);
}
catch (Exception e1)
{
Log.e(TAG, "", e1);
}
Log.i(TAG, "Server Response Code:->" + restClient.getResponseCode());
Log.i(TAG, "Server Response:->" + restClient.getResponse());
try
{
sleep(4 * 1000);
}
catch (InterruptedException e)
{
Log.e(TAG, "Web service interrupted", e);
}
}
}
}
Also I've tried to remove sleep part and make the thread to run with timer and timer task like:
public void sendRecord()
{
scanTask = new TimerTask()
{
public void run()
{
handler.post(new Runnable()
{
public void run()
{
RestClient restClient = new RestClient(RecordWebService.SERVER_ADDRESS + "/hello");
try
{
restClient.execute(RequestMethod.GET);
}
catch (Exception e1)
{
Log.e(TAG, "", e1);
}
Log.i(TAG, "Server Response Code:->" + restClient.getResponseCode());
Log.i(TAG, "Server Response:->" + restClient.getResponse());
}
});
}
};
t.schedule(scanTask, 1000, 4000);
}
but no luck, my gui hangs when it comes to restClient.execute .
You can find RestClient.java # http://www.giantflyingsaucer.com/blog/?p=1462
How can I make my requests not block my gui thread?
Edit:
public void sendRecord()
{
scanTask = new TimerTask()
{
public void run()
{
RestClient restClient = new RestClient(RecordWebService.SERVER_ADDRESS + "/hello");
try
{
restClient.execute(RequestMethod.GET);
}
catch (Exception e1)
{
Log.e(TAG, "", e1);
}
Log.i(TAG, "Server Response Code:->" + restClient.getResponseCode());
Log.i(TAG, "Server Response:->" + restClient.getResponse());
}
};
t.schedule(scanTask, 1000, 4000);
}
Without handler, I call this in onCreate of my activity but still ui hanging.
Or you can use an IntentService which will handle the thread issues for you.
This is an example class:
public class MyService extends IntentService {
public MyService() {
super("MyService");
}
public MyService(String name) {
super(name);
}
#Override
protected void onHandleIntent(Intent arg0) {
//Do what you want
}
}
Then you just call:
Intent intent = new Intent(getApplicationContext(),MyService.class);
startService(intent);
Edit:
To repeat the same thing every 4 seconds you should do something like this:
PendingIntent serviceIntent= PendingIntent.getService(context,
0, new Intent(context, MyService.class), 0);
long firstTime = SystemClock.elapsedRealtime();
AlarmManager am = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
long intervalInSec = 4;
am.setRepeating(AlarmManager.ELAPSED_REALTIME, firstTime, intervalInSec*1000, serviceIntent)
;
In your code (2d version) happens next: You create thread, and it asks UI thread to do some net interaction. Just exclude handler.post(...) while executing request. Later you can use this for simple runnable for updating your UI with results of request.