1
0
Fork 0
mirror of https://github.com/syncthing/syncthing-android.git synced 2025-01-10 12:05:53 +00:00

Added proper shutdown (using hack).

This commit is contained in:
Felix Ableitner 2014-05-13 11:09:07 +02:00
parent 7a5855fec5
commit 745de67005
4 changed files with 123 additions and 11 deletions

View file

@ -0,0 +1,38 @@
package com.nutomic.syncthingandroid;
import android.os.AsyncTask;
import android.util.Log;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
/**
* Performs a POST request with no parameters to the URL in uri[0].
*/
class RestTask extends AsyncTask<String, Void, Void> {
private static final String TAG = "RequestTask";
@Override
protected Void doInBackground(String... uri) {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(uri[0]);
String responseString = null;
try {
HttpResponse response = httpclient.execute(httppost);
}
catch (IOException e) {
Log.w(TAG, "Failed to call Rest API", e);
}
return null;
}
}

View file

@ -4,16 +4,33 @@ import android.app.Notification;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.app.Service; import android.app.Service;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle;
import android.os.IBinder; import android.os.IBinder;
import android.support.v4.app.NotificationCompat; import android.support.v4.app.NotificationCompat;
/**
* Holds the native syncthing instance and provides an API to access it.
*/
public class SyncthingService extends Service { public class SyncthingService extends Service {
private static final String TAG = "SyncthingService"; private static final String TAG = "SyncthingService";
private static final int NOTIFICATION_ID = 1; private static final int NOTIFICATION_ID = 1;
/**
* URL of the local syncthing web UI.
*/
public static final String SYNCTHING_URL = "http://127.0.0.1:8080";
/**
* Path to call for shutdown (with POST).
*/
private static final String PATH_SHUTDOWN = "/rest/shutdown";
private final SyncthingServiceBinder mBinder = new SyncthingServiceBinder(this);
/**
* Creates notification, starts native binary.
*/
@Override @Override
public void onCreate() { public void onCreate() {
PendingIntent pi = PendingIntent.getActivity( PendingIntent pi = PendingIntent.getActivity(
@ -36,6 +53,24 @@ public class SyncthingService extends Service {
@Override @Override
public IBinder onBind(Intent intent) { public IBinder onBind(Intent intent) {
return null; return mBinder;
}
/**
* Stops the native binary.
*
* NOTE: This stops all Activities and Services.
*/
@Override
public void onDestroy() {
super.onDestroy();
new RestTask() {
@Override
protected void onPostExecute(Void aVoid) {
// HACK: Android does not release the memory for the native binary, so we explicitly
// stop the VM and thus also all Activities/Services.
System.exit(0);
}
}.execute(SYNCTHING_URL + PATH_SHUTDOWN);
} }
} }

View file

@ -0,0 +1,17 @@
package com.nutomic.syncthingandroid;
import android.os.Binder;
public class SyncthingServiceBinder extends Binder {
SyncthingService mService;
public SyncthingServiceBinder(SyncthingService service) {
mService = service;
}
public SyncthingService getService() {
return mService;
}
}

View file

@ -2,9 +2,13 @@ package com.nutomic.syncthingandroid;
import android.app.Activity; import android.app.Activity;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.IBinder;
import android.util.Log; import android.util.Log;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
@ -23,11 +27,6 @@ public class WebGuiActivity extends Activity {
private static final String TAG = "WebGuiActivity"; private static final String TAG = "WebGuiActivity";
/**
* URL of the local syncthing web UI.
*/
private static final String SYNCTHING_URL = "http://127.0.0.1:8080";
/** /**
* Folder where syncthing config is stored. * Folder where syncthing config is stored.
* *
@ -48,6 +47,20 @@ public class WebGuiActivity extends Activity {
private WebView mWebView; private WebView mWebView;
private View mLoadingView; private View mLoadingView;
private SyncthingService mSyncthingService;
private ServiceConnection mSyncthingServiceConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
SyncthingServiceBinder binder = (SyncthingServiceBinder) service;
mSyncthingService = binder.getService();
}
public void onServiceDisconnected(ComponentName className) {
mSyncthingService = null;
}
};
/** /**
* Retries loading every second until the web UI becomes available. * Retries loading every second until the web UI becomes available.
*/ */
@ -63,7 +76,7 @@ public class WebGuiActivity extends Activity {
@Override @Override
public void run() { public void run() {
mError = 0; mError = 0;
mWebView.loadUrl(SYNCTHING_URL); mWebView.loadUrl(SyncthingService.SYNCTHING_URL);
} }
}, 1000); }, 1000);
@ -81,7 +94,9 @@ public class WebGuiActivity extends Activity {
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
startService(new Intent(this, SyncthingService.class)); getApplicationContext().bindService(
new Intent(this, SyncthingService.class),
mSyncthingServiceConnection, Context.BIND_AUTO_CREATE);
setContentView(R.layout.main); setContentView(R.layout.main);
@ -92,7 +107,7 @@ public class WebGuiActivity extends Activity {
mWebView = (WebView) findViewById(R.id.webview); mWebView = (WebView) findViewById(R.id.webview);
mWebView.getSettings().setJavaScriptEnabled(true); mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.setWebViewClient(mWebViewClient); mWebView.setWebViewClient(mWebViewClient);
mWebView.loadUrl(SYNCTHING_URL); mWebView.loadUrl(SyncthingService.SYNCTHING_URL);
// Handle first start. // Handle first start.
if (!new File(CONFIG_FOLDER, CERT_FILE).exists()) { if (!new File(CONFIG_FOLDER, CERT_FILE).exists()) {
@ -108,6 +123,12 @@ public class WebGuiActivity extends Activity {
} }
} }
@Override
public void onDestroy() {
super.onDestroy();
getApplicationContext().unbindService(mSyncthingServiceConnection);
}
@Override @Override
public boolean onCreateOptionsMenu(Menu menu) { public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu); getMenuInflater().inflate(R.menu.menu, menu);
@ -121,8 +142,9 @@ public class WebGuiActivity extends Activity {
startActivity(new Intent(this, SettingsActivity.class)); startActivity(new Intent(this, SettingsActivity.class));
return true; return true;
case R.id.exit: case R.id.exit:
stopService(new Intent(this, SyncthingService.class)); // Make sure we unbind first.
finish(); finish();
getApplicationContext().stopService(new Intent(this, SyncthingService.class));
return true; return true;
default: default:
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);