mirror of
https://github.com/syncthing/syncthing-android.git
synced 2025-01-10 20:15:54 +00:00
Added proper shutdown (using hack).
This commit is contained in:
parent
7a5855fec5
commit
745de67005
4 changed files with 123 additions and 11 deletions
38
src/main/java/com/nutomic/syncthingandroid/RestTask.java
Normal file
38
src/main/java/com/nutomic/syncthingandroid/RestTask.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue