package com.greenaddress.greenbits.ui;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.inputmethod.InputMethodManager;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import com.google.common.util.concurrent.Futures;
import com.greenaddress.greenbits.GaService;
import com.greenaddress.greenbits.GreenAddressApplication;
import de.schildbach.wallet.ui.ScanActivity;
/**
* Base class for activities within the application.
*
* Provides access to the main Application and Service objects along with
* support code to handle service initialization, error handling etc.
*/
public abstract class GaActivity extends AppCompatActivity {
private static final String TAG = GaActivity.class.getSimpleName();
// Both of these variables are only assigned in the UI thread.
// mService is available to all derived classes as soon as
// onCreateWithService() is called. Once assigned it does not
// change so may be read from background threads.
private boolean mResumed;
protected GaService mService;
private GreenAddressApplication getGAApp() {
return (GreenAddressApplication) getApplication();
}
@Override
protected final void onCreate(final Bundle savedInstanceState) {
Log.d(TAG, "onCreate -> " + this.getClass().getSimpleName());
super.onCreate(savedInstanceState);
final int viewId = getMainViewId();
if (viewId != UI.INVALID_RESOURCE_ID)
setContentView(viewId);
// Call onCreateWithService() on the GUI thread once our service
// becomes available. In most cases this will execute immediately.
Futures.addCallback(getGAApp().onServiceAttached, new CB.Op<Void>() {
@Override
public void onSuccess(final Void result) {
GaActivity.this.runOnUiThread(new Runnable() {
public void run() {
final GaActivity self = GaActivity.this;
Log.d(TAG, "onCreateWithService -> " + self.getClass().getSimpleName());
self.mService = getGAApp().mService;
self.onCreateWithService(savedInstanceState);
if (self.mResumed) {
// We resumed before the service became available, and so
// did not call onResumeWithService() then - call it now.
Log.d(TAG, "(delayed)onResumeWithService -> " + self.getClass().getSimpleName());
self.mService.incRef();
onResumeWithService();
}
}
});
}
});
}
@Override
final public void onPause() {
Log.d(TAG, "onPause -> " + getClass().getSimpleName() +
(mService == null ? " (no attached service)" : ""));
super.onPause();
mResumed = false;
if (mService != null) {
mService.decRef();
onPauseWithService();
}
}
@Override
final public void onResume() {
Log.d(TAG, "onResume -> " + getClass().getSimpleName() +
(mService == null ? " (no attached service)" : ""));
super.onResume();
mResumed = true;
if (mService != null) {
mService.incRef();
onResumeWithService();
}
}
/** Override to provide the main view id */
protected int getMainViewId() { return UI.INVALID_RESOURCE_ID; }
/** Override to provide onCreate/onResume/onPause processing.
* When called, our service is guaranteed to be available. */
abstract protected void onCreateWithService(final Bundle savedInstanceState);
protected void onPauseWithService() { }
protected void onResumeWithService() { }
// Utility methods
void finishOnUiThread() {
runOnUiThread(new Runnable() {
public void run() {
GaActivity.this.finish();
}
});
}
protected void setMenuItemVisible(final Menu m, final int id, final boolean visible) {
if (m == null)
return;
runOnUiThread(new Runnable() {
public void run() {
final MenuItem item = m.findItem(id);
if (item != null)
item.setVisible(visible);
}
});
}
protected void hideKeyboardFrom(final View v) {
final View toHideFrom = v == null ? getCurrentFocus() : v;
if (toHideFrom != null) {
final InputMethodManager imm;
imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(toHideFrom.getWindowToken(), 0);
}
}
public void toast(final Throwable t) { UI.toast(this, t, null); }
public void toast(final int id) { UI.toast(this, id, Toast.LENGTH_LONG); }
public void toast(final int id, final Button reenable) { UI.toast(this, getString(id), reenable); }
public void toast(final String s) { UI.toast(this, s, Toast.LENGTH_LONG); }
public void shortToast(final int id) { UI.toast(this, id, Toast.LENGTH_SHORT); }
@Override
protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case TabbedMainActivity.REQUEST_SEND_QR_SCAN:
case TabbedMainActivity.REQUEST_SEND_QR_SCAN_EXCHANGER:
if (data != null && data.getStringExtra(ScanActivity.INTENT_EXTRA_RESULT) != null) {
String scanned = data.getStringExtra(ScanActivity.INTENT_EXTRA_RESULT);
if (!(scanned.length() >= 8 && scanned.substring(0, 8).equalsIgnoreCase("bitcoin:")))
scanned = String.format("bitcoin:%s", scanned);
final Intent browsable;
if (requestCode == TabbedMainActivity.REQUEST_SEND_QR_SCAN)
browsable = new Intent(this, TabbedMainActivity.class);
else
browsable = new Intent(this, SellActivity.class);
browsable.setData(Uri.parse(scanned));
browsable.addCategory(Intent.CATEGORY_BROWSABLE);
browsable.putExtra("internal_qr", true);
if (data.getStringExtra("sendAmount") != null)
browsable.putExtra("sendAmount", data.getStringExtra("sendAmount"));
// start new activity and finish old one
startActivity(browsable);
this.finish();
}
break;
}
}
}